aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lj_gc.c18
-rw-r--r--src/lj_obj.h2
-rw-r--r--src/lj_parse.c4
-rw-r--r--src/lj_state.c1
-rw-r--r--src/lj_trace.c91
-rw-r--r--src/lj_vmevent.c5
-rw-r--r--src/lj_vmevent.h22
7 files changed, 76 insertions, 67 deletions
diff --git a/src/lj_gc.c b/src/lj_gc.c
index d9581d20..c779d583 100644
--- a/src/lj_gc.c
+++ b/src/lj_gc.c
@@ -106,6 +106,7 @@ static void gc_mark_start(global_State *g)
106 setgcrefnull(g->gc.weak); 106 setgcrefnull(g->gc.weak);
107 gc_markobj(g, mainthread(g)); 107 gc_markobj(g, mainthread(g));
108 gc_markobj(g, tabref(mainthread(g)->env)); 108 gc_markobj(g, tabref(mainthread(g)->env));
109 gc_markobj(g, vmthread(g));
109 gc_marktv(g, &g->registrytv); 110 gc_marktv(g, &g->registrytv);
110 gc_mark_gcroot(g); 111 gc_mark_gcroot(g);
111 g->gc.state = GCSpropagate; 112 g->gc.state = GCSpropagate;
@@ -507,24 +508,25 @@ static void gc_call_finalizer(global_State *g, lua_State *L,
507 uint8_t oldh = hook_save(g); 508 uint8_t oldh = hook_save(g);
508 GCSize oldt = g->gc.threshold; 509 GCSize oldt = g->gc.threshold;
509 int errcode; 510 int errcode;
511 lua_State *VL = vmthread(g);
510 TValue *top; 512 TValue *top;
511 lj_trace_abort(g); 513 lj_trace_abort(g);
512 hook_entergc(g); /* Disable hooks and new traces during __gc. */ 514 hook_entergc(g); /* Disable hooks and new traces during __gc. */
513 if (LJ_HASPROFILE && (oldh & HOOK_PROFILE)) lj_dispatch_update(g); 515 if (LJ_HASPROFILE && (oldh & HOOK_PROFILE)) lj_dispatch_update(g);
514 g->gc.threshold = LJ_MAX_MEM; /* Prevent GC steps. */ 516 g->gc.threshold = LJ_MAX_MEM; /* Prevent GC steps. */
515 top = L->top; 517 top = VL->top;
516 copyTV(L, top++, mo); 518 copyTV(VL, top++, mo);
517 if (LJ_FR2) setnilV(top++); 519 if (LJ_FR2) setnilV(top++);
518 setgcV(L, top, o, ~o->gch.gct); 520 setgcV(VL, top, o, ~o->gch.gct);
519 L->top = top+1; 521 VL->top = top+1;
520 errcode = lj_vm_pcall(L, top, 1+0, -1); /* Stack: |mo|o| -> | */ 522 errcode = lj_vm_pcall(VL, top, 1+0, -1); /* Stack: |mo|o| -> | */
523 setgcref(g->cur_L, obj2gco(L));
521 hook_restore(g, oldh); 524 hook_restore(g, oldh);
522 if (LJ_HASPROFILE && (oldh & HOOK_PROFILE)) lj_dispatch_update(g); 525 if (LJ_HASPROFILE && (oldh & HOOK_PROFILE)) lj_dispatch_update(g);
523 g->gc.threshold = oldt; /* Restore GC threshold. */ 526 g->gc.threshold = oldt; /* Restore GC threshold. */
524 if (errcode) { 527 if (errcode) {
525 ptrdiff_t errobj = savestack(L, L->top-1); /* Stack may be resized. */ 528 lj_vmevent_send(g, ERRFIN,
526 lj_vmevent_send(L, ERRFIN, 529 copyTV(V, V->top++, L->top-1);
527 copyTV(L, L->top++, restorestack(L, errobj));
528 ); 530 );
529 L->top--; 531 L->top--;
530 } 532 }
diff --git a/src/lj_obj.h b/src/lj_obj.h
index 855727bf..73b186e2 100644
--- a/src/lj_obj.h
+++ b/src/lj_obj.h
@@ -647,6 +647,7 @@ typedef struct global_State {
647 TValue tmptv, tmptv2; /* Temporary TValues. */ 647 TValue tmptv, tmptv2; /* Temporary TValues. */
648 Node nilnode; /* Fallback 1-element hash part (nil key and value). */ 648 Node nilnode; /* Fallback 1-element hash part (nil key and value). */
649 TValue registrytv; /* Anchor for registry. */ 649 TValue registrytv; /* Anchor for registry. */
650 GCRef vmthref; /* Link to VM thread. */
650 GCupval uvhead; /* Head of double-linked list of all open upvalues. */ 651 GCupval uvhead; /* Head of double-linked list of all open upvalues. */
651 int32_t hookcount; /* Instruction hook countdown. */ 652 int32_t hookcount; /* Instruction hook countdown. */
652 int32_t hookcstart; /* Start count for instruction hook counter. */ 653 int32_t hookcstart; /* Start count for instruction hook counter. */
@@ -663,6 +664,7 @@ typedef struct global_State {
663} global_State; 664} global_State;
664 665
665#define mainthread(g) (&gcref(g->mainthref)->th) 666#define mainthread(g) (&gcref(g->mainthref)->th)
667#define vmthread(g) (&gcref(g->vmthref)->th)
666#define niltv(L) \ 668#define niltv(L) \
667 check_exp(tvisnil(&G(L)->nilnode.val), &G(L)->nilnode.val) 669 check_exp(tvisnil(&G(L)->nilnode.val), &G(L)->nilnode.val)
668#define niltvg(g) \ 670#define niltvg(g) \
diff --git a/src/lj_parse.c b/src/lj_parse.c
index e326432a..181ce4d7 100644
--- a/src/lj_parse.c
+++ b/src/lj_parse.c
@@ -1593,8 +1593,8 @@ static GCproto *fs_finish(LexState *ls, BCLine line)
1593 fs_fixup_line(fs, pt, (void *)((char *)pt + ofsli), numline); 1593 fs_fixup_line(fs, pt, (void *)((char *)pt + ofsli), numline);
1594 fs_fixup_var(ls, pt, (uint8_t *)((char *)pt + ofsdbg), ofsvar); 1594 fs_fixup_var(ls, pt, (uint8_t *)((char *)pt + ofsdbg), ofsvar);
1595 1595
1596 lj_vmevent_send(L, BC, 1596 lj_vmevent_send(G(L), BC,
1597 setprotoV(L, L->top++, pt); 1597 setprotoV(V, V->top++, pt);
1598 ); 1598 );
1599 1599
1600 L->top--; /* Pop table of constants. */ 1600 L->top--; /* Pop table of constants. */
diff --git a/src/lj_state.c b/src/lj_state.c
index fb6d41a5..9d4fdcee 100644
--- a/src/lj_state.c
+++ b/src/lj_state.c
@@ -202,6 +202,7 @@ static TValue *cpluaopen(lua_State *L, lua_CFunction dummy, void *ud)
202#endif 202#endif
203 lj_trace_initstate(g); 203 lj_trace_initstate(g);
204 lj_err_verify(); 204 lj_err_verify();
205 setgcref(g->vmthref, obj2gco(lj_state_new(L)));
205 return NULL; 206 return NULL;
206} 207}
207 208
diff --git a/src/lj_trace.c b/src/lj_trace.c
index 3e2cd0b3..47d7faa5 100644
--- a/src/lj_trace.c
+++ b/src/lj_trace.c
@@ -296,8 +296,8 @@ int lj_trace_flushall(lua_State *L)
296 /* Free the whole machine code and invalidate all exit stub groups. */ 296 /* Free the whole machine code and invalidate all exit stub groups. */
297 lj_mcode_free(J); 297 lj_mcode_free(J);
298 memset(J->exitstubgroup, 0, sizeof(J->exitstubgroup)); 298 memset(J->exitstubgroup, 0, sizeof(J->exitstubgroup));
299 lj_vmevent_send(L, TRACE, 299 lj_vmevent_send(J2G(J), TRACE,
300 setstrV(L, L->top++, lj_str_newlit(L, "flush")); 300 setstrV(V, V->top++, lj_str_newlit(V, "flush"));
301 ); 301 );
302 return 0; 302 return 0;
303} 303}
@@ -416,7 +416,6 @@ setpenalty:
416/* Start tracing. */ 416/* Start tracing. */
417static void trace_start(jit_State *J) 417static void trace_start(jit_State *J)
418{ 418{
419 lua_State *L;
420 TraceNo traceno; 419 TraceNo traceno;
421 420
422 if ((J->pt->flags & PROTO_NOJIT)) { /* JIT disabled for this proto? */ 421 if ((J->pt->flags & PROTO_NOJIT)) { /* JIT disabled for this proto? */
@@ -466,20 +465,19 @@ static void trace_start(jit_State *J)
466 J->ktrace = 0; 465 J->ktrace = 0;
467 setgcref(J->cur.startpt, obj2gco(J->pt)); 466 setgcref(J->cur.startpt, obj2gco(J->pt));
468 467
469 L = J->L; 468 lj_vmevent_send(J2G(J), TRACE,
470 lj_vmevent_send(L, TRACE, 469 setstrV(V, V->top++, lj_str_newlit(V, "start"));
471 setstrV(L, L->top++, lj_str_newlit(L, "start")); 470 setintV(V->top++, traceno);
472 setintV(L->top++, traceno); 471 setfuncV(V, V->top++, J->fn);
473 setfuncV(L, L->top++, J->fn); 472 setintV(V->top++, proto_bcpos(J->pt, J->pc));
474 setintV(L->top++, proto_bcpos(J->pt, J->pc));
475 if (J->parent) { 473 if (J->parent) {
476 setintV(L->top++, J->parent); 474 setintV(V->top++, J->parent);
477 setintV(L->top++, J->exitno); 475 setintV(V->top++, J->exitno);
478 } else { 476 } else {
479 BCOp op = bc_op(*J->pc); 477 BCOp op = bc_op(*J->pc);
480 if (op == BC_CALLM || op == BC_CALL || op == BC_ITERC) { 478 if (op == BC_CALLM || op == BC_CALL || op == BC_ITERC) {
481 setintV(L->top++, J->exitno); /* Parent of stitched trace. */ 479 setintV(V->top++, J->exitno); /* Parent of stitched trace. */
482 setintV(L->top++, -1); 480 setintV(V->top++, -1);
483 } 481 }
484 } 482 }
485 ); 483 );
@@ -494,7 +492,6 @@ static void trace_stop(jit_State *J)
494 GCproto *pt = &gcref(J->cur.startpt)->pt; 492 GCproto *pt = &gcref(J->cur.startpt)->pt;
495 TraceNo traceno = J->cur.traceno; 493 TraceNo traceno = J->cur.traceno;
496 GCtrace *T = J->curfinal; 494 GCtrace *T = J->curfinal;
497 lua_State *L;
498 495
499 switch (op) { 496 switch (op) {
500 case BC_FORL: 497 case BC_FORL:
@@ -551,11 +548,10 @@ static void trace_stop(jit_State *J)
551 J->postproc = LJ_POST_NONE; 548 J->postproc = LJ_POST_NONE;
552 trace_save(J, T); 549 trace_save(J, T);
553 550
554 L = J->L; 551 lj_vmevent_send(J2G(J), TRACE,
555 lj_vmevent_send(L, TRACE, 552 setstrV(V, V->top++, lj_str_newlit(V, "stop"));
556 setstrV(L, L->top++, lj_str_newlit(L, "stop")); 553 setintV(V->top++, traceno);
557 setintV(L->top++, traceno); 554 setfuncV(V, V->top++, J->fn);
558 setfuncV(L, L->top++, J->fn);
559 ); 555 );
560} 556}
561 557
@@ -610,18 +606,17 @@ static int trace_abort(jit_State *J)
610 /* Is there anything to abort? */ 606 /* Is there anything to abort? */
611 traceno = J->cur.traceno; 607 traceno = J->cur.traceno;
612 if (traceno) { 608 if (traceno) {
613 ptrdiff_t errobj = savestack(L, L->top-1); /* Stack may be resized. */
614 J->cur.link = 0; 609 J->cur.link = 0;
615 J->cur.linktype = LJ_TRLINK_NONE; 610 J->cur.linktype = LJ_TRLINK_NONE;
616 lj_vmevent_send(L, TRACE, 611 lj_vmevent_send(J2G(J), TRACE,
617 cTValue *bot = tvref(L->stack)+LJ_FR2; 612 cTValue *bot = tvref(L->stack)+LJ_FR2;
618 cTValue *frame; 613 cTValue *frame;
619 const BCIns *pc; 614 const BCIns *pc;
620 BCPos pos = 0; 615 BCPos pos = 0;
621 setstrV(L, L->top++, lj_str_newlit(L, "abort")); 616 setstrV(V, V->top++, lj_str_newlit(V, "abort"));
622 setintV(L->top++, traceno); 617 setintV(V->top++, traceno);
623 /* Find original Lua function call to generate a better error message. */ 618 /* Find original Lua function call to generate a better error message. */
624 for (frame = J->L->base-1, pc = J->pc; ; frame = frame_prev(frame)) { 619 for (frame = L->base-1, pc = J->pc; ; frame = frame_prev(frame)) {
625 if (isluafunc(frame_func(frame))) { 620 if (isluafunc(frame_func(frame))) {
626 pos = proto_bcpos(funcproto(frame_func(frame)), pc); 621 pos = proto_bcpos(funcproto(frame_func(frame)), pc);
627 break; 622 break;
@@ -633,10 +628,10 @@ static int trace_abort(jit_State *J)
633 pc = frame_pc(frame) - 1; 628 pc = frame_pc(frame) - 1;
634 } 629 }
635 } 630 }
636 setfuncV(L, L->top++, frame_func(frame)); 631 setfuncV(V, V->top++, frame_func(frame));
637 setintV(L->top++, pos); 632 setintV(V->top++, pos);
638 copyTV(L, L->top++, restorestack(L, errobj)); 633 copyTV(V, V->top++, L->top-1);
639 copyTV(L, L->top++, &J->errinfo); 634 copyTV(V, V->top++, &J->errinfo);
640 ); 635 );
641 /* Drop aborted trace after the vmevent (which may still access it). */ 636 /* Drop aborted trace after the vmevent (which may still access it). */
642 setgcrefnull(J->trace[traceno]); 637 setgcrefnull(J->trace[traceno]);
@@ -692,16 +687,16 @@ static TValue *trace_state(lua_State *L, lua_CFunction dummy, void *ud)
692 case LJ_TRACE_RECORD: 687 case LJ_TRACE_RECORD:
693 trace_pendpatch(J, 0); 688 trace_pendpatch(J, 0);
694 setvmstate(J2G(J), RECORD); 689 setvmstate(J2G(J), RECORD);
695 lj_vmevent_send_(L, RECORD, 690 lj_vmevent_send_(J2G(J), RECORD,
696 /* Save/restore state for trace recorder. */ 691 /* Save/restore state for trace recorder. */
697 TValue savetv = J2G(J)->tmptv; 692 TValue savetv = J2G(J)->tmptv;
698 TValue savetv2 = J2G(J)->tmptv2; 693 TValue savetv2 = J2G(J)->tmptv2;
699 TraceNo parent = J->parent; 694 TraceNo parent = J->parent;
700 ExitNo exitno = J->exitno; 695 ExitNo exitno = J->exitno;
701 setintV(L->top++, J->cur.traceno); 696 setintV(V->top++, J->cur.traceno);
702 setfuncV(L, L->top++, J->fn); 697 setfuncV(V, V->top++, J->fn);
703 setintV(L->top++, J->pt ? (int32_t)proto_bcpos(J->pt, J->pc) : -1); 698 setintV(V->top++, J->pt ? (int32_t)proto_bcpos(J->pt, J->pc) : -1);
704 setintV(L->top++, J->framedepth); 699 setintV(V->top++, J->framedepth);
705 , 700 ,
706 J2G(J)->tmptv = savetv; 701 J2G(J)->tmptv = savetv;
707 J2G(J)->tmptv2 = savetv2; 702 J2G(J)->tmptv2 = savetv2;
@@ -839,23 +834,23 @@ static TValue *trace_exit_cp(lua_State *L, lua_CFunction dummy, void *ud)
839 834
840#ifndef LUAJIT_DISABLE_VMEVENT 835#ifndef LUAJIT_DISABLE_VMEVENT
841/* Push all registers from exit state. */ 836/* Push all registers from exit state. */
842static void trace_exit_regs(lua_State *L, ExitState *ex) 837static void trace_exit_regs(lua_State *V, ExitState *ex)
843{ 838{
844 int32_t i; 839 int32_t i;
845 setintV(L->top++, RID_NUM_GPR); 840 setintV(V->top++, RID_NUM_GPR);
846 setintV(L->top++, RID_NUM_FPR); 841 setintV(V->top++, RID_NUM_FPR);
847 for (i = 0; i < RID_NUM_GPR; i++) { 842 for (i = 0; i < RID_NUM_GPR; i++) {
848 if (sizeof(ex->gpr[i]) == sizeof(int32_t)) 843 if (sizeof(ex->gpr[i]) == sizeof(int32_t))
849 setintV(L->top++, (int32_t)ex->gpr[i]); 844 setintV(V->top++, (int32_t)ex->gpr[i]);
850 else 845 else
851 setnumV(L->top++, (lua_Number)ex->gpr[i]); 846 setnumV(V->top++, (lua_Number)ex->gpr[i]);
852 } 847 }
853#if !LJ_SOFTFP 848#if !LJ_SOFTFP
854 for (i = 0; i < RID_NUM_FPR; i++) { 849 for (i = 0; i < RID_NUM_FPR; i++) {
855 setnumV(L->top, ex->fpr[i]); 850 setnumV(V->top, ex->fpr[i]);
856 if (LJ_UNLIKELY(tvisnan(L->top))) 851 if (LJ_UNLIKELY(tvisnan(V->top)))
857 setnanV(L->top); 852 setnanV(V->top);
858 L->top++; 853 V->top++;
859 } 854 }
860#endif 855#endif
861} 856}
@@ -897,6 +892,8 @@ int LJ_FASTCALL lj_trace_exit(jit_State *J, void *exptr)
897 892
898#ifdef EXITSTATE_PCREG 893#ifdef EXITSTATE_PCREG
899 J->parent = trace_exit_find(J, (MCode *)(intptr_t)ex->gpr[EXITSTATE_PCREG]); 894 J->parent = trace_exit_find(J, (MCode *)(intptr_t)ex->gpr[EXITSTATE_PCREG]);
895#else
896 UNUSED(ex);
900#endif 897#endif
901 T = traceref(J, J->parent); UNUSED(T); 898 T = traceref(J, J->parent); UNUSED(T);
902#ifdef EXITSTATE_CHECKEXIT 899#ifdef EXITSTATE_CHECKEXIT
@@ -917,11 +914,11 @@ int LJ_FASTCALL lj_trace_exit(jit_State *J, void *exptr)
917 if (exitcode) copyTV(L, L->top++, &exiterr); /* Anchor the error object. */ 914 if (exitcode) copyTV(L, L->top++, &exiterr); /* Anchor the error object. */
918 915
919 if (!(LJ_HASPROFILE && (G(L)->hookmask & HOOK_PROFILE))) 916 if (!(LJ_HASPROFILE && (G(L)->hookmask & HOOK_PROFILE)))
920 lj_vmevent_send(L, TEXIT, 917 lj_vmevent_send(G(L), TEXIT,
921 lj_state_checkstack(L, 4+RID_NUM_GPR+RID_NUM_FPR+LUA_MINSTACK); 918 lj_state_checkstack(V, 4+RID_NUM_GPR+RID_NUM_FPR+LUA_MINSTACK);
922 setintV(L->top++, J->parent); 919 setintV(V->top++, J->parent);
923 setintV(L->top++, J->exitno); 920 setintV(V->top++, J->exitno);
924 trace_exit_regs(L, ex); 921 trace_exit_regs(V, ex);
925 ); 922 );
926 923
927 pc = exd.pc; 924 pc = exd.pc;
diff --git a/src/lj_vmevent.c b/src/lj_vmevent.c
index 070c6144..8913ead9 100644
--- a/src/lj_vmevent.c
+++ b/src/lj_vmevent.c
@@ -38,6 +38,7 @@ ptrdiff_t lj_vmevent_prepare(lua_State *L, VMEvent ev)
38void lj_vmevent_call(lua_State *L, ptrdiff_t argbase) 38void lj_vmevent_call(lua_State *L, ptrdiff_t argbase)
39{ 39{
40 global_State *g = G(L); 40 global_State *g = G(L);
41 lua_State *oldL = gco2th(gcref(g->cur_L));
41 uint8_t oldmask = g->vmevmask; 42 uint8_t oldmask = g->vmevmask;
42 uint8_t oldh = hook_save(g); 43 uint8_t oldh = hook_save(g);
43 int status; 44 int status;
@@ -51,6 +52,10 @@ void lj_vmevent_call(lua_State *L, ptrdiff_t argbase)
51 fputs(tvisstr(L->top) ? strVdata(L->top) : "?", stderr); 52 fputs(tvisstr(L->top) ? strVdata(L->top) : "?", stderr);
52 fputc('\n', stderr); 53 fputc('\n', stderr);
53 } 54 }
55 setgcref(g->cur_L, obj2gco(oldL));
56#if LJ_HASJIT
57 G2J(g)->L = oldL;
58#endif
54 hook_restore(g, oldh); 59 hook_restore(g, oldh);
55 if (g->vmevmask != VMEVENT_NOCACHE) 60 if (g->vmevmask != VMEVENT_NOCACHE)
56 g->vmevmask = oldmask; /* Restore event mask, but not if not modified. */ 61 g->vmevmask = oldmask; /* Restore event mask, but not if not modified. */
diff --git a/src/lj_vmevent.h b/src/lj_vmevent.h
index 8a995360..cdd4f758 100644
--- a/src/lj_vmevent.h
+++ b/src/lj_vmevent.h
@@ -32,23 +32,25 @@ typedef enum {
32} VMEvent; 32} VMEvent;
33 33
34#ifdef LUAJIT_DISABLE_VMEVENT 34#ifdef LUAJIT_DISABLE_VMEVENT
35#define lj_vmevent_send(L, ev, args) UNUSED(L) 35#define lj_vmevent_send(g, ev, args) UNUSED(g)
36#define lj_vmevent_send_(L, ev, args, post) UNUSED(L) 36#define lj_vmevent_send_(g, ev, args, post) UNUSED(g)
37#else 37#else
38#define lj_vmevent_send(L, ev, args) \ 38#define lj_vmevent_send(g, ev, args) \
39 if (G(L)->vmevmask & VMEVENT_MASK(LJ_VMEVENT_##ev)) { \ 39 if ((g)->vmevmask & VMEVENT_MASK(LJ_VMEVENT_##ev)) { \
40 ptrdiff_t argbase = lj_vmevent_prepare(L, LJ_VMEVENT_##ev); \ 40 lua_State *V = vmthread(g); \
41 ptrdiff_t argbase = lj_vmevent_prepare(V, LJ_VMEVENT_##ev); \
41 if (argbase) { \ 42 if (argbase) { \
42 args \ 43 args \
43 lj_vmevent_call(L, argbase); \ 44 lj_vmevent_call(V, argbase); \
44 } \ 45 } \
45 } 46 }
46#define lj_vmevent_send_(L, ev, args, post) \ 47#define lj_vmevent_send_(g, ev, args, post) \
47 if (G(L)->vmevmask & VMEVENT_MASK(LJ_VMEVENT_##ev)) { \ 48 if ((g)->vmevmask & VMEVENT_MASK(LJ_VMEVENT_##ev)) { \
48 ptrdiff_t argbase = lj_vmevent_prepare(L, LJ_VMEVENT_##ev); \ 49 lua_State *V = vmthread(g); \
50 ptrdiff_t argbase = lj_vmevent_prepare(V, LJ_VMEVENT_##ev); \
49 if (argbase) { \ 51 if (argbase) { \
50 args \ 52 args \
51 lj_vmevent_call(L, argbase); \ 53 lj_vmevent_call(V, argbase); \
52 post \ 54 post \
53 } \ 55 } \
54 } 56 }