diff options
| author | Mike Pall <mike> | 2013-09-08 02:53:23 +0200 |
|---|---|---|
| committer | Mike Pall <mike> | 2013-09-08 02:53:23 +0200 |
| commit | d1194a82eb24afa1c749a0a8080b67d168f9f201 (patch) | |
| tree | fb3bebc2cbf5032a49653dd6a0bd31c420dd8083 /src | |
| parent | d3d30d389b504495d054d71bdee0fe2677d4b44c (diff) | |
| download | luajit-d1194a82eb24afa1c749a0a8080b67d168f9f201.tar.gz luajit-d1194a82eb24afa1c749a0a8080b67d168f9f201.tar.bz2 luajit-d1194a82eb24afa1c749a0a8080b67d168f9f201.zip | |
Low-overhead profiler, part 4: JIT compiler support.
Diffstat (limited to 'src')
| -rw-r--r-- | src/Makefile.dep | 8 | ||||
| -rw-r--r-- | src/lj_asm.c | 1 | ||||
| -rw-r--r-- | src/lj_asm_arm.h | 10 | ||||
| -rw-r--r-- | src/lj_asm_mips.h | 11 | ||||
| -rw-r--r-- | src/lj_asm_ppc.h | 11 | ||||
| -rw-r--r-- | src/lj_asm_x86.h | 10 | ||||
| -rw-r--r-- | src/lj_ir.h | 1 | ||||
| -rw-r--r-- | src/lj_jit.h | 6 | ||||
| -rw-r--r-- | src/lj_opt_fold.c | 11 | ||||
| -rw-r--r-- | src/lj_profile.c | 17 | ||||
| -rw-r--r-- | src/lj_record.c | 60 | ||||
| -rw-r--r-- | src/lj_trace.c | 17 |
12 files changed, 151 insertions, 12 deletions
diff --git a/src/Makefile.dep b/src/Makefile.dep index 7991bd16..3f080374 100644 --- a/src/Makefile.dep +++ b/src/Makefile.dep | |||
| @@ -170,12 +170,12 @@ lj_parse.o: lj_parse.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ | |||
| 170 | lj_vm.h lj_vmevent.h | 170 | lj_vm.h lj_vmevent.h |
| 171 | lj_profile.o: lj_profile.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ | 171 | lj_profile.o: lj_profile.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ |
| 172 | lj_buf.h lj_gc.h lj_str.h lj_frame.h lj_bc.h lj_debug.h lj_dispatch.h \ | 172 | lj_buf.h lj_gc.h lj_str.h lj_frame.h lj_bc.h lj_debug.h lj_dispatch.h \ |
| 173 | lj_jit.h lj_ir.h lj_profile.h luajit.h | 173 | lj_jit.h lj_ir.h lj_trace.h lj_traceerr.h lj_profile.h luajit.h |
| 174 | lj_record.o: lj_record.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ | 174 | lj_record.o: lj_record.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ |
| 175 | lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_meta.h lj_frame.h lj_bc.h \ | 175 | lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_meta.h lj_frame.h lj_bc.h \ |
| 176 | lj_ctype.h lj_gc.h lj_ff.h lj_ffdef.h lj_ir.h lj_jit.h lj_ircall.h \ | 176 | lj_ctype.h lj_gc.h lj_ff.h lj_ffdef.h lj_debug.h lj_ir.h lj_jit.h \ |
| 177 | lj_iropt.h lj_trace.h lj_dispatch.h lj_traceerr.h lj_record.h \ | 177 | lj_ircall.h lj_iropt.h lj_trace.h lj_dispatch.h lj_traceerr.h \ |
| 178 | lj_ffrecord.h lj_snap.h lj_vm.h | 178 | lj_record.h lj_ffrecord.h lj_snap.h lj_vm.h |
| 179 | lj_snap.o: lj_snap.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \ | 179 | lj_snap.o: lj_snap.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \ |
| 180 | lj_tab.h lj_state.h lj_frame.h lj_bc.h lj_ir.h lj_jit.h lj_iropt.h \ | 180 | lj_tab.h lj_state.h lj_frame.h lj_bc.h lj_ir.h lj_jit.h lj_iropt.h \ |
| 181 | lj_trace.h lj_dispatch.h lj_traceerr.h lj_snap.h lj_target.h \ | 181 | lj_trace.h lj_dispatch.h lj_traceerr.h lj_snap.h lj_target.h \ |
diff --git a/src/lj_asm.c b/src/lj_asm.c index ee1cc5b5..2bf273e1 100644 --- a/src/lj_asm.c +++ b/src/lj_asm.c | |||
| @@ -1565,6 +1565,7 @@ static void asm_ir(ASMState *as, IRIns *ir) | |||
| 1565 | case IR_PHI: asm_phi(as, ir); break; | 1565 | case IR_PHI: asm_phi(as, ir); break; |
| 1566 | case IR_HIOP: asm_hiop(as, ir); break; | 1566 | case IR_HIOP: asm_hiop(as, ir); break; |
| 1567 | case IR_GCSTEP: asm_gcstep(as, ir); break; | 1567 | case IR_GCSTEP: asm_gcstep(as, ir); break; |
| 1568 | case IR_PROF: asm_prof(as, ir); break; | ||
| 1568 | 1569 | ||
| 1569 | /* Guarded assertions. */ | 1570 | /* Guarded assertions. */ |
| 1570 | case IR_LT: case IR_GE: case IR_LE: case IR_GT: | 1571 | case IR_LT: case IR_GE: case IR_LE: case IR_GT: |
diff --git a/src/lj_asm_arm.h b/src/lj_asm_arm.h index 497a5692..d736859c 100644 --- a/src/lj_asm_arm.h +++ b/src/lj_asm_arm.h | |||
| @@ -1915,6 +1915,16 @@ static void asm_hiop(ASMState *as, IRIns *ir) | |||
| 1915 | #endif | 1915 | #endif |
| 1916 | } | 1916 | } |
| 1917 | 1917 | ||
| 1918 | /* -- Profiling ----------------------------------------------------------- */ | ||
| 1919 | |||
| 1920 | static void asm_prof(ASMState *as, IRIns *ir) | ||
| 1921 | { | ||
| 1922 | UNUSED(ir); | ||
| 1923 | asm_guardcc(as, CC_NE); | ||
| 1924 | emit_n(as, ARMI_TST|ARMI_K12|HOOK_PROFILE, RID_TMP); | ||
| 1925 | emit_lsptr(as, ARMI_LDRB, RID_TMP, (void *)&J2G(as->J)->hookmask); | ||
| 1926 | } | ||
| 1927 | |||
| 1918 | /* -- Stack handling ------------------------------------------------------ */ | 1928 | /* -- Stack handling ------------------------------------------------------ */ |
| 1919 | 1929 | ||
| 1920 | /* Check Lua stack size for overflow. Use exit handler as fallback. */ | 1930 | /* Check Lua stack size for overflow. Use exit handler as fallback. */ |
diff --git a/src/lj_asm_mips.h b/src/lj_asm_mips.h index 74eff10b..365538bb 100644 --- a/src/lj_asm_mips.h +++ b/src/lj_asm_mips.h | |||
| @@ -1562,6 +1562,17 @@ static void asm_hiop(ASMState *as, IRIns *ir) | |||
| 1562 | #endif | 1562 | #endif |
| 1563 | } | 1563 | } |
| 1564 | 1564 | ||
| 1565 | /* -- Profiling ----------------------------------------------------------- */ | ||
| 1566 | |||
| 1567 | static void asm_prof(ASMState *as, IRIns *ir) | ||
| 1568 | { | ||
| 1569 | UNUSED(ir); | ||
| 1570 | asm_guard(as, MIPSI_BNE, RID_TMP, RID_ZERO); | ||
| 1571 | emit_tsi(as, MIPSI_ANDI, RID_TMP, RID_TMP, HOOK_PROFILE); | ||
| 1572 | emit_lsglptr(as, MIPSI_LBU, RID_TMP, | ||
| 1573 | (int32_t)offsetof(global_State, hookmask)); | ||
| 1574 | } | ||
| 1575 | |||
| 1565 | /* -- Stack handling ------------------------------------------------------ */ | 1576 | /* -- Stack handling ------------------------------------------------------ */ |
| 1566 | 1577 | ||
| 1567 | /* Check Lua stack size for overflow. Use exit handler as fallback. */ | 1578 | /* Check Lua stack size for overflow. Use exit handler as fallback. */ |
diff --git a/src/lj_asm_ppc.h b/src/lj_asm_ppc.h index 652dcca0..e0dcaed0 100644 --- a/src/lj_asm_ppc.h +++ b/src/lj_asm_ppc.h | |||
| @@ -1738,6 +1738,17 @@ static void asm_hiop(ASMState *as, IRIns *ir) | |||
| 1738 | #endif | 1738 | #endif |
| 1739 | } | 1739 | } |
| 1740 | 1740 | ||
| 1741 | /* -- Profiling ----------------------------------------------------------- */ | ||
| 1742 | |||
| 1743 | static void asm_prof(ASMState *as, IRIns *ir) | ||
| 1744 | { | ||
| 1745 | UNUSED(ir); | ||
| 1746 | asm_guardcc(as, CC_NE); | ||
| 1747 | emit_asi(as, PPCI_ANDIDOT, RID_TMP, RID_TMP, HOOK_PROFILE); | ||
| 1748 | emit_lsglptr(as, PPCI_LBZ, RID_TMP, | ||
| 1749 | (int32_t)offsetof(global_State, hookmask)); | ||
| 1750 | } | ||
| 1751 | |||
| 1741 | /* -- Stack handling ------------------------------------------------------ */ | 1752 | /* -- Stack handling ------------------------------------------------------ */ |
| 1742 | 1753 | ||
| 1743 | /* Check Lua stack size for overflow. Use exit handler as fallback. */ | 1754 | /* Check Lua stack size for overflow. Use exit handler as fallback. */ |
diff --git a/src/lj_asm_x86.h b/src/lj_asm_x86.h index 82517600..8b72c5e8 100644 --- a/src/lj_asm_x86.h +++ b/src/lj_asm_x86.h | |||
| @@ -2348,6 +2348,16 @@ static void asm_hiop(ASMState *as, IRIns *ir) | |||
| 2348 | #endif | 2348 | #endif |
| 2349 | } | 2349 | } |
| 2350 | 2350 | ||
| 2351 | /* -- Profiling ----------------------------------------------------------- */ | ||
| 2352 | |||
| 2353 | static void asm_prof(ASMState *as, IRIns *ir) | ||
| 2354 | { | ||
| 2355 | UNUSED(ir); | ||
| 2356 | asm_guardcc(as, CC_NE); | ||
| 2357 | emit_i8(as, HOOK_PROFILE); | ||
| 2358 | emit_rma(as, XO_GROUP3b, XOg_TEST, &J2G(as->J)->hookmask); | ||
| 2359 | } | ||
| 2360 | |||
| 2351 | /* -- Stack handling ------------------------------------------------------ */ | 2361 | /* -- Stack handling ------------------------------------------------------ */ |
| 2352 | 2362 | ||
| 2353 | /* Check Lua stack size for overflow. Use exit handler as fallback. */ | 2363 | /* Check Lua stack size for overflow. Use exit handler as fallback. */ |
diff --git a/src/lj_ir.h b/src/lj_ir.h index 841153d8..54bbbdda 100644 --- a/src/lj_ir.h +++ b/src/lj_ir.h | |||
| @@ -40,6 +40,7 @@ | |||
| 40 | _(USE, S , ref, ___) \ | 40 | _(USE, S , ref, ___) \ |
| 41 | _(PHI, S , ref, ref) \ | 41 | _(PHI, S , ref, ref) \ |
| 42 | _(RENAME, S , ref, lit) \ | 42 | _(RENAME, S , ref, lit) \ |
| 43 | _(PROF, S , ___, ___) \ | ||
| 43 | \ | 44 | \ |
| 44 | /* Constants. */ \ | 45 | /* Constants. */ \ |
| 45 | _(KPRI, N , ___, ___) \ | 46 | _(KPRI, N , ___, ___) \ |
diff --git a/src/lj_jit.h b/src/lj_jit.h index 2683b462..cfb04aa7 100644 --- a/src/lj_jit.h +++ b/src/lj_jit.h | |||
| @@ -396,6 +396,12 @@ typedef struct jit_State { | |||
| 396 | size_t szallmcarea; /* Total size of all allocated mcode areas. */ | 396 | size_t szallmcarea; /* Total size of all allocated mcode areas. */ |
| 397 | 397 | ||
| 398 | TValue errinfo; /* Additional info element for trace errors. */ | 398 | TValue errinfo; /* Additional info element for trace errors. */ |
| 399 | |||
| 400 | #if LJ_HASPROFILE | ||
| 401 | GCproto *prev_pt; /* Previous prototype. */ | ||
| 402 | BCLine prev_line; /* Previous line. */ | ||
| 403 | int prof_mode; /* Profiling mode: 0, 'f', 'l'. */ | ||
| 404 | #endif | ||
| 399 | } | 405 | } |
| 400 | #if LJ_TARGET_ARM | 406 | #if LJ_TARGET_ARM |
| 401 | LJ_ALIGN(16) /* For DISPATCH-relative addresses in assembler part. */ | 407 | LJ_ALIGN(16) /* For DISPATCH-relative addresses in assembler part. */ |
diff --git a/src/lj_opt_fold.c b/src/lj_opt_fold.c index 1d37a7fd..84c5dc00 100644 --- a/src/lj_opt_fold.c +++ b/src/lj_opt_fold.c | |||
| @@ -2285,6 +2285,17 @@ LJFOLDF(barrier_tnew_tdup) | |||
| 2285 | return DROPFOLD; | 2285 | return DROPFOLD; |
| 2286 | } | 2286 | } |
| 2287 | 2287 | ||
| 2288 | /* -- Profiling ----------------------------------------------------------- */ | ||
| 2289 | |||
| 2290 | LJFOLD(PROF any any) | ||
| 2291 | LJFOLDF(prof) | ||
| 2292 | { | ||
| 2293 | IRRef ref = J->chain[IR_PROF]; | ||
| 2294 | if (ref+1 == J->cur.nins) /* Drop neighbouring IR_PROF. */ | ||
| 2295 | return ref; | ||
| 2296 | return EMITFOLD; | ||
| 2297 | } | ||
| 2298 | |||
| 2288 | /* -- Stores and allocations ---------------------------------------------- */ | 2299 | /* -- Stores and allocations ---------------------------------------------- */ |
| 2289 | 2300 | ||
| 2290 | /* Stores and allocations cannot be folded or passed on to CSE in general. | 2301 | /* Stores and allocations cannot be folded or passed on to CSE in general. |
diff --git a/src/lj_profile.c b/src/lj_profile.c index 0baad06c..a58aefc8 100644 --- a/src/lj_profile.c +++ b/src/lj_profile.c | |||
| @@ -14,6 +14,10 @@ | |||
| 14 | #include "lj_frame.h" | 14 | #include "lj_frame.h" |
| 15 | #include "lj_debug.h" | 15 | #include "lj_debug.h" |
| 16 | #include "lj_dispatch.h" | 16 | #include "lj_dispatch.h" |
| 17 | #if LJ_HASJIT | ||
| 18 | #include "lj_jit.h" | ||
| 19 | #include "lj_trace.h" | ||
| 20 | #endif | ||
| 17 | #include "lj_profile.h" | 21 | #include "lj_profile.h" |
| 18 | 22 | ||
| 19 | #include "luajit.h" | 23 | #include "luajit.h" |
| @@ -218,13 +222,20 @@ LUA_API void luaJIT_profile_start(lua_State *L, const char *mode, | |||
| 218 | ProfileState *ps = &profile_state; | 222 | ProfileState *ps = &profile_state; |
| 219 | int interval = LJ_PROFILE_INTERVAL_DEFAULT; | 223 | int interval = LJ_PROFILE_INTERVAL_DEFAULT; |
| 220 | while (*mode) { | 224 | while (*mode) { |
| 221 | switch (*mode++) { | 225 | int m = *mode++; |
| 226 | switch (m) { | ||
| 222 | case 'i': | 227 | case 'i': |
| 223 | interval = 0; | 228 | interval = 0; |
| 224 | while (*mode >= '0' && *mode <= '9') | 229 | while (*mode >= '0' && *mode <= '9') |
| 225 | interval = interval * 10 + (*mode++ - '0'); | 230 | interval = interval * 10 + (*mode++ - '0'); |
| 226 | if (interval <= 0) interval = 1; | 231 | if (interval <= 0) interval = 1; |
| 227 | break; | 232 | break; |
| 233 | #if LJ_HASJIT | ||
| 234 | case 'l': case 'f': | ||
| 235 | L2J(L)->prof_mode = m; | ||
| 236 | lj_trace_flushall(L); | ||
| 237 | break; | ||
| 238 | #endif | ||
| 228 | default: /* Ignore unknown mode chars. */ | 239 | default: /* Ignore unknown mode chars. */ |
| 229 | break; | 240 | break; |
| 230 | } | 241 | } |
| @@ -251,6 +262,10 @@ LUA_API void luaJIT_profile_stop(lua_State *L) | |||
| 251 | profile_timer_stop(ps); | 262 | profile_timer_stop(ps); |
| 252 | g->hookmask &= ~HOOK_PROFILE; | 263 | g->hookmask &= ~HOOK_PROFILE; |
| 253 | lj_dispatch_update(g); | 264 | lj_dispatch_update(g); |
| 265 | #if LJ_HASJIT | ||
| 266 | G2J(g)->prof_mode = 0; | ||
| 267 | lj_trace_flushall(L); | ||
| 268 | #endif | ||
| 254 | lj_buf_free(g, &ps->sb); | 269 | lj_buf_free(g, &ps->sb); |
| 255 | setmref(ps->sb.b, NULL); | 270 | setmref(ps->sb.b, NULL); |
| 256 | setmref(ps->sb.e, NULL); | 271 | setmref(ps->sb.e, NULL); |
diff --git a/src/lj_record.c b/src/lj_record.c index bdf0212a..3dcb0a85 100644 --- a/src/lj_record.c +++ b/src/lj_record.c | |||
| @@ -20,6 +20,9 @@ | |||
| 20 | #endif | 20 | #endif |
| 21 | #include "lj_bc.h" | 21 | #include "lj_bc.h" |
| 22 | #include "lj_ff.h" | 22 | #include "lj_ff.h" |
| 23 | #if LJ_HASPROFILE | ||
| 24 | #include "lj_debug.h" | ||
| 25 | #endif | ||
| 23 | #include "lj_ir.h" | 26 | #include "lj_ir.h" |
| 24 | #include "lj_jit.h" | 27 | #include "lj_jit.h" |
| 25 | #include "lj_ircall.h" | 28 | #include "lj_ircall.h" |
| @@ -579,6 +582,52 @@ static void rec_loop_jit(jit_State *J, TraceNo lnk, LoopEvent ev) | |||
| 579 | } /* Side trace continues across a loop that's left or not entered. */ | 582 | } /* Side trace continues across a loop that's left or not entered. */ |
| 580 | } | 583 | } |
| 581 | 584 | ||
| 585 | /* -- Record profiler hook checks ----------------------------------------- */ | ||
| 586 | |||
| 587 | #if LJ_HASPROFILE | ||
| 588 | |||
| 589 | /* Need to insert profiler hook check? */ | ||
| 590 | static int rec_profile_need(jit_State *J, GCproto *pt, const BCIns *pc) | ||
| 591 | { | ||
| 592 | GCproto *ppt; | ||
| 593 | lua_assert(J->prof_mode == 'f' || J->prof_mode == 'l'); | ||
| 594 | if (!pt) | ||
| 595 | return 0; | ||
| 596 | ppt = J->prev_pt; | ||
| 597 | J->prev_pt = pt; | ||
| 598 | if (pt != ppt && ppt) { | ||
| 599 | J->prev_line = -1; | ||
| 600 | return 1; | ||
| 601 | } | ||
| 602 | if (J->prof_mode == 'l') { | ||
| 603 | BCLine line = lj_debug_line(pt, proto_bcpos(pt, pc)); | ||
| 604 | BCLine pline = J->prev_line; | ||
| 605 | J->prev_line = line; | ||
| 606 | if (pline != line) | ||
| 607 | return 1; | ||
| 608 | } | ||
| 609 | return 0; | ||
| 610 | } | ||
| 611 | |||
| 612 | static void rec_profile_ins(jit_State *J, const BCIns *pc) | ||
| 613 | { | ||
| 614 | if (J->prof_mode && rec_profile_need(J, J->pt, pc)) { | ||
| 615 | emitir(IRTG(IR_PROF, IRT_NIL), 0, 0); | ||
| 616 | lj_snap_add(J); | ||
| 617 | } | ||
| 618 | } | ||
| 619 | |||
| 620 | static void rec_profile_ret(jit_State *J) | ||
| 621 | { | ||
| 622 | if (J->prof_mode == 'f') { | ||
| 623 | emitir(IRTG(IR_PROF, IRT_NIL), 0, 0); | ||
| 624 | J->prev_pt = NULL; | ||
| 625 | lj_snap_add(J); | ||
| 626 | } | ||
| 627 | } | ||
| 628 | |||
| 629 | #endif | ||
| 630 | |||
| 582 | /* -- Record calls and returns -------------------------------------------- */ | 631 | /* -- Record calls and returns -------------------------------------------- */ |
| 583 | 632 | ||
| 584 | /* Specialize to the runtime value of the called function or its prototype. */ | 633 | /* Specialize to the runtime value of the called function or its prototype. */ |
| @@ -1770,6 +1819,10 @@ void lj_record_ins(jit_State *J) | |||
| 1770 | rec_check_ir(J); | 1819 | rec_check_ir(J); |
| 1771 | #endif | 1820 | #endif |
| 1772 | 1821 | ||
| 1822 | #if LJ_HASPROFILE | ||
| 1823 | rec_profile_ins(J, pc); | ||
| 1824 | #endif | ||
| 1825 | |||
| 1773 | /* Keep a copy of the runtime values of var/num/str operands. */ | 1826 | /* Keep a copy of the runtime values of var/num/str operands. */ |
| 1774 | #define rav (&ix.valv) | 1827 | #define rav (&ix.valv) |
| 1775 | #define rbv (&ix.tabv) | 1828 | #define rbv (&ix.tabv) |
| @@ -2074,6 +2127,9 @@ void lj_record_ins(jit_State *J) | |||
| 2074 | rc = (BCReg)(J->L->top - J->L->base) - ra + 1; | 2127 | rc = (BCReg)(J->L->top - J->L->base) - ra + 1; |
| 2075 | /* fallthrough */ | 2128 | /* fallthrough */ |
| 2076 | case BC_RET: case BC_RET0: case BC_RET1: | 2129 | case BC_RET: case BC_RET0: case BC_RET1: |
| 2130 | #if LJ_HASPROFILE | ||
| 2131 | rec_profile_ret(J); | ||
| 2132 | #endif | ||
| 2077 | lj_record_ret(J, ra, (ptrdiff_t)rc-1); | 2133 | lj_record_ret(J, ra, (ptrdiff_t)rc-1); |
| 2078 | break; | 2134 | break; |
| 2079 | 2135 | ||
| @@ -2303,6 +2359,10 @@ void lj_record_setup(jit_State *J) | |||
| 2303 | if (1 + J->pt->framesize >= LJ_MAX_JSLOTS) | 2359 | if (1 + J->pt->framesize >= LJ_MAX_JSLOTS) |
| 2304 | lj_trace_err(J, LJ_TRERR_STACKOV); | 2360 | lj_trace_err(J, LJ_TRERR_STACKOV); |
| 2305 | } | 2361 | } |
| 2362 | #if LJ_HASPROFILE | ||
| 2363 | J->prev_pt = NULL; | ||
| 2364 | J->prev_line = -1; | ||
| 2365 | #endif | ||
| 2306 | #ifdef LUAJIT_ENABLE_CHECKHOOK | 2366 | #ifdef LUAJIT_ENABLE_CHECKHOOK |
| 2307 | /* Regularly check for instruction/line hooks from compiled code and | 2367 | /* Regularly check for instruction/line hooks from compiled code and |
| 2308 | ** exit to the interpreter if the hooks are set. | 2368 | ** exit to the interpreter if the hooks are set. |
diff --git a/src/lj_trace.c b/src/lj_trace.c index c70fc247..2b8d931f 100644 --- a/src/lj_trace.c +++ b/src/lj_trace.c | |||
| @@ -766,17 +766,20 @@ int LJ_FASTCALL lj_trace_exit(jit_State *J, void *exptr) | |||
| 766 | if (errcode) | 766 | if (errcode) |
| 767 | return -errcode; /* Return negated error code. */ | 767 | return -errcode; /* Return negated error code. */ |
| 768 | 768 | ||
| 769 | lj_vmevent_send(L, TEXIT, | 769 | if (!(LJ_HASPROFILE && (G(L)->hookmask & HOOK_PROFILE))) |
| 770 | lj_state_checkstack(L, 4+RID_NUM_GPR+RID_NUM_FPR+LUA_MINSTACK); | 770 | lj_vmevent_send(L, TEXIT, |
| 771 | setintV(L->top++, J->parent); | 771 | lj_state_checkstack(L, 4+RID_NUM_GPR+RID_NUM_FPR+LUA_MINSTACK); |
| 772 | setintV(L->top++, J->exitno); | 772 | setintV(L->top++, J->parent); |
| 773 | trace_exit_regs(L, ex); | 773 | setintV(L->top++, J->exitno); |
| 774 | ); | 774 | trace_exit_regs(L, ex); |
| 775 | ); | ||
| 775 | 776 | ||
| 776 | pc = exd.pc; | 777 | pc = exd.pc; |
| 777 | cf = cframe_raw(L->cframe); | 778 | cf = cframe_raw(L->cframe); |
| 778 | setcframe_pc(cf, pc); | 779 | setcframe_pc(cf, pc); |
| 779 | if (G(L)->gc.state == GCSatomic || G(L)->gc.state == GCSfinalize) { | 780 | if (LJ_HASPROFILE && (G(L)->hookmask & HOOK_PROFILE)) { |
| 781 | /* Just exit to interpreter. */ | ||
| 782 | } else if (G(L)->gc.state == GCSatomic || G(L)->gc.state == GCSfinalize) { | ||
| 780 | if (!(G(L)->hookmask & HOOK_GC)) | 783 | if (!(G(L)->hookmask & HOOK_GC)) |
| 781 | lj_gc_step(L); /* Exited because of GC: drive GC forward. */ | 784 | lj_gc_step(L); /* Exited because of GC: drive GC forward. */ |
| 782 | } else { | 785 | } else { |
