aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Pall <mike>2019-12-08 19:56:56 +0100
committerMike Pall <mike>2019-12-08 19:56:56 +0100
commit92fa45f9eb5d9aa732c6b972a85c26120d7612b4 (patch)
treed77d6d6d99b040b38d9c596528aeea02044a3814 /src
parent9600e4318e17ef73d73c1980008d648c1c98f959 (diff)
downloadluajit-92fa45f9eb5d9aa732c6b972a85c26120d7612b4.tar.gz
luajit-92fa45f9eb5d9aa732c6b972a85c26120d7612b4.tar.bz2
luajit-92fa45f9eb5d9aa732c6b972a85c26120d7612b4.zip
Fix interaction between profiler hooks and finalizers.
Thanks to Julien Desgats.
Diffstat (limited to 'src')
-rw-r--r--src/lj_gc.c2
-rw-r--r--src/lj_obj.h3
-rw-r--r--src/lj_profile.c2
3 files changed, 5 insertions, 2 deletions
diff --git a/src/lj_gc.c b/src/lj_gc.c
index 2aaf5b2c..012d0879 100644
--- a/src/lj_gc.c
+++ b/src/lj_gc.c
@@ -466,6 +466,7 @@ static void gc_call_finalizer(global_State *g, lua_State *L,
466 TValue *top; 466 TValue *top;
467 lj_trace_abort(g); 467 lj_trace_abort(g);
468 hook_entergc(g); /* Disable hooks and new traces during __gc. */ 468 hook_entergc(g); /* Disable hooks and new traces during __gc. */
469 if (LJ_HASPROFILE && (oldh & HOOK_PROFILE)) lj_dispatch_update(g);
469 g->gc.threshold = LJ_MAX_MEM; /* Prevent GC steps. */ 470 g->gc.threshold = LJ_MAX_MEM; /* Prevent GC steps. */
470 top = L->top; 471 top = L->top;
471 copyTV(L, top++, mo); 472 copyTV(L, top++, mo);
@@ -474,6 +475,7 @@ static void gc_call_finalizer(global_State *g, lua_State *L,
474 L->top = top+1; 475 L->top = top+1;
475 errcode = lj_vm_pcall(L, top, 1+0, -1); /* Stack: |mo|o| -> | */ 476 errcode = lj_vm_pcall(L, top, 1+0, -1); /* Stack: |mo|o| -> | */
476 hook_restore(g, oldh); 477 hook_restore(g, oldh);
478 if (LJ_HASPROFILE && (oldh & HOOK_PROFILE)) lj_dispatch_update(g);
477 g->gc.threshold = oldt; /* Restore GC threshold. */ 479 g->gc.threshold = oldt; /* Restore GC threshold. */
478 if (errcode) 480 if (errcode)
479 lj_err_throw(L, errcode); /* Propagate errors. */ 481 lj_err_throw(L, errcode); /* Propagate errors. */
diff --git a/src/lj_obj.h b/src/lj_obj.h
index 72b7ace8..5d5cc49b 100644
--- a/src/lj_obj.h
+++ b/src/lj_obj.h
@@ -638,7 +638,8 @@ typedef struct global_State {
638#define HOOK_PROFILE 0x80 638#define HOOK_PROFILE 0x80
639#define hook_active(g) ((g)->hookmask & HOOK_ACTIVE) 639#define hook_active(g) ((g)->hookmask & HOOK_ACTIVE)
640#define hook_enter(g) ((g)->hookmask |= HOOK_ACTIVE) 640#define hook_enter(g) ((g)->hookmask |= HOOK_ACTIVE)
641#define hook_entergc(g) ((g)->hookmask |= (HOOK_ACTIVE|HOOK_GC)) 641#define hook_entergc(g) \
642 ((g)->hookmask = ((g)->hookmask | (HOOK_ACTIVE|HOOK_GC)) & ~HOOK_PROFILE)
642#define hook_vmevent(g) ((g)->hookmask |= (HOOK_ACTIVE|HOOK_VMEVENT)) 643#define hook_vmevent(g) ((g)->hookmask |= (HOOK_ACTIVE|HOOK_VMEVENT))
643#define hook_leave(g) ((g)->hookmask &= ~HOOK_ACTIVE) 644#define hook_leave(g) ((g)->hookmask &= ~HOOK_ACTIVE)
644#define hook_save(g) ((g)->hookmask & ~HOOK_EVENTMASK) 645#define hook_save(g) ((g)->hookmask & ~HOOK_EVENTMASK)
diff --git a/src/lj_profile.c b/src/lj_profile.c
index 3223697f..e2966e0c 100644
--- a/src/lj_profile.c
+++ b/src/lj_profile.c
@@ -153,7 +153,7 @@ static void profile_trigger(ProfileState *ps)
153 profile_lock(ps); 153 profile_lock(ps);
154 ps->samples++; /* Always increment number of samples. */ 154 ps->samples++; /* Always increment number of samples. */
155 mask = g->hookmask; 155 mask = g->hookmask;
156 if (!(mask & (HOOK_PROFILE|HOOK_VMEVENT))) { /* Set profile hook. */ 156 if (!(mask & (HOOK_PROFILE|HOOK_VMEVENT|HOOK_GC))) { /* Set profile hook. */
157 int st = g->vmstate; 157 int st = g->vmstate;
158 ps->vmstate = st >= 0 ? 'N' : 158 ps->vmstate = st >= 0 ? 'N' :
159 st == ~LJ_VMST_INTERP ? 'I' : 159 st == ~LJ_VMST_INTERP ? 'I' :