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