116a5fed65808adf648004b34f98718301d718fa2darylm/* 216a5fed65808adf648004b34f98718301d718fa2darylm** $Id: lmem.c,v 1.84.1.1 2013/04/12 18:48:47 roberto Exp $ 316a5fed65808adf648004b34f98718301d718fa2darylm** Interface to Memory Manager 416a5fed65808adf648004b34f98718301d718fa2darylm** See Copyright Notice in lua.h 516a5fed65808adf648004b34f98718301d718fa2darylm*/ 616a5fed65808adf648004b34f98718301d718fa2darylm 716a5fed65808adf648004b34f98718301d718fa2darylm 816a5fed65808adf648004b34f98718301d718fa2darylm#include <stddef.h> 916a5fed65808adf648004b34f98718301d718fa2darylm 1016a5fed65808adf648004b34f98718301d718fa2darylm#define lmem_c 1116a5fed65808adf648004b34f98718301d718fa2darylm#define LUA_CORE 1216a5fed65808adf648004b34f98718301d718fa2darylm 1316a5fed65808adf648004b34f98718301d718fa2darylm#include "lua.h" 1416a5fed65808adf648004b34f98718301d718fa2darylm 1516a5fed65808adf648004b34f98718301d718fa2darylm#include "ldebug.h" 1616a5fed65808adf648004b34f98718301d718fa2darylm#include "ldo.h" 1716a5fed65808adf648004b34f98718301d718fa2darylm#include "lgc.h" 1816a5fed65808adf648004b34f98718301d718fa2darylm#include "lmem.h" 1916a5fed65808adf648004b34f98718301d718fa2darylm#include "lobject.h" 2016a5fed65808adf648004b34f98718301d718fa2darylm#include "lstate.h" 2116a5fed65808adf648004b34f98718301d718fa2darylm 2216a5fed65808adf648004b34f98718301d718fa2darylm 2316a5fed65808adf648004b34f98718301d718fa2darylm 2416a5fed65808adf648004b34f98718301d718fa2darylm/* 2516a5fed65808adf648004b34f98718301d718fa2darylm** About the realloc function: 2616a5fed65808adf648004b34f98718301d718fa2darylm** void * frealloc (void *ud, void *ptr, size_t osize, size_t nsize); 2716a5fed65808adf648004b34f98718301d718fa2darylm** (`osize' is the old size, `nsize' is the new size) 2816a5fed65808adf648004b34f98718301d718fa2darylm** 2916a5fed65808adf648004b34f98718301d718fa2darylm** * frealloc(ud, NULL, x, s) creates a new block of size `s' (no 3016a5fed65808adf648004b34f98718301d718fa2darylm** matter 'x'). 3116a5fed65808adf648004b34f98718301d718fa2darylm** 3216a5fed65808adf648004b34f98718301d718fa2darylm** * frealloc(ud, p, x, 0) frees the block `p' 3316a5fed65808adf648004b34f98718301d718fa2darylm** (in this specific case, frealloc must return NULL); 3416a5fed65808adf648004b34f98718301d718fa2darylm** particularly, frealloc(ud, NULL, 0, 0) does nothing 3516a5fed65808adf648004b34f98718301d718fa2darylm** (which is equivalent to free(NULL) in ANSI C) 3616a5fed65808adf648004b34f98718301d718fa2darylm** 3716a5fed65808adf648004b34f98718301d718fa2darylm** frealloc returns NULL if it cannot create or reallocate the area 3816a5fed65808adf648004b34f98718301d718fa2darylm** (any reallocation to an equal or smaller size cannot fail!) 3916a5fed65808adf648004b34f98718301d718fa2darylm*/ 4016a5fed65808adf648004b34f98718301d718fa2darylm 4116a5fed65808adf648004b34f98718301d718fa2darylm 4216a5fed65808adf648004b34f98718301d718fa2darylm 4316a5fed65808adf648004b34f98718301d718fa2darylm#define MINSIZEARRAY 4 4416a5fed65808adf648004b34f98718301d718fa2darylm 4516a5fed65808adf648004b34f98718301d718fa2darylm 4616a5fed65808adf648004b34f98718301d718fa2darylmvoid *luaM_growaux_ (lua_State *L, void *block, int *size, size_t size_elems, 4716a5fed65808adf648004b34f98718301d718fa2darylm int limit, const char *what) { 4816a5fed65808adf648004b34f98718301d718fa2darylm void *newblock; 4916a5fed65808adf648004b34f98718301d718fa2darylm int newsize; 5016a5fed65808adf648004b34f98718301d718fa2darylm if (*size >= limit/2) { /* cannot double it? */ 5116a5fed65808adf648004b34f98718301d718fa2darylm if (*size >= limit) /* cannot grow even a little? */ 5216a5fed65808adf648004b34f98718301d718fa2darylm luaG_runerror(L, "too many %s (limit is %d)", what, limit); 5316a5fed65808adf648004b34f98718301d718fa2darylm newsize = limit; /* still have at least one free place */ 5416a5fed65808adf648004b34f98718301d718fa2darylm } 5516a5fed65808adf648004b34f98718301d718fa2darylm else { 5616a5fed65808adf648004b34f98718301d718fa2darylm newsize = (*size)*2; 5716a5fed65808adf648004b34f98718301d718fa2darylm if (newsize < MINSIZEARRAY) 5816a5fed65808adf648004b34f98718301d718fa2darylm newsize = MINSIZEARRAY; /* minimum size */ 5916a5fed65808adf648004b34f98718301d718fa2darylm } 6016a5fed65808adf648004b34f98718301d718fa2darylm newblock = luaM_reallocv(L, block, *size, newsize, size_elems); 6116a5fed65808adf648004b34f98718301d718fa2darylm *size = newsize; /* update only when everything else is OK */ 6216a5fed65808adf648004b34f98718301d718fa2darylm return newblock; 6316a5fed65808adf648004b34f98718301d718fa2darylm} 6416a5fed65808adf648004b34f98718301d718fa2darylm 6516a5fed65808adf648004b34f98718301d718fa2darylm 6616a5fed65808adf648004b34f98718301d718fa2darylml_noret luaM_toobig (lua_State *L) { 6716a5fed65808adf648004b34f98718301d718fa2darylm luaG_runerror(L, "memory allocation error: block too big"); 6816a5fed65808adf648004b34f98718301d718fa2darylm} 6916a5fed65808adf648004b34f98718301d718fa2darylm 7016a5fed65808adf648004b34f98718301d718fa2darylm 7116a5fed65808adf648004b34f98718301d718fa2darylm 7216a5fed65808adf648004b34f98718301d718fa2darylm/* 7316a5fed65808adf648004b34f98718301d718fa2darylm** generic allocation routine. 7416a5fed65808adf648004b34f98718301d718fa2darylm*/ 7516a5fed65808adf648004b34f98718301d718fa2darylmvoid *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) { 7616a5fed65808adf648004b34f98718301d718fa2darylm void *newblock; 7716a5fed65808adf648004b34f98718301d718fa2darylm global_State *g = G(L); 7816a5fed65808adf648004b34f98718301d718fa2darylm size_t realosize = (block) ? osize : 0; 7916a5fed65808adf648004b34f98718301d718fa2darylm lua_assert((realosize == 0) == (block == NULL)); 8016a5fed65808adf648004b34f98718301d718fa2darylm#if defined(HARDMEMTESTS) 8116a5fed65808adf648004b34f98718301d718fa2darylm if (nsize > realosize && g->gcrunning) 8216a5fed65808adf648004b34f98718301d718fa2darylm luaC_fullgc(L, 1); /* force a GC whenever possible */ 8316a5fed65808adf648004b34f98718301d718fa2darylm#endif 8416a5fed65808adf648004b34f98718301d718fa2darylm newblock = (*g->frealloc)(g->ud, block, osize, nsize); 8516a5fed65808adf648004b34f98718301d718fa2darylm if (newblock == NULL && nsize > 0) { 8616a5fed65808adf648004b34f98718301d718fa2darylm api_check(L, nsize > realosize, 8716a5fed65808adf648004b34f98718301d718fa2darylm "realloc cannot fail when shrinking a block"); 8816a5fed65808adf648004b34f98718301d718fa2darylm if (g->gcrunning) { 8916a5fed65808adf648004b34f98718301d718fa2darylm luaC_fullgc(L, 1); /* try to free some memory... */ 9016a5fed65808adf648004b34f98718301d718fa2darylm newblock = (*g->frealloc)(g->ud, block, osize, nsize); /* try again */ 9116a5fed65808adf648004b34f98718301d718fa2darylm } 9216a5fed65808adf648004b34f98718301d718fa2darylm if (newblock == NULL) 9316a5fed65808adf648004b34f98718301d718fa2darylm luaD_throw(L, LUA_ERRMEM); 9416a5fed65808adf648004b34f98718301d718fa2darylm } 9516a5fed65808adf648004b34f98718301d718fa2darylm lua_assert((nsize == 0) == (newblock == NULL)); 9616a5fed65808adf648004b34f98718301d718fa2darylm g->GCdebt = (g->GCdebt + nsize) - realosize; 9716a5fed65808adf648004b34f98718301d718fa2darylm return newblock; 9816a5fed65808adf648004b34f98718301d718fa2darylm} 9916a5fed65808adf648004b34f98718301d718fa2darylm 100