summaryrefslogtreecommitdiff
path: root/libguile/vm.c
diff options
context:
space:
mode:
authorAndy Wingo <wingo@pobox.com>2018-09-14 15:11:13 +0200
committerAndy Wingo <wingo@pobox.com>2018-09-14 15:16:33 +0200
commit09b8f8ec06f0f7fbed66255a3085a100e8c3646a (patch)
treecb23bf185b1fa05d655780a9a43006f5357cac8d /libguile/vm.c
parent12b125f2ad6defe77de29cab6f54f367e07550c2 (diff)
downloadguile-09b8f8ec06f0f7fbed66255a3085a100e8c3646a.tar.gz
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.
Diffstat (limited to 'libguile/vm.c')
-rw-r--r--libguile/vm.c23
1 files changed, 20 insertions, 3 deletions
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