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.c43
1 files changed, 28 insertions, 15 deletions
diff --git a/src/lj_state.c b/src/lj_state.c
index ab064266..dc82e260 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"
@@ -26,6 +27,7 @@
26#include "lj_vm.h" 27#include "lj_vm.h"
27#include "lj_lex.h" 28#include "lj_lex.h"
28#include "lj_alloc.h" 29#include "lj_alloc.h"
30#include "luajit.h"
29 31
30/* -- Stack handling ------------------------------------------------------ */ 32/* -- Stack handling ------------------------------------------------------ */
31 33
@@ -47,6 +49,7 @@
47** one extra slot if mobj is not a function. Only lj_meta_tset needs 5 49** 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 50** slots above top, but then mobj is always a function. So we can get by
49** with 5 extra slots. 51** with 5 extra slots.
52** LJ_FR2: We need 2 more slots for the frame PC and the continuation PC.
50*/ 53*/
51 54
52/* Resize stack slots and adjust pointers in state. */ 55/* Resize stack slots and adjust pointers in state. */
@@ -59,7 +62,7 @@ static void resizestack(lua_State *L, MSize n)
59 GCobj *up; 62 GCobj *up;
60 lua_assert((MSize)(tvref(L->maxstack)-oldst)==L->stacksize-LJ_STACK_EXTRA-1); 63 lua_assert((MSize)(tvref(L->maxstack)-oldst)==L->stacksize-LJ_STACK_EXTRA-1);
61 st = (TValue *)lj_mem_realloc(L, tvref(L->stack), 64 st = (TValue *)lj_mem_realloc(L, tvref(L->stack),
62 (MSize)(L->stacksize*sizeof(TValue)), 65 (MSize)(oldsize*sizeof(TValue)),
63 (MSize)(realsize*sizeof(TValue))); 66 (MSize)(realsize*sizeof(TValue)));
64 setmref(L->stack, st); 67 setmref(L->stack, st);
65 delta = (char *)st - (char *)oldst; 68 delta = (char *)st - (char *)oldst;
@@ -67,12 +70,12 @@ static void resizestack(lua_State *L, MSize n)
67 while (oldsize < realsize) /* Clear new slots. */ 70 while (oldsize < realsize) /* Clear new slots. */
68 setnilV(st + oldsize++); 71 setnilV(st + oldsize++);
69 L->stacksize = realsize; 72 L->stacksize = realsize;
73 if ((size_t)(mref(G(L)->jit_base, char) - (char *)oldst) < oldsize)
74 setmref(G(L)->jit_base, mref(G(L)->jit_base, char) + delta);
70 L->base = (TValue *)((char *)L->base + delta); 75 L->base = (TValue *)((char *)L->base + delta);
71 L->top = (TValue *)((char *)L->top + delta); 76 L->top = (TValue *)((char *)L->top + delta);
72 for (up = gcref(L->openupval); up != NULL; up = gcnext(up)) 77 for (up = gcref(L->openupval); up != NULL; up = gcnext(up))
73 setmref(gco2uv(up)->v, (TValue *)((char *)uvval(gco2uv(up)) + delta)); 78 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} 79}
77 80
78/* Relimit stack after error, in case the limit was overdrawn. */ 81/* Relimit stack after error, in case the limit was overdrawn. */
@@ -89,7 +92,8 @@ void lj_state_shrinkstack(lua_State *L, MSize used)
89 return; /* Avoid stack shrinking while handling stack overflow. */ 92 return; /* Avoid stack shrinking while handling stack overflow. */
90 if (4*used < L->stacksize && 93 if (4*used < L->stacksize &&
91 2*(LJ_STACK_START+LJ_STACK_EXTRA) < L->stacksize && 94 2*(LJ_STACK_START+LJ_STACK_EXTRA) < L->stacksize &&
92 obj2gco(L) != gcref(G(L)->jit_L)) /* Don't shrink stack of live trace. */ 95 /* Don't shrink stack of live trace. */
96 (tvref(G(L)->jit_base) == NULL || obj2gco(L) != gcref(G(L)->cur_L)))
93 resizestack(L, L->stacksize >> 1); 97 resizestack(L, L->stacksize >> 1);
94} 98}
95 99
@@ -125,8 +129,9 @@ static void stack_init(lua_State *L1, lua_State *L)
125 L1->stacksize = LJ_STACK_START + LJ_STACK_EXTRA; 129 L1->stacksize = LJ_STACK_START + LJ_STACK_EXTRA;
126 stend = st + L1->stacksize; 130 stend = st + L1->stacksize;
127 setmref(L1->maxstack, stend - LJ_STACK_EXTRA - 1); 131 setmref(L1->maxstack, stend - LJ_STACK_EXTRA - 1);
128 L1->base = L1->top = st+1; 132 setthreadV(L1, st++, L1); /* Needed for curr_funcisL() on empty stack. */
129 setthreadV(L1, st, L1); /* Needed for curr_funcisL() on empty stack. */ 133 if (LJ_FR2) setnilV(st++);
134 L1->base = L1->top = st;
130 while (st < stend) /* Clear new slots. */ 135 while (st < stend) /* Clear new slots. */
131 setnilV(st++); 136 setnilV(st++);
132} 137}
@@ -164,7 +169,7 @@ static void close_state(lua_State *L)
164 lj_ctype_freestate(g); 169 lj_ctype_freestate(g);
165#endif 170#endif
166 lj_mem_freevec(g, g->strhash, g->strmask+1, GCRef); 171 lj_mem_freevec(g, g->strhash, g->strmask+1, GCRef);
167 lj_str_freebuf(g, &g->tmpbuf); 172 lj_buf_free(g, &g->tmpbuf);
168 lj_mem_freevec(g, tvref(L->stack), L->stacksize, TValue); 173 lj_mem_freevec(g, tvref(L->stack), L->stacksize, TValue);
169 lua_assert(g->gc.total == sizeof(GG_State)); 174 lua_assert(g->gc.total == sizeof(GG_State));
170#ifndef LUAJIT_USE_SYSMALLOC 175#ifndef LUAJIT_USE_SYSMALLOC
@@ -175,7 +180,7 @@ static void close_state(lua_State *L)
175 g->allocf(g->allocd, G2GG(g), sizeof(GG_State), 0); 180 g->allocf(g->allocd, G2GG(g), sizeof(GG_State), 0);
176} 181}
177 182
178#if LJ_64 && !(defined(LUAJIT_USE_VALGRIND) && defined(LUAJIT_USE_SYSMALLOC)) 183#if LJ_64 && !LJ_GC64 && !(defined(LUAJIT_USE_VALGRIND) && defined(LUAJIT_USE_SYSMALLOC))
179lua_State *lj_state_newstate(lua_Alloc f, void *ud) 184lua_State *lj_state_newstate(lua_Alloc f, void *ud)
180#else 185#else
181LUA_API lua_State *lua_newstate(lua_Alloc f, void *ud) 186LUA_API lua_State *lua_newstate(lua_Alloc f, void *ud)
@@ -184,7 +189,7 @@ LUA_API lua_State *lua_newstate(lua_Alloc f, void *ud)
184 GG_State *GG = (GG_State *)f(ud, NULL, 0, sizeof(GG_State)); 189 GG_State *GG = (GG_State *)f(ud, NULL, 0, sizeof(GG_State));
185 lua_State *L = &GG->L; 190 lua_State *L = &GG->L;
186 global_State *g = &GG->g; 191 global_State *g = &GG->g;
187 if (GG == NULL || !checkptr32(GG)) return NULL; 192 if (GG == NULL || !checkptrGC(GG)) return NULL;
188 memset(GG, 0, sizeof(GG_State)); 193 memset(GG, 0, sizeof(GG_State));
189 L->gct = ~LJ_TTHREAD; 194 L->gct = ~LJ_TTHREAD;
190 L->marked = LJ_GC_WHITE0 | LJ_GC_FIXED | LJ_GC_SFIXED; /* Prevent free. */ 195 L->marked = LJ_GC_WHITE0 | LJ_GC_FIXED | LJ_GC_SFIXED; /* Prevent free. */
@@ -202,8 +207,10 @@ LUA_API lua_State *lua_newstate(lua_Alloc f, void *ud)
202 setnilV(registry(L)); 207 setnilV(registry(L));
203 setnilV(&g->nilnode.val); 208 setnilV(&g->nilnode.val);
204 setnilV(&g->nilnode.key); 209 setnilV(&g->nilnode.key);
210#if !LJ_GC64
205 setmref(g->nilnode.freetop, &g->nilnode); 211 setmref(g->nilnode.freetop, &g->nilnode);
206 lj_str_initbuf(&g->tmpbuf); 212#endif
213 lj_buf_init(NULL, &g->tmpbuf);
207 g->gc.state = GCSpause; 214 g->gc.state = GCSpause;
208 setgcref(g->gc.root, obj2gco(L)); 215 setgcref(g->gc.root, obj2gco(L));
209 setmref(g->gc.sweep, &g->gc.root); 216 setmref(g->gc.sweep, &g->gc.root);
@@ -217,7 +224,7 @@ LUA_API lua_State *lua_newstate(lua_Alloc f, void *ud)
217 close_state(L); 224 close_state(L);
218 return NULL; 225 return NULL;
219 } 226 }
220 L->status = 0; 227 L->status = LUA_OK;
221 return L; 228 return L;
222} 229}
223 230
@@ -236,6 +243,10 @@ LUA_API void lua_close(lua_State *L)
236 global_State *g = G(L); 243 global_State *g = G(L);
237 int i; 244 int i;
238 L = mainthread(g); /* Only the main thread can be closed. */ 245 L = mainthread(g); /* Only the main thread can be closed. */
246#if LJ_HASPROFILE
247 luaJIT_profile_stop(L);
248#endif
249 setgcrefnull(g->cur_L);
239 lj_func_closeuv(L, tvref(L->stack)); 250 lj_func_closeuv(L, tvref(L->stack));
240 lj_gc_separateudata(g, 1); /* Separate udata which have GC metamethods. */ 251 lj_gc_separateudata(g, 1); /* Separate udata which have GC metamethods. */
241#if LJ_HASJIT 252#if LJ_HASJIT
@@ -245,10 +256,10 @@ LUA_API void lua_close(lua_State *L)
245#endif 256#endif
246 for (i = 0;;) { 257 for (i = 0;;) {
247 hook_enter(g); 258 hook_enter(g);
248 L->status = 0; 259 L->status = LUA_OK;
260 L->base = L->top = tvref(L->stack) + 1 + LJ_FR2;
249 L->cframe = NULL; 261 L->cframe = NULL;
250 L->base = L->top = tvref(L->stack) + 1; 262 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; 263 if (++i >= 10) break;
253 lj_gc_separateudata(g, 1); /* Separate udata again. */ 264 lj_gc_separateudata(g, 1); /* Separate udata again. */
254 if (gcref(g->gc.mmudata) == NULL) /* Until nothing is left to do. */ 265 if (gcref(g->gc.mmudata) == NULL) /* Until nothing is left to do. */
@@ -263,7 +274,7 @@ lua_State *lj_state_new(lua_State *L)
263 lua_State *L1 = lj_mem_newobj(L, lua_State); 274 lua_State *L1 = lj_mem_newobj(L, lua_State);
264 L1->gct = ~LJ_TTHREAD; 275 L1->gct = ~LJ_TTHREAD;
265 L1->dummy_ffid = FF_C; 276 L1->dummy_ffid = FF_C;
266 L1->status = 0; 277 L1->status = LUA_OK;
267 L1->stacksize = 0; 278 L1->stacksize = 0;
268 setmref(L1->stack, NULL); 279 setmref(L1->stack, NULL);
269 L1->cframe = NULL; 280 L1->cframe = NULL;
@@ -279,6 +290,8 @@ lua_State *lj_state_new(lua_State *L)
279void LJ_FASTCALL lj_state_free(global_State *g, lua_State *L) 290void LJ_FASTCALL lj_state_free(global_State *g, lua_State *L)
280{ 291{
281 lua_assert(L != mainthread(g)); 292 lua_assert(L != mainthread(g));
293 if (obj2gco(L) == gcref(g->cur_L))
294 setgcrefnull(g->cur_L);
282 lj_func_closeuv(L, tvref(L->stack)); 295 lj_func_closeuv(L, tvref(L->stack));
283 lua_assert(gcref(L->openupval) == NULL); 296 lua_assert(gcref(L->openupval) == NULL);
284 lj_mem_freevec(g, tvref(L->stack), L->stacksize, TValue); 297 lj_mem_freevec(g, tvref(L->stack), L->stacksize, TValue);