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 /src | |
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.
Diffstat (limited to 'src')
-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 | } |