aboutsummaryrefslogtreecommitdiff
path: root/src/lj_state.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lj_state.c')
-rw-r--r--src/lj_state.c112
1 files changed, 80 insertions, 32 deletions
diff --git a/src/lj_state.c b/src/lj_state.c
index 1e2cfde9..0b9c46ba 100644
--- a/src/lj_state.c
+++ b/src/lj_state.c
@@ -12,6 +12,7 @@
12#include "lj_obj.h" 12#include "lj_obj.h"
13#include "lj_gc.h" 13#include "lj_gc.h"
14#include "lj_err.h" 14#include "lj_err.h"
15#include "lj_buf.h"
15#include "lj_str.h" 16#include "lj_str.h"
16#include "lj_tab.h" 17#include "lj_tab.h"
17#include "lj_func.h" 18#include "lj_func.h"
@@ -24,8 +25,10 @@
24#include "lj_trace.h" 25#include "lj_trace.h"
25#include "lj_dispatch.h" 26#include "lj_dispatch.h"
26#include "lj_vm.h" 27#include "lj_vm.h"
28#include "lj_prng.h"
27#include "lj_lex.h" 29#include "lj_lex.h"
28#include "lj_alloc.h" 30#include "lj_alloc.h"
31#include "luajit.h"
29 32
30/* -- Stack handling ------------------------------------------------------ */ 33/* -- Stack handling ------------------------------------------------------ */
31 34
@@ -47,6 +50,7 @@
47** one extra slot if mobj is not a function. Only lj_meta_tset needs 5 50** one extra slot if mobj is not a function. Only lj_meta_tset needs 5
48** slots above top, but then mobj is always a function. So we can get by 51** slots above top, but then mobj is always a function. So we can get by
49** with 5 extra slots. 52** with 5 extra slots.
53** LJ_FR2: We need 2 more slots for the frame PC and the continuation PC.
50*/ 54*/
51 55
52/* Resize stack slots and adjust pointers in state. */ 56/* Resize stack slots and adjust pointers in state. */
@@ -57,9 +61,10 @@ static void resizestack(lua_State *L, MSize n)
57 MSize oldsize = L->stacksize; 61 MSize oldsize = L->stacksize;
58 MSize realsize = n + 1 + LJ_STACK_EXTRA; 62 MSize realsize = n + 1 + LJ_STACK_EXTRA;
59 GCobj *up; 63 GCobj *up;
60 lua_assert((MSize)(tvref(L->maxstack)-oldst)==L->stacksize-LJ_STACK_EXTRA-1); 64 lj_assertL((MSize)(tvref(L->maxstack)-oldst) == L->stacksize-LJ_STACK_EXTRA-1,
65 "inconsistent stack size");
61 st = (TValue *)lj_mem_realloc(L, tvref(L->stack), 66 st = (TValue *)lj_mem_realloc(L, tvref(L->stack),
62 (MSize)(L->stacksize*sizeof(TValue)), 67 (MSize)(oldsize*sizeof(TValue)),
63 (MSize)(realsize*sizeof(TValue))); 68 (MSize)(realsize*sizeof(TValue)));
64 setmref(L->stack, st); 69 setmref(L->stack, st);
65 delta = (char *)st - (char *)oldst; 70 delta = (char *)st - (char *)oldst;
@@ -67,12 +72,12 @@ static void resizestack(lua_State *L, MSize n)
67 while (oldsize < realsize) /* Clear new slots. */ 72 while (oldsize < realsize) /* Clear new slots. */
68 setnilV(st + oldsize++); 73 setnilV(st + oldsize++);
69 L->stacksize = realsize; 74 L->stacksize = realsize;
75 if ((size_t)(mref(G(L)->jit_base, char) - (char *)oldst) < oldsize)
76 setmref(G(L)->jit_base, mref(G(L)->jit_base, char) + delta);
70 L->base = (TValue *)((char *)L->base + delta); 77 L->base = (TValue *)((char *)L->base + delta);
71 L->top = (TValue *)((char *)L->top + delta); 78 L->top = (TValue *)((char *)L->top + delta);
72 for (up = gcref(L->openupval); up != NULL; up = gcnext(up)) 79 for (up = gcref(L->openupval); up != NULL; up = gcnext(up))
73 setmref(gco2uv(up)->v, (TValue *)((char *)uvval(gco2uv(up)) + delta)); 80 setmref(gco2uv(up)->v, (TValue *)((char *)uvval(gco2uv(up)) + delta));
74 if (obj2gco(L) == gcref(G(L)->jit_L))
75 setmref(G(L)->jit_base, mref(G(L)->jit_base, char) + delta);
76} 81}
77 82
78/* Relimit stack after error, in case the limit was overdrawn. */ 83/* Relimit stack after error, in case the limit was overdrawn. */
@@ -89,7 +94,8 @@ void lj_state_shrinkstack(lua_State *L, MSize used)
89 return; /* Avoid stack shrinking while handling stack overflow. */ 94 return; /* Avoid stack shrinking while handling stack overflow. */
90 if (4*used < L->stacksize && 95 if (4*used < L->stacksize &&
91 2*(LJ_STACK_START+LJ_STACK_EXTRA) < L->stacksize && 96 2*(LJ_STACK_START+LJ_STACK_EXTRA) < L->stacksize &&
92 obj2gco(L) != gcref(G(L)->jit_L)) /* Don't shrink stack of live trace. */ 97 /* Don't shrink stack of live trace. */
98 (tvref(G(L)->jit_base) == NULL || obj2gco(L) != gcref(G(L)->cur_L)))
93 resizestack(L, L->stacksize >> 1); 99 resizestack(L, L->stacksize >> 1);
94} 100}
95 101
@@ -125,8 +131,9 @@ static void stack_init(lua_State *L1, lua_State *L)
125 L1->stacksize = LJ_STACK_START + LJ_STACK_EXTRA; 131 L1->stacksize = LJ_STACK_START + LJ_STACK_EXTRA;
126 stend = st + L1->stacksize; 132 stend = st + L1->stacksize;
127 setmref(L1->maxstack, stend - LJ_STACK_EXTRA - 1); 133 setmref(L1->maxstack, stend - LJ_STACK_EXTRA - 1);
128 L1->base = L1->top = st+1; 134 setthreadV(L1, st++, L1); /* Needed for curr_funcisL() on empty stack. */
129 setthreadV(L1, st, L1); /* Needed for curr_funcisL() on empty stack. */ 135 if (LJ_FR2) setnilV(st++);
136 L1->base = L1->top = st;
130 while (st < stend) /* Clear new slots. */ 137 while (st < stend) /* Clear new slots. */
131 setnilV(st++); 138 setnilV(st++);
132} 139}
@@ -143,12 +150,13 @@ static TValue *cpluaopen(lua_State *L, lua_CFunction dummy, void *ud)
143 /* NOBARRIER: State initialization, all objects are white. */ 150 /* NOBARRIER: State initialization, all objects are white. */
144 setgcref(L->env, obj2gco(lj_tab_new(L, 0, LJ_MIN_GLOBAL))); 151 setgcref(L->env, obj2gco(lj_tab_new(L, 0, LJ_MIN_GLOBAL)));
145 settabV(L, registry(L), lj_tab_new(L, 0, LJ_MIN_REGISTRY)); 152 settabV(L, registry(L), lj_tab_new(L, 0, LJ_MIN_REGISTRY));
146 lj_str_resize(L, LJ_MIN_STRTAB-1); 153 lj_str_init(L);
147 lj_meta_init(L); 154 lj_meta_init(L);
148 lj_lex_init(L); 155 lj_lex_init(L);
149 fixstring(lj_err_str(L, LJ_ERR_ERRMEM)); /* Preallocate memory error msg. */ 156 fixstring(lj_err_str(L, LJ_ERR_ERRMEM)); /* Preallocate memory error msg. */
150 g->gc.threshold = 4*g->gc.total; 157 g->gc.threshold = 4*g->gc.total;
151 lj_trace_initstate(g); 158 lj_trace_initstate(g);
159 lj_err_verify();
152 return NULL; 160 return NULL;
153} 161}
154 162
@@ -157,16 +165,25 @@ static void close_state(lua_State *L)
157 global_State *g = G(L); 165 global_State *g = G(L);
158 lj_func_closeuv(L, tvref(L->stack)); 166 lj_func_closeuv(L, tvref(L->stack));
159 lj_gc_freeall(g); 167 lj_gc_freeall(g);
160 lua_assert(gcref(g->gc.root) == obj2gco(L)); 168 lj_assertG(gcref(g->gc.root) == obj2gco(L),
161 lua_assert(g->strnum == 0); 169 "main thread is not first GC object");
170 lj_assertG(g->str.num == 0, "leaked %d strings", g->str.num);
162 lj_trace_freestate(g); 171 lj_trace_freestate(g);
163#if LJ_HASFFI 172#if LJ_HASFFI
164 lj_ctype_freestate(g); 173 lj_ctype_freestate(g);
165#endif 174#endif
166 lj_mem_freevec(g, g->strhash, g->strmask+1, GCRef); 175 lj_str_freetab(g);
167 lj_str_freebuf(g, &g->tmpbuf); 176 lj_buf_free(g, &g->tmpbuf);
168 lj_mem_freevec(g, tvref(L->stack), L->stacksize, TValue); 177 lj_mem_freevec(g, tvref(L->stack), L->stacksize, TValue);
169 lua_assert(g->gc.total == sizeof(GG_State)); 178#if LJ_64
179 if (mref(g->gc.lightudseg, uint32_t)) {
180 MSize segnum = g->gc.lightudnum ? (2 << lj_fls(g->gc.lightudnum)) : 2;
181 lj_mem_freevec(g, mref(g->gc.lightudseg, uint32_t), segnum, uint32_t);
182 }
183#endif
184 lj_assertG(g->gc.total == sizeof(GG_State),
185 "memory leak of %lld bytes",
186 (long long)(g->gc.total - sizeof(GG_State)));
170#ifndef LUAJIT_USE_SYSMALLOC 187#ifndef LUAJIT_USE_SYSMALLOC
171 if (g->allocf == lj_alloc_f) 188 if (g->allocf == lj_alloc_f)
172 lj_alloc_destroy(g->allocd); 189 lj_alloc_destroy(g->allocd);
@@ -175,17 +192,34 @@ static void close_state(lua_State *L)
175 g->allocf(g->allocd, G2GG(g), sizeof(GG_State), 0); 192 g->allocf(g->allocd, G2GG(g), sizeof(GG_State), 0);
176} 193}
177 194
178#if LJ_64 && !(defined(LUAJIT_USE_VALGRIND) && defined(LUAJIT_USE_SYSMALLOC)) 195#if LJ_64 && !LJ_GC64 && !(defined(LUAJIT_USE_VALGRIND) && defined(LUAJIT_USE_SYSMALLOC))
179lua_State *lj_state_newstate(lua_Alloc f, void *ud) 196lua_State *lj_state_newstate(lua_Alloc allocf, void *allocd)
180#else 197#else
181LUA_API lua_State *lua_newstate(lua_Alloc f, void *ud) 198LUA_API lua_State *lua_newstate(lua_Alloc allocf, void *allocd)
182#endif 199#endif
183{ 200{
184 GG_State *GG = (GG_State *)f(ud, NULL, 0, sizeof(GG_State)); 201 PRNGState prng;
185 lua_State *L = &GG->L; 202 GG_State *GG;
186 global_State *g = &GG->g; 203 lua_State *L;
187 if (GG == NULL || !checkptr32(GG)) return NULL; 204 global_State *g;
205 /* We need the PRNG for the memory allocator, so initialize this first. */
206 if (!lj_prng_seed_secure(&prng)) {
207 lj_assertX(0, "secure PRNG seeding failed");
208 /* Can only return NULL here, so this errors with "not enough memory". */
209 return NULL;
210 }
211#ifndef LUAJIT_USE_SYSMALLOC
212 if (allocf == LJ_ALLOCF_INTERNAL) {
213 allocd = lj_alloc_create(&prng);
214 if (!allocd) return NULL;
215 allocf = lj_alloc_f;
216 }
217#endif
218 GG = (GG_State *)allocf(allocd, NULL, 0, sizeof(GG_State));
219 if (GG == NULL || !checkptrGC(GG)) return NULL;
188 memset(GG, 0, sizeof(GG_State)); 220 memset(GG, 0, sizeof(GG_State));
221 L = &GG->L;
222 g = &GG->g;
189 L->gct = ~LJ_TTHREAD; 223 L->gct = ~LJ_TTHREAD;
190 L->marked = LJ_GC_WHITE0 | LJ_GC_FIXED | LJ_GC_SFIXED; /* Prevent free. */ 224 L->marked = LJ_GC_WHITE0 | LJ_GC_FIXED | LJ_GC_SFIXED; /* Prevent free. */
191 L->dummy_ffid = FF_C; 225 L->dummy_ffid = FF_C;
@@ -193,17 +227,25 @@ LUA_API lua_State *lua_newstate(lua_Alloc f, void *ud)
193 g->gc.currentwhite = LJ_GC_WHITE0 | LJ_GC_FIXED; 227 g->gc.currentwhite = LJ_GC_WHITE0 | LJ_GC_FIXED;
194 g->strempty.marked = LJ_GC_WHITE0; 228 g->strempty.marked = LJ_GC_WHITE0;
195 g->strempty.gct = ~LJ_TSTR; 229 g->strempty.gct = ~LJ_TSTR;
196 g->allocf = f; 230 g->allocf = allocf;
197 g->allocd = ud; 231 g->allocd = allocd;
232 g->prng = prng;
233#ifndef LUAJIT_USE_SYSMALLOC
234 if (allocf == lj_alloc_f) {
235 lj_alloc_setprng(allocd, &g->prng);
236 }
237#endif
198 setgcref(g->mainthref, obj2gco(L)); 238 setgcref(g->mainthref, obj2gco(L));
199 setgcref(g->uvhead.prev, obj2gco(&g->uvhead)); 239 setgcref(g->uvhead.prev, obj2gco(&g->uvhead));
200 setgcref(g->uvhead.next, obj2gco(&g->uvhead)); 240 setgcref(g->uvhead.next, obj2gco(&g->uvhead));
201 g->strmask = ~(MSize)0; 241 g->str.mask = ~(MSize)0;
202 setnilV(registry(L)); 242 setnilV(registry(L));
203 setnilV(&g->nilnode.val); 243 setnilV(&g->nilnode.val);
204 setnilV(&g->nilnode.key); 244 setnilV(&g->nilnode.key);
245#if !LJ_GC64
205 setmref(g->nilnode.freetop, &g->nilnode); 246 setmref(g->nilnode.freetop, &g->nilnode);
206 lj_str_initbuf(&g->tmpbuf); 247#endif
248 lj_buf_init(NULL, &g->tmpbuf);
207 g->gc.state = GCSpause; 249 g->gc.state = GCSpause;
208 setgcref(g->gc.root, obj2gco(L)); 250 setgcref(g->gc.root, obj2gco(L));
209 setmref(g->gc.sweep, &g->gc.root); 251 setmref(g->gc.sweep, &g->gc.root);
@@ -217,7 +259,7 @@ LUA_API lua_State *lua_newstate(lua_Alloc f, void *ud)
217 close_state(L); 259 close_state(L);
218 return NULL; 260 return NULL;
219 } 261 }
220 L->status = 0; 262 L->status = LUA_OK;
221 return L; 263 return L;
222} 264}
223 265
@@ -236,6 +278,10 @@ LUA_API void lua_close(lua_State *L)
236 global_State *g = G(L); 278 global_State *g = G(L);
237 int i; 279 int i;
238 L = mainthread(g); /* Only the main thread can be closed. */ 280 L = mainthread(g); /* Only the main thread can be closed. */
281#if LJ_HASPROFILE
282 luaJIT_profile_stop(L);
283#endif
284 setgcrefnull(g->cur_L);
239 lj_func_closeuv(L, tvref(L->stack)); 285 lj_func_closeuv(L, tvref(L->stack));
240 lj_gc_separateudata(g, 1); /* Separate udata which have GC metamethods. */ 286 lj_gc_separateudata(g, 1); /* Separate udata which have GC metamethods. */
241#if LJ_HASJIT 287#if LJ_HASJIT
@@ -245,10 +291,10 @@ LUA_API void lua_close(lua_State *L)
245#endif 291#endif
246 for (i = 0;;) { 292 for (i = 0;;) {
247 hook_enter(g); 293 hook_enter(g);
248 L->status = 0; 294 L->status = LUA_OK;
295 L->base = L->top = tvref(L->stack) + 1 + LJ_FR2;
249 L->cframe = NULL; 296 L->cframe = NULL;
250 L->base = L->top = tvref(L->stack) + 1; 297 if (lj_vm_cpcall(L, NULL, NULL, cpfinalize) == LUA_OK) {
251 if (lj_vm_cpcall(L, NULL, NULL, cpfinalize) == 0) {
252 if (++i >= 10) break; 298 if (++i >= 10) break;
253 lj_gc_separateudata(g, 1); /* Separate udata again. */ 299 lj_gc_separateudata(g, 1); /* Separate udata again. */
254 if (gcref(g->gc.mmudata) == NULL) /* Until nothing is left to do. */ 300 if (gcref(g->gc.mmudata) == NULL) /* Until nothing is left to do. */
@@ -263,7 +309,7 @@ lua_State *lj_state_new(lua_State *L)
263 lua_State *L1 = lj_mem_newobj(L, lua_State); 309 lua_State *L1 = lj_mem_newobj(L, lua_State);
264 L1->gct = ~LJ_TTHREAD; 310 L1->gct = ~LJ_TTHREAD;
265 L1->dummy_ffid = FF_C; 311 L1->dummy_ffid = FF_C;
266 L1->status = 0; 312 L1->status = LUA_OK;
267 L1->stacksize = 0; 313 L1->stacksize = 0;
268 setmref(L1->stack, NULL); 314 setmref(L1->stack, NULL);
269 L1->cframe = NULL; 315 L1->cframe = NULL;
@@ -272,15 +318,17 @@ lua_State *lj_state_new(lua_State *L)
272 setmrefr(L1->glref, L->glref); 318 setmrefr(L1->glref, L->glref);
273 setgcrefr(L1->env, L->env); 319 setgcrefr(L1->env, L->env);
274 stack_init(L1, L); /* init stack */ 320 stack_init(L1, L); /* init stack */
275 lua_assert(iswhite(obj2gco(L1))); 321 lj_assertL(iswhite(obj2gco(L1)), "new thread object is not white");
276 return L1; 322 return L1;
277} 323}
278 324
279void LJ_FASTCALL lj_state_free(global_State *g, lua_State *L) 325void LJ_FASTCALL lj_state_free(global_State *g, lua_State *L)
280{ 326{
281 lua_assert(L != mainthread(g)); 327 lj_assertG(L != mainthread(g), "free of main thread");
328 if (obj2gco(L) == gcref(g->cur_L))
329 setgcrefnull(g->cur_L);
282 lj_func_closeuv(L, tvref(L->stack)); 330 lj_func_closeuv(L, tvref(L->stack));
283 lua_assert(gcref(L->openupval) == NULL); 331 lj_assertG(gcref(L->openupval) == NULL, "stale open upvalues");
284 lj_mem_freevec(g, tvref(L->stack), L->stacksize, TValue); 332 lj_mem_freevec(g, tvref(L->stack), L->stacksize, TValue);
285 lj_mem_freet(g, L); 333 lj_mem_freet(g, L);
286} 334}