3 ** $Id: lmem.c,v 1.84.1.1 2013/04/12 18:48:47 roberto Exp $
4 ** Interface to Memory Manager
5 ** See Copyright Notice in lua.h
12 #include <sys/lua/lua.h>
24 ** About the realloc function:
25 ** void * frealloc (void *ud, void *ptr, size_t osize, size_t nsize);
26 ** (`osize' is the old size, `nsize' is the new size)
28 ** * frealloc(ud, NULL, x, s) creates a new block of size `s' (no
31 ** * frealloc(ud, p, x, 0) frees the block `p'
32 ** (in this specific case, frealloc must return NULL);
33 ** particularly, frealloc(ud, NULL, 0, 0) does nothing
34 ** (which is equivalent to free(NULL) in ANSI C)
36 ** frealloc returns NULL if it cannot create or reallocate the area
37 ** (any reallocation to an equal or smaller size cannot fail!)
42 #define MINSIZEARRAY 4
45 void *luaM_growaux_ (lua_State
*L
, void *block
, int *size
, size_t size_elems
,
46 int limit
, const char *what
) {
49 if (*size
>= limit
/2) { /* cannot double it? */
50 if (*size
>= limit
) /* cannot grow even a little? */
51 luaG_runerror(L
, "too many %s (limit is %d)", what
, limit
);
52 newsize
= limit
; /* still have at least one free place */
56 if (newsize
< MINSIZEARRAY
)
57 newsize
= MINSIZEARRAY
; /* minimum size */
59 newblock
= luaM_reallocv(L
, block
, *size
, newsize
, size_elems
);
60 *size
= newsize
; /* update only when everything else is OK */
65 l_noret
luaM_toobig (lua_State
*L
) {
66 luaG_runerror(L
, "memory allocation error: block too big");
72 ** generic allocation routine.
74 void *luaM_realloc_ (lua_State
*L
, void *block
, size_t osize
, size_t nsize
) {
76 global_State
*g
= G(L
);
77 size_t realosize
= (block
) ? osize
: 0;
78 lua_assert((realosize
== 0) == (block
== NULL
));
79 #if defined(HARDMEMTESTS)
80 if (nsize
> realosize
&& g
->gcrunning
)
81 luaC_fullgc(L
, 1); /* force a GC whenever possible */
83 newblock
= (*g
->frealloc
)(g
->ud
, block
, osize
, nsize
);
84 if (newblock
== NULL
&& nsize
> 0) {
85 api_check(L
, nsize
> realosize
,
86 "realloc cannot fail when shrinking a block");
88 luaC_fullgc(L
, 1); /* try to free some memory... */
89 newblock
= (*g
->frealloc
)(g
->ud
, block
, osize
, nsize
); /* try again */
92 luaD_throw(L
, LUA_ERRMEM
);
94 lua_assert((nsize
== 0) == (newblock
== NULL
));
95 g
->GCdebt
= (g
->GCdebt
+ nsize
) - realosize
;