1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-06-14 15:40:19 +02:00

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.
This commit is contained in:
Andy Wingo 2018-09-14 15:11:13 +02:00
parent 12b125f2ad
commit 09b8f8ec06
2 changed files with 75 additions and 51 deletions

View file

@ -458,35 +458,38 @@ VM_NAME (scm_thread *thread)
*/ */
VM_DEFINE_OP (5, instrument_entry, "instrument-entry", OP2 (X32, N32)) VM_DEFINE_OP (5, instrument_entry, "instrument-entry", OP2 (X32, N32))
{ {
int32_t data_offset = ip[1]; if (!VP->disable_mcode)
struct scm_jit_function_data *data;
data = (struct scm_jit_function_data *) (ip + data_offset);
if (data->mcode)
{ {
SYNC_IP (); struct scm_jit_function_data *data;
scm_jit_enter_mcode (thread, data->mcode);
CACHE_REGISTER ();
NEXT (0);
}
if (data->counter >= scm_jit_counter_threshold) int32_t data_offset = ip[1];
{ data = (struct scm_jit_function_data *) (ip + data_offset);
const uint8_t *mcode;
SYNC_IP (); if (data->mcode)
mcode = scm_jit_compute_mcode (thread, data);
if (mcode)
{ {
scm_jit_enter_mcode (thread, mcode); SYNC_IP ();
scm_jit_enter_mcode (thread, data->mcode);
CACHE_REGISTER (); CACHE_REGISTER ();
NEXT (0); NEXT (0);
} }
if (data->counter >= scm_jit_counter_threshold)
{
const uint8_t *mcode;
SYNC_IP ();
mcode = scm_jit_compute_mcode (thread, data);
if (mcode)
{
scm_jit_enter_mcode (thread, mcode);
CACHE_REGISTER ();
NEXT (0);
}
}
else
data->counter += SCM_JIT_COUNTER_ENTRY_INCREMENT;
} }
else
data->counter += SCM_JIT_COUNTER_ENTRY_INCREMENT;
APPLY_HOOK (); APPLY_HOOK ();
@ -572,18 +575,19 @@ VM_NAME (scm_thread *thread)
old_fp = VP->fp; old_fp = VP->fp;
VP->fp = SCM_FRAME_DYNAMIC_LINK (old_fp); VP->fp = SCM_FRAME_DYNAMIC_LINK (old_fp);
mcode = SCM_FRAME_MACHINE_RETURN_ADDRESS (old_fp); if (!VP->disable_mcode)
if (mcode)
{ {
scm_jit_enter_mcode (thread, mcode); mcode = SCM_FRAME_MACHINE_RETURN_ADDRESS (old_fp);
CACHE_REGISTER (); if (mcode)
NEXT (0); {
} scm_jit_enter_mcode (thread, mcode);
else CACHE_REGISTER ();
{ NEXT (0);
ip = SCM_FRAME_VIRTUAL_RETURN_ADDRESS (old_fp); }
NEXT (0);
} }
ip = SCM_FRAME_VIRTUAL_RETURN_ADDRESS (old_fp);
NEXT (0);
} }
@ -695,7 +699,7 @@ VM_NAME (scm_thread *thread)
SYNC_IP (); SYNC_IP ();
mcode = CALL_INTRINSIC (compose_continuation, (thread, vmcont)); mcode = CALL_INTRINSIC (compose_continuation, (thread, vmcont));
if (mcode) if (mcode && !VP->disable_mcode)
{ {
scm_jit_enter_mcode (thread, mcode); scm_jit_enter_mcode (thread, mcode);
CACHE_REGISTER (); CACHE_REGISTER ();
@ -717,27 +721,30 @@ VM_NAME (scm_thread *thread)
*/ */
VM_DEFINE_OP (14, instrument_loop, "instrument-loop", OP2 (X32, N32)) VM_DEFINE_OP (14, instrument_loop, "instrument-loop", OP2 (X32, N32))
{ {
int32_t data_offset = ip[1]; if (!VP->disable_mcode)
struct scm_jit_function_data *data;
data = (struct scm_jit_function_data *) (ip + data_offset);
if (data->counter >= scm_jit_counter_threshold)
{ {
const uint8_t *mcode; int32_t data_offset = ip[1];
struct scm_jit_function_data *data;
SYNC_IP (); data = (struct scm_jit_function_data *) (ip + data_offset);
mcode = scm_jit_compute_mcode (thread, data);
if (mcode) if (data->counter >= scm_jit_counter_threshold)
{ {
scm_jit_enter_mcode (thread, mcode); const uint8_t *mcode;
CACHE_REGISTER ();
NEXT (0); SYNC_IP ();
mcode = scm_jit_compute_mcode (thread, data);
if (mcode)
{
scm_jit_enter_mcode (thread, mcode);
CACHE_REGISTER ();
NEXT (0);
}
} }
else
data->counter += SCM_JIT_COUNTER_LOOP_INCREMENT;
} }
else
data->counter += SCM_JIT_COUNTER_LOOP_INCREMENT;
NEXT (2); NEXT (2);
} }
@ -782,7 +789,7 @@ VM_NAME (scm_thread *thread)
ABORT_HOOK (); ABORT_HOOK ();
if (mcode) if (mcode && !VP->disable_mcode)
scm_jit_enter_mcode (thread, mcode); scm_jit_enter_mcode (thread, mcode);
CACHE_REGISTER (); CACHE_REGISTER ();

View file

@ -198,6 +198,18 @@ scm_i_capture_current_stack (void)
0); 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) \ #define FOR_EACH_HOOK(M) \
M(apply) \ M(apply) \
M(return) \ M(return) \
@ -219,12 +231,17 @@ vm_hook_compute_enabled (scm_thread *thread, SCM hook, uint8_t *enabled)
static void static void
vm_recompute_disable_mcode (scm_thread *thread) vm_recompute_disable_mcode (scm_thread *thread)
{ {
uint8_t was_disabled = thread->vm.disable_mcode;
thread->vm.disable_mcode = 0; thread->vm.disable_mcode = 0;
#define DISABLE_MCODE_IF_HOOK_ENABLED(h) \ #define DISABLE_MCODE_IF_HOOK_ENABLED(h) \
if (thread->vm.h##_hook_enabled) \ if (thread->vm.h##_hook_enabled) \
thread->vm.disable_mcode = 1; 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 #undef DISABLE_MCODE_IF_HOOK_ENABLED
if (thread->vm.disable_mcode && !was_disabled)
vm_clear_mcode_return_addresses (thread);
} }
static int static int
@ -1499,9 +1516,9 @@ scm_call_n (SCM proc, SCM *argv, size_t nargs)
uint8_t *mcode = vp->mra_after_abort; uint8_t *mcode = vp->mra_after_abort;
scm_gc_after_nonlocal_exit (); scm_gc_after_nonlocal_exit ();
/* Non-local return. */ /* Non-local return. */
if (vp->trace_level) if (vp->abort_hook_enabled)
invoke_abort_hook (thread); invoke_abort_hook (thread);
if (mcode) if (mcode && !vp->disable_mcode)
scm_jit_enter_mcode (thread, mcode); scm_jit_enter_mcode (thread, mcode);
} }
else else