diff options
| author | Mike Pall <mike> | 2010-01-28 02:30:12 +0100 |
|---|---|---|
| committer | Mike Pall <mike> | 2010-01-28 02:30:12 +0100 |
| commit | 725da9224d2d2a0bc0a1b6504b1fb87bf1674611 (patch) | |
| tree | ef04d598b19bb44b10599c9fa636b2ea934b25b1 | |
| parent | fb2c583cfccc75fb1b1ae95a99bdeb80629cf74c (diff) | |
| download | luajit-725da9224d2d2a0bc0a1b6504b1fb87bf1674611.tar.gz luajit-725da9224d2d2a0bc0a1b6504b1fb87bf1674611.tar.bz2 luajit-725da9224d2d2a0bc0a1b6504b1fb87bf1674611.zip | |
Don't modify jit_State and exit counters while in vmevent.
Fixes crash with hot loop in TEXIT callback which cleared J->parent.
| -rw-r--r-- | src/lj_trace.c | 31 |
1 files changed, 16 insertions, 15 deletions
diff --git a/src/lj_trace.c b/src/lj_trace.c index fb36c7ee..b2b35373 100644 --- a/src/lj_trace.c +++ b/src/lj_trace.c | |||
| @@ -540,26 +540,26 @@ void lj_trace_ins(jit_State *J) | |||
| 540 | /* Start recording a new trace. */ | 540 | /* Start recording a new trace. */ |
| 541 | static void trace_new(jit_State *J) | 541 | static void trace_new(jit_State *J) |
| 542 | { | 542 | { |
| 543 | /* Only start a new trace if not inside __gc call or vmevent. */ | 543 | lua_assert(J->state == LJ_TRACE_IDLE); |
| 544 | if (!(J2G(J)->hookmask & (HOOK_GC|HOOK_VMEVENT))) { | 544 | J->state = LJ_TRACE_START; |
| 545 | lua_assert(J->state == LJ_TRACE_IDLE); | 545 | J->fn = curr_func(J->L); |
| 546 | J->state = LJ_TRACE_START; | 546 | J->pt = funcproto(J->fn); |
| 547 | J->fn = curr_func(J->L); | 547 | lj_trace_ins(J); |
| 548 | J->pt = funcproto(J->fn); | ||
| 549 | lj_trace_ins(J); | ||
| 550 | } | ||
| 551 | } | 548 | } |
| 552 | 549 | ||
| 553 | /* A hotcount triggered. Start recording a root trace. */ | 550 | /* A hotcount triggered. Start recording a root trace. */ |
| 554 | void LJ_FASTCALL lj_trace_hot(jit_State *J, const BCIns *pc) | 551 | void LJ_FASTCALL lj_trace_hot(jit_State *J, const BCIns *pc) |
| 555 | { | 552 | { |
| 556 | lua_State *L = J->L; | ||
| 557 | L->top = curr_topL(L); /* Only called from Lua and NRESULTS is not used. */ | ||
| 558 | hotcount_set(J2GG(J), pc, J->param[JIT_P_hotloop]+1); /* Reset hotcount. */ | 553 | hotcount_set(J2GG(J), pc, J->param[JIT_P_hotloop]+1); /* Reset hotcount. */ |
| 559 | J->parent = 0; /* Root trace. */ | 554 | /* Only start a new trace if not inside __gc call or vmevent. */ |
| 560 | J->exitno = 0; | 555 | if (!(J2G(J)->hookmask & (HOOK_GC|HOOK_VMEVENT))) { |
| 561 | J->pc = pc-1; /* The interpreter bytecode PC is offset by 1. */ | 556 | lua_State *L = J->L; |
| 562 | trace_new(J); | 557 | L->top = curr_topL(L); /* Only called from Lua and NRESULTS is not used. */ |
| 558 | J->parent = 0; /* Root trace. */ | ||
| 559 | J->exitno = 0; | ||
| 560 | J->pc = pc-1; /* The interpreter bytecode PC is offset by 1. */ | ||
| 561 | trace_new(J); | ||
| 562 | } | ||
| 563 | } | 563 | } |
| 564 | 564 | ||
| 565 | /* A trace exited. Restore interpreter state and check for hot exits. */ | 565 | /* A trace exited. Restore interpreter state and check for hot exits. */ |
| @@ -593,7 +593,8 @@ void * LJ_FASTCALL lj_trace_exit(jit_State *J, void *exptr) | |||
| 593 | 593 | ||
| 594 | { /* Check for a hot exit. */ | 594 | { /* Check for a hot exit. */ |
| 595 | SnapShot *snap = &J->trace[J->parent]->snap[J->exitno]; | 595 | SnapShot *snap = &J->trace[J->parent]->snap[J->exitno]; |
| 596 | if (snap->count != SNAPCOUNT_DONE && | 596 | if (!(J2G(J)->hookmask & (HOOK_GC|HOOK_VMEVENT)) && |
| 597 | snap->count != SNAPCOUNT_DONE && | ||
| 597 | ++snap->count >= J->param[JIT_P_hotexit]) | 598 | ++snap->count >= J->param[JIT_P_hotexit]) |
| 598 | trace_new(J); /* Start recording a side trace. */ | 599 | trace_new(J); /* Start recording a side trace. */ |
| 599 | } | 600 | } |
