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