xref: /freebsd-src/sys/contrib/openzfs/module/lua/lmem.c (revision c03c5b1c80914ec656fbee84539355d1fad68bf9)
1*eda14cbcSMatt Macy /*
2*eda14cbcSMatt Macy ** $Id: lmem.c,v 1.84.1.1 2013/04/12 18:48:47 roberto Exp $
3*eda14cbcSMatt Macy ** Interface to Memory Manager
4*eda14cbcSMatt Macy ** See Copyright Notice in lua.h
5*eda14cbcSMatt Macy */
6*eda14cbcSMatt Macy 
7*eda14cbcSMatt Macy 
8*eda14cbcSMatt Macy #define lmem_c
9*eda14cbcSMatt Macy #define LUA_CORE
10*eda14cbcSMatt Macy 
11*eda14cbcSMatt Macy #include <sys/lua/lua.h>
12*eda14cbcSMatt Macy 
13*eda14cbcSMatt Macy #include "ldebug.h"
14*eda14cbcSMatt Macy #include "ldo.h"
15*eda14cbcSMatt Macy #include "lgc.h"
16*eda14cbcSMatt Macy #include "lmem.h"
17*eda14cbcSMatt Macy #include "lobject.h"
18*eda14cbcSMatt Macy #include "lstate.h"
19*eda14cbcSMatt Macy 
20*eda14cbcSMatt Macy 
21*eda14cbcSMatt Macy 
22*eda14cbcSMatt Macy /*
23*eda14cbcSMatt Macy ** About the realloc function:
24*eda14cbcSMatt Macy ** void * frealloc (void *ud, void *ptr, size_t osize, size_t nsize);
25*eda14cbcSMatt Macy ** (`osize' is the old size, `nsize' is the new size)
26*eda14cbcSMatt Macy **
27*eda14cbcSMatt Macy ** * frealloc(ud, NULL, x, s) creates a new block of size `s' (no
28*eda14cbcSMatt Macy ** matter 'x').
29*eda14cbcSMatt Macy **
30*eda14cbcSMatt Macy ** * frealloc(ud, p, x, 0) frees the block `p'
31*eda14cbcSMatt Macy ** (in this specific case, frealloc must return NULL);
32*eda14cbcSMatt Macy ** particularly, frealloc(ud, NULL, 0, 0) does nothing
33*eda14cbcSMatt Macy ** (which is equivalent to free(NULL) in ANSI C)
34*eda14cbcSMatt Macy **
35*eda14cbcSMatt Macy ** frealloc returns NULL if it cannot create or reallocate the area
36*eda14cbcSMatt Macy ** (any reallocation to an equal or smaller size cannot fail!)
37*eda14cbcSMatt Macy */
38*eda14cbcSMatt Macy 
39*eda14cbcSMatt Macy 
40*eda14cbcSMatt Macy 
41*eda14cbcSMatt Macy #define MINSIZEARRAY	4
42*eda14cbcSMatt Macy 
43*eda14cbcSMatt Macy 
luaM_growaux_(lua_State * L,void * block,int * size,size_t size_elems,int limit,const char * what)44*eda14cbcSMatt Macy void *luaM_growaux_ (lua_State *L, void *block, int *size, size_t size_elems,
45*eda14cbcSMatt Macy                      int limit, const char *what) {
46*eda14cbcSMatt Macy   void *newblock;
47*eda14cbcSMatt Macy   int newsize;
48*eda14cbcSMatt Macy   if (*size >= limit/2) {  /* cannot double it? */
49*eda14cbcSMatt Macy     if (*size >= limit)  /* cannot grow even a little? */
50*eda14cbcSMatt Macy       luaG_runerror(L, "too many %s (limit is %d)", what, limit);
51*eda14cbcSMatt Macy     newsize = limit;  /* still have at least one free place */
52*eda14cbcSMatt Macy   }
53*eda14cbcSMatt Macy   else {
54*eda14cbcSMatt Macy     newsize = (*size)*2;
55*eda14cbcSMatt Macy     if (newsize < MINSIZEARRAY)
56*eda14cbcSMatt Macy       newsize = MINSIZEARRAY;  /* minimum size */
57*eda14cbcSMatt Macy   }
58*eda14cbcSMatt Macy   newblock = luaM_reallocv(L, block, *size, newsize, size_elems);
59*eda14cbcSMatt Macy   *size = newsize;  /* update only when everything else is OK */
60*eda14cbcSMatt Macy   return newblock;
61*eda14cbcSMatt Macy }
62*eda14cbcSMatt Macy 
63*eda14cbcSMatt Macy 
luaM_toobig(lua_State * L)64*eda14cbcSMatt Macy l_noret luaM_toobig (lua_State *L) {
65*eda14cbcSMatt Macy   luaG_runerror(L, "memory allocation error: block too big");
66*eda14cbcSMatt Macy }
67*eda14cbcSMatt Macy 
68*eda14cbcSMatt Macy 
69*eda14cbcSMatt Macy 
70*eda14cbcSMatt Macy /*
71*eda14cbcSMatt Macy ** generic allocation routine.
72*eda14cbcSMatt Macy */
luaM_realloc_(lua_State * L,void * block,size_t osize,size_t nsize)73*eda14cbcSMatt Macy void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) {
74*eda14cbcSMatt Macy   void *newblock;
75*eda14cbcSMatt Macy   global_State *g = G(L);
76*eda14cbcSMatt Macy   size_t realosize = (block) ? osize : 0;
77*eda14cbcSMatt Macy   lua_assert((realosize == 0) == (block == NULL));
78*eda14cbcSMatt Macy #if defined(HARDMEMTESTS)
79*eda14cbcSMatt Macy   if (nsize > realosize && g->gcrunning)
80*eda14cbcSMatt Macy     luaC_fullgc(L, 1);  /* force a GC whenever possible */
81*eda14cbcSMatt Macy #endif
82*eda14cbcSMatt Macy   newblock = (*g->frealloc)(g->ud, block, osize, nsize);
83*eda14cbcSMatt Macy   if (newblock == NULL && nsize > 0) {
84*eda14cbcSMatt Macy     api_check(L, nsize > realosize,
85*eda14cbcSMatt Macy                  "realloc cannot fail when shrinking a block");
86*eda14cbcSMatt Macy     if (g->gcrunning) {
87*eda14cbcSMatt Macy       luaC_fullgc(L, 1);  /* try to free some memory... */
88*eda14cbcSMatt Macy       newblock = (*g->frealloc)(g->ud, block, osize, nsize);  /* try again */
89*eda14cbcSMatt Macy     }
90*eda14cbcSMatt Macy     if (newblock == NULL)
91*eda14cbcSMatt Macy       luaD_throw(L, LUA_ERRMEM);
92*eda14cbcSMatt Macy   }
93*eda14cbcSMatt Macy   lua_assert((nsize == 0) == (newblock == NULL));
94*eda14cbcSMatt Macy   g->GCdebt = (g->GCdebt + nsize) - realosize;
95*eda14cbcSMatt Macy   return newblock;
96*eda14cbcSMatt Macy }
97