1 /* $NetBSD: lmem.c,v 1.4 2015/10/08 13:21:00 mbalmer Exp $ */
4 ** Id: lmem.c,v 1.91 2015/03/06 19:45:54 roberto Exp
5 ** Interface to Memory Manager
6 ** See Copyright Notice in lua.h
31 ** About the realloc function:
32 ** void * frealloc (void *ud, void *ptr, size_t osize, size_t nsize);
33 ** ('osize' is the old size, 'nsize' is the new size)
35 ** * frealloc(ud, NULL, x, s) creates a new block of size 's' (no
38 ** * frealloc(ud, p, x, 0) frees the block 'p'
39 ** (in this specific case, frealloc must return NULL);
40 ** particularly, frealloc(ud, NULL, 0, 0) does nothing
41 ** (which is equivalent to free(NULL) in ISO C)
43 ** frealloc returns NULL if it cannot create or reallocate the area
44 ** (any reallocation to an equal or smaller size cannot fail!)
49 #define MINSIZEARRAY 4
52 void *luaM_growaux_ (lua_State
*L
, void *block
, int *size
, size_t size_elems
,
53 int limit
, const char *what
) {
56 if (*size
>= limit
/2) { /* cannot double it? */
57 if (*size
>= limit
) /* cannot grow even a little? */
58 luaG_runerror(L
, "too many %s (limit is %d)", what
, limit
);
59 newsize
= limit
; /* still have at least one free place */
63 if (newsize
< MINSIZEARRAY
)
64 newsize
= MINSIZEARRAY
; /* minimum size */
66 newblock
= luaM_reallocv(L
, block
, *size
, newsize
, size_elems
);
67 *size
= newsize
; /* update only when everything else is OK */
72 l_noret
luaM_toobig (lua_State
*L
) {
73 luaG_runerror(L
, "memory allocation error: block too big");
79 ** generic allocation routine.
81 void *luaM_realloc_ (lua_State
*L
, void *block
, size_t osize
, size_t nsize
) {
83 global_State
*g
= G(L
);
84 size_t realosize
= (block
) ? osize
: 0;
85 lua_assert((realosize
== 0) == (block
== NULL
));
86 #if defined(HARDMEMTESTS)
87 if (nsize
> realosize
&& g
->gcrunning
)
88 luaC_fullgc(L
, 1); /* force a GC whenever possible */
90 newblock
= (*g
->frealloc
)(g
->ud
, block
, osize
, nsize
);
91 if (newblock
== NULL
&& nsize
> 0) {
92 lua_assert(nsize
> realosize
); /* cannot fail when shrinking a block */
93 if (g
->version
) { /* is state fully built? */
94 luaC_fullgc(L
, 1); /* try to free some memory... */
95 newblock
= (*g
->frealloc
)(g
->ud
, block
, osize
, nsize
); /* try again */
98 luaD_throw(L
, LUA_ERRMEM
);
100 lua_assert((nsize
== 0) == (newblock
== NULL
));
101 g
->GCdebt
= (g
->GCdebt
+ nsize
) - realosize
;