From 09b8f8ec06f0f7fbed66255a3085a100e8c3646a Mon Sep 17 00:00:00 2001 From: Andy Wingo Date: Fri, 14 Sep 2018 15:11:13 +0200 Subject: Deoptimize to VM when hooks are enabled * libguile/vm.c (vm_clear_mcode_return_addresses): New helper. (vm_recompute_disable_mcode): Force a thread to deoptimize if hooks become enabled. (scm_call_n): Don't enter mcode if it's disabled. Also check the right flag for when to run the abort hook (the abort_hook_enabled flag). * libguile/vm-engine.c (instrument-entry, instrument-loop) (return-values, abort, compose-continuation): Don't enter mcode if mcode is disabled for this thread. --- libguile/vm.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) (limited to 'libguile/vm.c') diff --git a/libguile/vm.c b/libguile/vm.c index 326b20448..a8ebabb0f 100644 --- a/libguile/vm.c +++ b/libguile/vm.c @@ -198,6 +198,18 @@ scm_i_capture_current_stack (void) 0); } +/* Call to force a thread to go back to the interpreter, for example + when single-stepping is enabled. */ +static void +vm_clear_mcode_return_addresses (scm_thread *thread) +{ + union scm_vm_stack_element *fp; + struct scm_vm *vp = &thread->vm; + + for (fp = vp->fp; fp < vp->stack_top; fp = SCM_FRAME_DYNAMIC_LINK (fp)) + SCM_FRAME_SET_MACHINE_RETURN_ADDRESS (fp, NULL); +} + #define FOR_EACH_HOOK(M) \ M(apply) \ M(return) \ @@ -219,12 +231,17 @@ vm_hook_compute_enabled (scm_thread *thread, SCM hook, uint8_t *enabled) static void vm_recompute_disable_mcode (scm_thread *thread) { + uint8_t was_disabled = thread->vm.disable_mcode; thread->vm.disable_mcode = 0; + #define DISABLE_MCODE_IF_HOOK_ENABLED(h) \ if (thread->vm.h##_hook_enabled) \ thread->vm.disable_mcode = 1; - FOR_EACH_HOOK (DISABLE_MCODE_IF_HOOK_ENABLED) + FOR_EACH_HOOK (DISABLE_MCODE_IF_HOOK_ENABLED); #undef DISABLE_MCODE_IF_HOOK_ENABLED + + if (thread->vm.disable_mcode && !was_disabled) + vm_clear_mcode_return_addresses (thread); } static int @@ -1499,9 +1516,9 @@ scm_call_n (SCM proc, SCM *argv, size_t nargs) uint8_t *mcode = vp->mra_after_abort; scm_gc_after_nonlocal_exit (); /* Non-local return. */ - if (vp->trace_level) + if (vp->abort_hook_enabled) invoke_abort_hook (thread); - if (mcode) + if (mcode && !vp->disable_mcode) scm_jit_enter_mcode (thread, mcode); } else -- cgit v1.2.1