diff options
Diffstat (limited to 'src/lj_trace.c')
-rw-r--r-- | src/lj_trace.c | 55 |
1 files changed, 27 insertions, 28 deletions
diff --git a/src/lj_trace.c b/src/lj_trace.c index 0a973d51..b5946346 100644 --- a/src/lj_trace.c +++ b/src/lj_trace.c | |||
@@ -532,46 +532,52 @@ static TValue *trace_state(lua_State *L, lua_CFunction dummy, void *ud) | |||
532 | /* -- Event handling ------------------------------------------------------ */ | 532 | /* -- Event handling ------------------------------------------------------ */ |
533 | 533 | ||
534 | /* A bytecode instruction is about to be executed. Record it. */ | 534 | /* A bytecode instruction is about to be executed. Record it. */ |
535 | void lj_trace_ins(jit_State *J) | 535 | void lj_trace_ins(jit_State *J, const BCIns *pc) |
536 | { | 536 | { |
537 | while (lj_vm_cpcall(J->L, NULL, (void *)J, trace_state) != 0) | 537 | /* Note: J->L must already be set. pc is the true bytecode PC here. */ |
538 | J->state = LJ_TRACE_ERR; | 538 | J->pc = pc; |
539 | } | ||
540 | |||
541 | /* Start recording a new trace. */ | ||
542 | static void trace_new(jit_State *J) | ||
543 | { | ||
544 | lua_assert(J->state == LJ_TRACE_IDLE); | ||
545 | J->state = LJ_TRACE_START; | ||
546 | J->fn = curr_func(J->L); | 539 | J->fn = curr_func(J->L); |
547 | J->pt = funcproto(J->fn); | 540 | J->pt = funcproto(J->fn); |
548 | lj_trace_ins(J); | 541 | while (lj_vm_cpcall(J->L, NULL, (void *)J, trace_state) != 0) |
542 | J->state = LJ_TRACE_ERR; | ||
549 | } | 543 | } |
550 | 544 | ||
551 | /* A hotcount triggered. Start recording a root trace. */ | 545 | /* A hotcount triggered. Start recording a root trace. */ |
552 | void LJ_FASTCALL lj_trace_hot(jit_State *J, const BCIns *pc) | 546 | void LJ_FASTCALL lj_trace_hot(jit_State *J, const BCIns *pc) |
553 | { | 547 | { |
548 | /* Note: pc is the interpreter bytecode PC here. It's offset by 1. */ | ||
554 | hotcount_set(J2GG(J), pc, J->param[JIT_P_hotloop]+1); /* Reset hotcount. */ | 549 | hotcount_set(J2GG(J), pc, J->param[JIT_P_hotloop]+1); /* Reset hotcount. */ |
555 | /* Only start a new trace if not recording or inside __gc call or vmevent. */ | 550 | /* Only start a new trace if not recording or inside __gc call or vmevent. */ |
556 | if (J->state == LJ_TRACE_IDLE && | 551 | if (J->state == LJ_TRACE_IDLE && |
557 | !(J2G(J)->hookmask & (HOOK_GC|HOOK_VMEVENT))) { | 552 | !(J2G(J)->hookmask & (HOOK_GC|HOOK_VMEVENT))) { |
558 | J->parent = 0; /* Root trace. */ | 553 | J->parent = 0; /* Root trace. */ |
559 | J->exitno = 0; | 554 | J->exitno = 0; |
560 | J->pc = pc-1; /* The interpreter bytecode PC is offset by 1. */ | 555 | J->state = LJ_TRACE_START; |
561 | trace_new(J); | 556 | lj_trace_ins(J, pc-1); |
562 | } | 557 | } |
563 | } | 558 | } |
564 | 559 | ||
565 | /* A trace exited. Restore interpreter state and check for hot exits. */ | 560 | /* Check for a hot side exit. If yes, start recording a side trace. */ |
561 | static void trace_hotside(jit_State *J, const BCIns *pc) | ||
562 | { | ||
563 | SnapShot *snap = &J->trace[J->parent]->snap[J->exitno]; | ||
564 | if (!(J2G(J)->hookmask & (HOOK_GC|HOOK_VMEVENT)) && | ||
565 | snap->count != SNAPCOUNT_DONE && | ||
566 | ++snap->count >= J->param[JIT_P_hotexit]) { | ||
567 | lua_assert(J->state == LJ_TRACE_IDLE); | ||
568 | /* J->parent is non-zero for a side trace. */ | ||
569 | J->state = LJ_TRACE_START; | ||
570 | lj_trace_ins(J, pc); | ||
571 | } | ||
572 | } | ||
573 | |||
574 | /* A trace exited. Restore interpreter state. */ | ||
566 | void * LJ_FASTCALL lj_trace_exit(jit_State *J, void *exptr) | 575 | void * LJ_FASTCALL lj_trace_exit(jit_State *J, void *exptr) |
567 | { | 576 | { |
577 | const BCIns *pc = lj_snap_restore(J, exptr); | ||
568 | lua_State *L = J->L; | 578 | lua_State *L = J->L; |
569 | void *cf; | 579 | void *cf = cframe_raw(L->cframe); |
570 | 580 | setcframe_pc(cf, pc); /* Restart interpreter at this PC. */ | |
571 | /* Restore interpreter state. */ | ||
572 | lj_snap_restore(J, exptr); | ||
573 | cf = cframe_raw(L->cframe); | ||
574 | setcframe_pc(cf, J->pc); | ||
575 | 581 | ||
576 | lj_vmevent_send(L, TEXIT, | 582 | lj_vmevent_send(L, TEXIT, |
577 | ExitState *ex = (ExitState *)exptr; | 583 | ExitState *ex = (ExitState *)exptr; |
@@ -591,14 +597,7 @@ void * LJ_FASTCALL lj_trace_exit(jit_State *J, void *exptr) | |||
591 | } | 597 | } |
592 | ); | 598 | ); |
593 | 599 | ||
594 | { /* Check for a hot exit. */ | 600 | trace_hotside(J, pc); |
595 | SnapShot *snap = &J->trace[J->parent]->snap[J->exitno]; | ||
596 | if (!(J2G(J)->hookmask & (HOOK_GC|HOOK_VMEVENT)) && | ||
597 | snap->count != SNAPCOUNT_DONE && | ||
598 | ++snap->count >= J->param[JIT_P_hotexit]) | ||
599 | trace_new(J); /* Start recording a side trace. */ | ||
600 | } | ||
601 | |||
602 | return cf; /* Return the interpreter C frame. */ | 601 | return cf; /* Return the interpreter C frame. */ |
603 | } | 602 | } |
604 | 603 | ||