* libguile/__scm.h (SCM_ASYNC_TICK): Add some branch prediction.
(SCM_ASYNC_TICK_WITH_CODE): New helper for when BUILDING_LIBGUILE,
runs code only if we're going to call async_click().
* libguile/vm-engine.h (VM_HANDLE_INTERRUPTS): New helper, uses
SCM_ASYNC_TICK_WITH_CODE to only save regs if we'll handle an
interrupt.
* libguile/vm-i-system.c (call, goto/args, return): use
VM_HANDLE_INTERRUPTS.
#ifdef BUILDING_LIBGUILE
/* FIXME: should change names */
-# define SCM_ASYNC_TICK \
- do \
- { \
- if (SCM_I_CURRENT_THREAD->pending_asyncs) \
- scm_async_click (); \
- } \
+# define SCM_ASYNC_TICK \
+ do \
+ { \
+ if (SCM_UNLIKELY (SCM_I_CURRENT_THREAD->pending_asyncs)) \
+ scm_async_click (); \
+ } \
+ while (0)
+
+/* SCM_ASYNC_TICK_WITH_CODE is only available to Guile itself */
+# define SCM_ASYNC_TICK_WITH_CODE(stmt) \
+ do \
+ { \
+ if (SCM_UNLIKELY (SCM_I_CURRENT_THREAD->pending_asyncs)) \
+ { \
+ stmt; \
+ scm_async_click (); \
+ } \
+ } \
while (0)
#else /* !BUILDING_LIBGUILE */
#define EXIT_HOOK() RUN_HOOK (SCM_VM_EXIT_HOOK)
#define RETURN_HOOK() RUN_HOOK (SCM_VM_RETURN_HOOK)
+#define VM_HANDLE_INTERRUPTS \
+ SCM_ASYNC_TICK_WITH_CODE (SYNC_REGISTER ())
+
\f
/*
* Stack operation
vm_call:
x = sp[-nargs];
- SYNC_REGISTER ();
- SCM_TICK; /* allow interrupt here */
+ VM_HANDLE_INTERRUPTS;
/*
* Subprogram call
vm_goto_args:
x = sp[-nargs];
- SYNC_REGISTER ();
- SCM_TICK; /* allow interrupt here */
+ VM_HANDLE_INTERRUPTS;
/*
* Tail call
vm_return:
EXIT_HOOK ();
RETURN_HOOK ();
- SYNC_REGISTER ();
- SCM_TICK; /* allow interrupt here */
+
+ VM_HANDLE_INTERRUPTS;
+
{
SCM ret;