mirror of https://github.com/rusefi/lua.git
avoid using one function for different tasks (malloc, free, etc.)
This commit is contained in:
parent
348fa1ca56
commit
49dfaf7447
77
lmem.c
77
lmem.c
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: lmem.c,v 1.90 2015/03/03 18:18:29 roberto Exp roberto $
|
||||
** $Id: lmem.c,v 1.91 2015/03/06 19:45:54 roberto Exp roberto $
|
||||
** Interface to Memory Manager
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -22,6 +22,14 @@
|
|||
#include "lstate.h"
|
||||
|
||||
|
||||
#if defined(HARDMEMTESTS)
|
||||
#define hardtest(L,os,s) /* force a GC whenever possible */ \
|
||||
if ((s) > (os) && (G(L))->gcrunning) luaC_fullgc(L, 1);
|
||||
#else
|
||||
#define hardtest(L,os,s) ((void)0)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** About the realloc function:
|
||||
|
@ -45,10 +53,12 @@
|
|||
#define MINSIZEARRAY 4
|
||||
|
||||
|
||||
void *luaM_growaux_ (lua_State *L, void *block, int *size, size_t size_elems,
|
||||
int limit, const char *what) {
|
||||
void *luaM_growaux_ (lua_State *L, void *block, int nelems, int *size,
|
||||
int size_elems, int limit, const char *what) {
|
||||
void *newblock;
|
||||
int newsize;
|
||||
if (nelems + 1 <= *size) /* does one extra element still fit? */
|
||||
return block; /* nothing to be done */
|
||||
if (*size >= limit/2) { /* cannot double it? */
|
||||
if (*size >= limit) /* cannot grow even a little? */
|
||||
luaG_runerror(L, "too many %s (limit is %d)", what, limit);
|
||||
|
@ -65,11 +75,40 @@ void *luaM_growaux_ (lua_State *L, void *block, int *size, size_t size_elems,
|
|||
}
|
||||
|
||||
|
||||
void *luaM_shrinkvector_ (lua_State *L, void *block, int *size,
|
||||
int final_n, int size_elem) {
|
||||
global_State *g = G(L);
|
||||
void *newblock;
|
||||
size_t oldsize = cast(size_t, (*size) * size_elem);
|
||||
size_t newsize = cast(size_t, final_n * size_elem);
|
||||
lua_assert(newsize <= oldsize);
|
||||
newblock = (*g->frealloc)(g->ud, block, oldsize, newsize);
|
||||
if (newblock == NULL && final_n > 0) /* allocation failed? */
|
||||
return block; /* keep old block */
|
||||
else {
|
||||
g->GCdebt += newsize - oldsize;
|
||||
*size = final_n;
|
||||
return newblock;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
l_noret luaM_toobig (lua_State *L) {
|
||||
luaG_runerror(L, "memory allocation error: block too big");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Free memory
|
||||
*/
|
||||
void luaM_free_ (lua_State *L, void *block, size_t osize) {
|
||||
global_State *g = G(L);
|
||||
lua_assert((block == 0) == (block == NULL));
|
||||
(*g->frealloc)(g->ud, block, osize, 0);
|
||||
g->GCdebt -= osize;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** generic allocation routine.
|
||||
|
@ -77,15 +116,11 @@ l_noret luaM_toobig (lua_State *L) {
|
|||
void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) {
|
||||
void *newblock;
|
||||
global_State *g = G(L);
|
||||
size_t realosize = (block) ? osize : 0;
|
||||
lua_assert((realosize == 0) == (block == NULL));
|
||||
#if defined(HARDMEMTESTS)
|
||||
if (nsize > realosize && g->gcrunning)
|
||||
luaC_fullgc(L, 1); /* force a GC whenever possible */
|
||||
#endif
|
||||
lua_assert((osize == 0) == (block == NULL));
|
||||
hardtest(L, osize, nsize);
|
||||
newblock = (*g->frealloc)(g->ud, block, osize, nsize);
|
||||
if (newblock == NULL && nsize > 0) {
|
||||
lua_assert(nsize > realosize); /* cannot fail when shrinking a block */
|
||||
lua_assert(nsize > osize); /* cannot fail when shrinking a block */
|
||||
if (g->version) { /* is state fully built? */
|
||||
luaC_fullgc(L, 1); /* try to free some memory... */
|
||||
newblock = (*g->frealloc)(g->ud, block, osize, nsize); /* try again */
|
||||
|
@ -94,7 +129,27 @@ void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) {
|
|||
luaD_throw(L, LUA_ERRMEM);
|
||||
}
|
||||
lua_assert((nsize == 0) == (newblock == NULL));
|
||||
g->GCdebt = (g->GCdebt + nsize) - realosize;
|
||||
g->GCdebt = (g->GCdebt + nsize) - osize;
|
||||
return newblock;
|
||||
}
|
||||
|
||||
|
||||
void *luaM_malloc (lua_State *L, size_t size, int tag) {
|
||||
hardtest(L, 0, size);
|
||||
if (size == 0)
|
||||
return NULL; /* that's all */
|
||||
else {
|
||||
global_State *g = G(L);
|
||||
void *newblock = (*g->frealloc)(g->ud, NULL, tag, size);
|
||||
if (newblock == NULL) {
|
||||
if (g->version) { /* is state fully built? */
|
||||
luaC_fullgc(L, 1); /* try to free some memory... */
|
||||
newblock = (*g->frealloc)(g->ud, NULL, tag, size); /* try again */
|
||||
}
|
||||
if (newblock == NULL)
|
||||
luaD_throw(L, LUA_ERRMEM);
|
||||
}
|
||||
g->GCdebt += size;
|
||||
return newblock;
|
||||
}
|
||||
}
|
||||
|
|
53
lmem.h
53
lmem.h
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: lmem.h,v 1.42 2014/12/19 13:45:40 roberto Exp roberto $
|
||||
** $Id: lmem.h,v 1.43 2014/12/19 17:26:14 roberto Exp roberto $
|
||||
** Interface to Memory Manager
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -15,11 +15,9 @@
|
|||
|
||||
|
||||
/*
|
||||
** This macro reallocs a vector 'b' from 'on' to 'n' elements, where
|
||||
** each element has size 'e'. In case of arithmetic overflow of the
|
||||
** product 'n'*'e', it raises an error (calling 'luaM_toobig'). Because
|
||||
** 'e' is always constant, it avoids the runtime division MAX_SIZET/(e).
|
||||
**
|
||||
** This macro tests whether it is safe to multiply 'n' by the size of
|
||||
** type 't' without overflows. Because 'e' is always constant, it avoids
|
||||
** the runtime division MAX_SIZET/(e).
|
||||
** (The macro is somewhat complex to avoid warnings: The 'sizeof'
|
||||
** comparison avoids a runtime comparison when overflow cannot occur.
|
||||
** The compiler should be able to optimize the real test by itself, but
|
||||
|
@ -27,10 +25,20 @@
|
|||
** false due to limited range of data type"; the +1 tricks the compiler,
|
||||
** avoiding this warning but also this optimization.)
|
||||
*/
|
||||
#define luaM_testsize(n,e) \
|
||||
(sizeof(n) >= sizeof(size_t) && cast(size_t, (n)) + 1 > MAX_SIZET/(e))
|
||||
|
||||
#define luaM_checksize(L,n,e) \
|
||||
(luaM_testsize(n,e) ? luaM_toobig(L) : cast_void(0))
|
||||
|
||||
/*
|
||||
** This macro reallocs a vector 'b' from 'on' to 'n' elements, where
|
||||
** each element has size 'e'. In case of arithmetic overflow of the
|
||||
** product 'n'*'e', it raises an error (calling 'luaM_toobig').
|
||||
*/
|
||||
#define luaM_reallocv(L,b,on,n,e) \
|
||||
(((sizeof(n) >= sizeof(size_t) && cast(size_t, (n)) + 1 > MAX_SIZET/(e)) \
|
||||
? luaM_toobig(L) : cast_void(0)) , \
|
||||
luaM_realloc_(L, (b), (on)*(e), (n)*(e)))
|
||||
(luaM_checksize(L,n,e), \
|
||||
luaM_realloc_(L, (b), cast(size_t, on)*(e), cast(size_t, n)*(e)))
|
||||
|
||||
/*
|
||||
** Arrays of chars do not need any test
|
||||
|
@ -38,32 +46,37 @@
|
|||
#define luaM_reallocvchar(L,b,on,n) \
|
||||
cast(char *, luaM_realloc_(L, (b), (on)*sizeof(char), (n)*sizeof(char)))
|
||||
|
||||
#define luaM_freemem(L, b, s) luaM_realloc_(L, (b), (s), 0)
|
||||
#define luaM_free(L, b) luaM_realloc_(L, (b), sizeof(*(b)), 0)
|
||||
#define luaM_freearray(L, b, n) luaM_realloc_(L, (b), (n)*sizeof(*(b)), 0)
|
||||
#define luaM_freemem(L, b, s) luaM_free_(L, (b), (s))
|
||||
#define luaM_free(L, b) luaM_free_(L, (b), sizeof(*(b)))
|
||||
#define luaM_freearray(L, b, n) luaM_free_(L, (b), (n)*sizeof(*(b)))
|
||||
|
||||
#define luaM_malloc(L,s) luaM_realloc_(L, NULL, 0, (s))
|
||||
#define luaM_new(L,t) cast(t *, luaM_malloc(L, sizeof(t)))
|
||||
#define luaM_new(L,t) cast(t *, luaM_malloc(L, sizeof(t), 0))
|
||||
#define luaM_newvector(L,n,t) \
|
||||
cast(t *, luaM_reallocv(L, NULL, 0, n, sizeof(t)))
|
||||
(luaM_checksize(L,n,sizeof(t)), cast(t *, luaM_malloc(L, (n)*sizeof(t), 0)))
|
||||
|
||||
#define luaM_newobject(L,tag,s) luaM_realloc_(L, NULL, tag, (s))
|
||||
#define luaM_newobject(L,tag,s) luaM_malloc(L, (s), tag)
|
||||
|
||||
#define luaM_growvector(L,v,nelems,size,t,limit,e) \
|
||||
if ((nelems)+1 > (size)) \
|
||||
((v)=cast(t *, luaM_growaux_(L,v,&(size),sizeof(t),limit,e)))
|
||||
((v)=cast(t *, luaM_growaux_(L,v,nelems,&(size),sizeof(t),limit,e)))
|
||||
|
||||
#define luaM_reallocvector(L, v,oldn,n,t) \
|
||||
((v)=cast(t *, luaM_reallocv(L, v, oldn, n, sizeof(t))))
|
||||
|
||||
#define luaM_shrinkvector(L,v,size,fs,t) \
|
||||
((v)=cast(t *, luaM_shrinkvector_(L, v, &(size), fs, sizeof(t))))
|
||||
|
||||
LUAI_FUNC l_noret luaM_toobig (lua_State *L);
|
||||
|
||||
/* not to be called directly */
|
||||
LUAI_FUNC void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize,
|
||||
size_t size);
|
||||
LUAI_FUNC void *luaM_growaux_ (lua_State *L, void *block, int *size,
|
||||
size_t size_elem, int limit,
|
||||
LUAI_FUNC void luaM_free_ (lua_State *L, void *block, size_t osize);
|
||||
LUAI_FUNC void *luaM_growaux_ (lua_State *L, void *block, int nelems,
|
||||
int *size, int size_elem, int limit,
|
||||
const char *what);
|
||||
LUAI_FUNC void *luaM_shrinkvector_ (lua_State *L, void *block, int *nelem,
|
||||
int final_n, int size_elem);
|
||||
LUAI_FUNC void *luaM_malloc (lua_State *L, size_t size, int tag);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
25
lparser.c
25
lparser.c
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: lparser.c,v 2.168 2017/11/23 16:35:54 roberto Exp roberto $
|
||||
** $Id: lparser.c,v 2.169 2017/11/30 13:29:18 roberto Exp roberto $
|
||||
** Lua Parser
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -569,21 +569,14 @@ static void close_func (LexState *ls) {
|
|||
luaK_ret(fs, 0, 0); /* final return */
|
||||
leaveblock(fs);
|
||||
luaK_finish(fs);
|
||||
luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction);
|
||||
f->sizecode = fs->pc;
|
||||
luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, ls_byte);
|
||||
f->sizelineinfo = fs->pc;
|
||||
luaM_reallocvector(L, f->abslineinfo, f->sizeabslineinfo,
|
||||
fs->nabslineinfo, AbsLineInfo);
|
||||
f->sizeabslineinfo = fs->nabslineinfo;
|
||||
luaM_reallocvector(L, f->k, f->sizek, fs->nk, TValue);
|
||||
f->sizek = fs->nk;
|
||||
luaM_reallocvector(L, f->p, f->sizep, fs->np, Proto *);
|
||||
f->sizep = fs->np;
|
||||
luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar);
|
||||
f->sizelocvars = fs->nlocvars;
|
||||
luaM_reallocvector(L, f->upvalues, f->sizeupvalues, fs->nups, Upvaldesc);
|
||||
f->sizeupvalues = fs->nups;
|
||||
luaM_shrinkvector(L, f->code, f->sizecode, fs->pc, Instruction);
|
||||
luaM_shrinkvector(L, f->lineinfo, f->sizelineinfo, fs->pc, ls_byte);
|
||||
luaM_shrinkvector(L, f->abslineinfo, f->sizeabslineinfo,
|
||||
fs->nabslineinfo, AbsLineInfo);
|
||||
luaM_shrinkvector(L, f->k, f->sizek, fs->nk, TValue);
|
||||
luaM_shrinkvector(L, f->p, f->sizep, fs->np, Proto *);
|
||||
luaM_shrinkvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar);
|
||||
luaM_shrinkvector(L, f->upvalues, f->sizeupvalues, fs->nups, Upvaldesc);
|
||||
lua_assert(fs->bl == NULL);
|
||||
ls->fs = fs->prev;
|
||||
luaC_checkGC(L);
|
||||
|
|
Loading…
Reference in New Issue