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 | |
parent | d3d30d389b504495d054d71bdee0fe2677d4b44c (diff) | |
download | luajit-d1194a82eb24afa1c749a0a8080b67d168f9f201.tar.gz luajit-d1194a82eb24afa1c749a0a8080b67d168f9f201.tar.bz2 luajit-d1194a82eb24afa1c749a0a8080b67d168f9f201.zip |
Low-overhead profiler, part 4: JIT compiler support.
-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 { |