1.0.4.16: some GC and interrupt refactoring
authorNikodemus Siivola <nikodemus@random-state.net>
Mon, 2 Apr 2007 08:37:36 +0000 (08:37 +0000)
committerNikodemus Siivola <nikodemus@random-state.net>
Mon, 2 Apr 2007 08:37:36 +0000 (08:37 +0000)
 * Conditionalize foreign_function_call_active on
   FOREIGN_FUNCTION_CALL_FLAG for clarity, and excice it from x86
   assember code.

 * Rename interrupt_maybe_gc to cheyneygc_handle_wp_violation, and
   move it cheyneygc.c. Don't pretend it is a signal handler, but pass
   in just the context and faulting address it needs.

 * Make gc_trigger_hit to accept the faulting address directly, since
   we already have it handy, and move it to cheneygc.c.

 * Rename interrupt_maybe_gc_int to maybe_gc, and move it to
   gc-common.c. Don't pretend it is a signal handler, but pass in just
   the context it needs.

 * maybe_gc_pending unused, deleted.

 * Only a single bytes_consed_between_gcs declaration, in gc.h.

 * Whitespace.

 No significant functional changes. Tested on x86/GENCGC, PPC/GENCGC,
 and PPC/Cheney.

 ...did you know that stepping is broken on PPC/Cheney but not on
 PPC/GENCGC?

19 files changed:
src/code/hash-table.lisp
src/compiler/ppc/insts.lisp
src/runtime/bsd-os.c
src/runtime/cheneygc-internal.h
src/runtime/cheneygc.c
src/runtime/gc-common.c
src/runtime/gc.h
src/runtime/gencgc.c
src/runtime/globals.c
src/runtime/globals.h
src/runtime/interrupt.c
src/runtime/interrupt.h
src/runtime/linux-os.c
src/runtime/osf1-os.c
src/runtime/ppc-arch.c
src/runtime/purify.c
src/runtime/sunos-os.c
src/runtime/x86-assem.S
version.lisp-expr

index 8ad97f3..22740e5 100644 (file)
@@ -87,7 +87,7 @@
 \f
 (defmacro-mundanely with-hash-table-iterator ((function hash-table) &body body)
   #!+sb-doc
-  "WITH-HASH-TABLE-ITERATOR ((function hash-table) &body body) 
+  "WITH-HASH-TABLE-ITERATOR ((function hash-table) &body body)
 
 Provides a method of manually looping over the elements of a hash-table.
 FUNCTION is bound to a generator-macro that, within the scope of the
index 14563c0..8229af3 100644 (file)
       (#.fun-end-breakpoint-trap
        (nt "Function end breakpoint trap"))
       (#.object-not-instance-trap
-       (nt "Object not instance trap"))
-    )))
+       (nt "Object not instance trap")))))
 
 (eval-when (:compile-toplevel :execute)
 
index 1b01396..dffa492 100644 (file)
@@ -207,7 +207,7 @@ memory_fault_handler(int signal, siginfo_t *siginfo, void *void_context
 #ifdef LISP_FEATURE_C_STACK_IS_CONTROL_STACK
             lisp_memory_fault_error(context, fault_addr);
 #else
-            if (!interrupt_maybe_gc_int(signal, siginfo, context)) {
+            if (!maybe_gc(context)) {
                 interrupt_handle_now(signal, siginfo, context);
             }
 #if defined(LISP_FEATURE_DARWIN)
@@ -269,9 +269,9 @@ sigsegv_handler(int signal, siginfo_t *info, void* void_context)
     unsigned int pc =  (unsigned int *)(*os_context_pc_addr(context));
     os_vm_address_t addr;
 
-    addr = arch_get_bad_addr(signal,info,context);
-    if(!interrupt_maybe_gc(signal, info, context))
-        if(!handle_guard_page_triggered(context,addr))
+    addr = arch_get_bad_addr(signal, info, context);
+    if (!cheneygc_handle_wp_violation(context, addr))
+        if (!handle_guard_page_triggered(context, addr))
             interrupt_handle_now(signal, info, context);
     /* Work around G5 bug; fix courtesy gbyers */
     DARWIN_FIX_CONTEXT(context);
index 874cff6..5b58bf6 100644 (file)
@@ -48,3 +48,4 @@ new_space_p(lispobj object)
 
 #endif
 
+extern boolean cheneygc_handle_wp_violation(os_context_t*, void*);
index 0f7d38b..25e9252 100644 (file)
@@ -48,8 +48,6 @@ lispobj *new_space_free_pointer;
 
 static void scavenge_newspace(void);
 
-extern unsigned long bytes_consed_between_gcs;
-
 \f
 /* collecting garbage */
 
@@ -623,3 +621,42 @@ void clear_auto_gc_trigger(void)
 
     current_auto_gc_trigger = NULL;
 }
+
+static boolean
+gc_trigger_hit(void *addr)
+{
+    if (current_auto_gc_trigger == NULL)
+        return 0;
+    else{
+        return (addr >= (void *)current_auto_gc_trigger &&
+                addr <((void *)current_dynamic_space + dynamic_space_size));
+    }
+}
+
+boolean
+cheneygc_handle_wp_violation(os_context_t *context, void *addr)
+{
+    if(!foreign_function_call_active && gc_trigger_hit(addr)){
+        struct thread *thread=arch_os_get_current_thread();
+        clear_auto_gc_trigger();
+        /* Don't flood the system with interrupts if the need to gc is
+         * already noted. This can happen for example when SUB-GC
+         * allocates or after a gc triggered in a WITHOUT-GCING. */
+        if (SymbolValue(GC_PENDING,thread) == NIL) {
+            if (SymbolValue(GC_INHIBIT,thread) == NIL) {
+                if (arch_pseudo_atomic_atomic(context)) {
+                    /* set things up so that GC happens when we finish
+                     * the PA section */
+                    SetSymbolValue(GC_PENDING,T,thread);
+                    arch_set_pseudo_atomic_interrupted(context);
+                } else {
+                    maybe_gc(context);
+                }
+            } else {
+                SetSymbolValue(GC_PENDING,T,thread);
+            }
+        }
+        return 1;
+    }
+    return 0;
+}
index f84d150..4182448 100644 (file)
@@ -2435,3 +2435,46 @@ gc_search_space(lispobj *start, size_t words, lispobj *pointer)
     }
     return (NULL);
 }
+
+boolean
+maybe_gc(os_context_t *context)
+{
+#ifndef LISP_FEATURE_WIN32
+    struct thread *thread = arch_os_get_current_thread();
+#endif
+
+    fake_foreign_function_call(context);
+    /* SUB-GC may return without GCing if *GC-INHIBIT* is set, in
+     * which case we will be running with no gc trigger barrier
+     * thing for a while.  But it shouldn't be long until the end
+     * of WITHOUT-GCING.
+     *
+     * FIXME: It would be good to protect the end of dynamic space for
+     * CheneyGC and signal a storage condition from there.
+     */
+
+    /* Restore the signal mask from the interrupted context before
+     * calling into Lisp if interrupts are enabled. Why not always?
+     *
+     * Suppose there is a WITHOUT-INTERRUPTS block far, far out. If an
+     * interrupt hits while in SUB-GC, it is deferred and the
+     * os_context_sigmask of that interrupt is set to block further
+     * deferrable interrupts (until the first one is
+     * handled). Unfortunately, that context refers to this place and
+     * when we return from here the signals will not be blocked.
+     *
+     * A kludgy alternative is to propagate the sigmask change to the
+     * outer context.
+     */
+#ifndef LISP_FEATURE_WIN32
+    if(SymbolValue(INTERRUPTS_ENABLED,thread)!=NIL) {
+        thread_sigmask(SIG_SETMASK, os_context_sigmask_addr(context), 0);
+        check_gc_signals_unblocked_or_lose();
+    }
+    else
+        unblock_gc_signals();
+#endif
+    funcall0(SymbolFunction(SUB_GC));
+    undo_fake_foreign_function_call(context);
+    return 1;
+}
index 76a10e1..224ae6c 100644 (file)
@@ -38,10 +38,12 @@ extern void gc_init_tables(void);
 extern void set_auto_gc_trigger(os_vm_size_t usage);
 extern void clear_auto_gc_trigger(void);
 
-extern int maybe_gc_pending;
-
 #include "fixnump.h"
 
 #include "pseudo-atomic.h"
 
+extern boolean maybe_gc(os_context_t *context);
+
+extern unsigned long bytes_consed_between_gcs;
+
 #endif /* _GC_H_ */
index 37b8b8e..136e23e 100644 (file)
@@ -145,7 +145,6 @@ boolean gencgc_partial_pickup = 0;
 
 /* the total bytes allocated. These are seen by Lisp DYNAMIC-USAGE. */
 unsigned long bytes_allocated = 0;
-extern unsigned long bytes_consed_between_gcs; /* gc-common.c */
 unsigned long auto_gc_trigger = 0;
 
 /* the source and destination generations. These are set before a GC starts
index 3d0139a..2b397cb 100644 (file)
@@ -22,7 +22,9 @@
 #include "globals.h"
 #include "validate.h"
 
+#ifdef FOREIGN_FUNCTION_CALL_FLAG
 int foreign_function_call_active;
+#endif
 
 lispobj *current_control_stack_pointer;
 lispobj *current_control_frame_pointer;
@@ -65,9 +67,11 @@ void globals_init(void)
     current_auto_gc_trigger = NULL;
 #endif
 
-    /* Set foreign function call active. */
+#ifdef FOREIGN_FUNCTION_CALL_FLAG
     foreign_function_call_active = 1;
-#if defined(LISP_FEATURE_SB_THREAD)
+#endif
+
+#ifdef LISP_FEATURE_SB_THREAD
     pthread_key_create(&specials,0);
 #endif
 }
index 4d83b31..de4b61f 100644 (file)
 
 #include "sbcl.h"
 
+/* Currently threads live only on x86oid platforms, but this thing
+ * cannot ever work with threads, so... */
+#if !defined(LISP_FEATURE_SB_THREAD) && !defined(LISP_FEATURE_X86) && !defined(LISP_FEATURE_X86_64)
+#define FOREIGN_FUNCTION_CALL_FLAG
+#endif
+
 #ifndef LANGUAGE_ASSEMBLY
+
+#ifdef FOREIGN_FUNCTION_CALL_FLAG
 extern int foreign_function_call_active;
+#endif
+
 extern size_t dynamic_space_size;
 
 #ifdef LISP_FEATURE_WIN32
@@ -102,7 +112,9 @@ extern void globals_init(void);
 #  define POINTERSIZE 4
 # endif
 
+#ifdef FOREIGN_FUNCTION_CALL_FLAG
 EXTERN(foreign_function_call_active, 4)
+#endif
 
 EXTERN(current_control_stack_pointer, POINTERSIZE)
 EXTERN(current_control_frame_pointer, POINTERSIZE)
index 69e890d..7e278d1 100644 (file)
@@ -73,7 +73,6 @@ static void store_signal_data_for_later (struct interrupt_data *data,
                                          void *handler, int signal,
                                          siginfo_t *info,
                                          os_context_t *context);
-boolean interrupt_maybe_gc_int(int signal, siginfo_t *info, void *v_context);
 
 void
 sigaddset_deferrable(sigset_t *s)
@@ -178,7 +177,7 @@ check_interrupts_enabled_or_lose(os_context_t *context)
     if (SymbolValue(INTERRUPTS_ENABLED,thread) == NIL)
         lose("interrupts not enabled\n");
     if (
-#if !defined(LISP_FEATURE_X86) && !defined(LISP_FEATURE_X86_64)
+#ifdef FOREIGN_FUNCTION_CALL_FLAG
         (!foreign_function_call_active) &&
 #endif
         arch_pseudo_atomic_atomic(context))
@@ -330,8 +329,9 @@ fake_foreign_function_call(os_context_t *context)
 
     thread->interrupt_contexts[context_index] = context;
 
-    /* no longer in Lisp now */
+#ifdef FOREIGN_FUNCTION_CALL_FLAG
     foreign_function_call_active = 1;
+#endif
 }
 
 /* blocks all blockable signals.  If you are calling from a signal handler,
@@ -344,8 +344,9 @@ undo_fake_foreign_function_call(os_context_t *context)
     /* Block all blockable signals. */
     block_blockable_signals();
 
-    /* going back into Lisp */
+#ifdef FOREIGN_FUNCTION_CALL_FLAG
     foreign_function_call_active = 0;
+#endif
 
     /* Undo dynamic binding of FREE_INTERRUPT_CONTEXT_INDEX */
     unbind(thread);
@@ -432,7 +433,7 @@ interrupt_handle_pending(os_context_t *context)
             /* GC_PENDING is cleared in SUB-GC, or if another thread
              * is doing a gc already we will get a SIG_STOP_FOR_GC and
              * that will clear it. */
-            interrupt_maybe_gc_int(0,NULL,context);
+            maybe_gc(context);
         }
         check_blockables_blocked_or_lose();
     }
@@ -441,7 +442,7 @@ interrupt_handle_pending(os_context_t *context)
      * enabled run the pending handler */
     if (!((SymbolValue(INTERRUPTS_ENABLED,thread) == NIL) ||
           (
-#if !defined(LISP_FEATURE_X86) && !defined(LISP_FEATURE_X86_64)
+#ifdef FOREIGN_FUNCTION_CALL_FLAG
            (!foreign_function_call_active) &&
 #endif
            arch_pseudo_atomic_atomic(context)))) {
@@ -496,7 +497,7 @@ void
 interrupt_handle_now(int signal, siginfo_t *info, void *void_context)
 {
     os_context_t *context = (os_context_t*)void_context;
-#if !defined(LISP_FEATURE_X86) && !defined(LISP_FEATURE_X86_64)
+#ifndef LISP_FEATURE_SB_THREAD
     boolean were_in_lisp;
 #endif
     union interrupt_handler handler;
@@ -523,7 +524,7 @@ interrupt_handle_now(int signal, siginfo_t *info, void *void_context)
         return;
     }
 
-#if !defined(LISP_FEATURE_X86) && !defined(LISP_FEATURE_X86_64)
+#ifdef FOREIGN_FUNCTION_CALL_FLAG
     were_in_lisp = !foreign_function_call_active;
     if (were_in_lisp)
 #endif
@@ -649,7 +650,7 @@ maybe_defer_handler(void *handler, struct interrupt_data *data,
      * actually use its argument for anything on x86, so this branch
      * may succeed even when context is null (gencgc alloc()) */
     if (
-#if !defined(LISP_FEATURE_X86) && !defined(LISP_FEATURE_X86_64)
+#ifdef FOREIGN_FUNCTION_CALL_FLAG
         /* FIXME: this foreign_function_call_active test is dubious at
          * best. If a foreign call is made in a pseudo atomic section
          * (?) or more likely a pseudo atomic section is in a foreign
@@ -844,18 +845,6 @@ interrupt_handle_now_handler(int signal, siginfo_t *info, void *void_context)
  */
 
 #ifndef LISP_FEATURE_GENCGC
-/* since GENCGC has its own way to record trigger */
-static boolean
-gc_trigger_hit(int signal, siginfo_t *info, os_context_t *context)
-{
-    if (current_auto_gc_trigger == NULL)
-        return 0;
-    else{
-        void *badaddr=arch_get_bad_addr(signal,info,context);
-        return (badaddr >= (void *)current_auto_gc_trigger &&
-                badaddr <((void *)current_dynamic_space + dynamic_space_size));
-    }
-}
 #endif
 
 /* manipulate the signal context and stack such that when the handler
@@ -1105,92 +1094,6 @@ handle_guard_page_triggered(os_context_t *context,os_vm_address_t addr)
     }
     else return 0;
 }
-
-#ifndef LISP_FEATURE_GENCGC
-/* This function gets called from the SIGSEGV (for e.g. Linux, NetBSD, &
- * OpenBSD) or SIGBUS (for e.g. FreeBSD) handler. Here we check
- * whether the signal was due to treading on the mprotect()ed zone -
- * and if so, arrange for a GC to happen. */
-extern unsigned long bytes_consed_between_gcs; /* gc-common.c */
-
-boolean
-interrupt_maybe_gc(int signal, siginfo_t *info, void *void_context)
-{
-    os_context_t *context=(os_context_t *) void_context;
-
-    if(!foreign_function_call_active && gc_trigger_hit(signal, info, context)){
-        struct thread *thread=arch_os_get_current_thread();
-        clear_auto_gc_trigger();
-        /* Don't flood the system with interrupts if the need to gc is
-         * already noted. This can happen for example when SUB-GC
-         * allocates or after a gc triggered in a WITHOUT-GCING. */
-        if (SymbolValue(GC_PENDING,thread) == NIL) {
-            if (SymbolValue(GC_INHIBIT,thread) == NIL) {
-                if (arch_pseudo_atomic_atomic(context)) {
-                    /* set things up so that GC happens when we finish
-                     * the PA section */
-                    SetSymbolValue(GC_PENDING,T,thread);
-                    arch_set_pseudo_atomic_interrupted(context);
-                } else {
-                    interrupt_maybe_gc_int(signal,info,void_context);
-                }
-            } else {
-                SetSymbolValue(GC_PENDING,T,thread);
-            }
-        }
-        return 1;
-    }
-    return 0;
-}
-
-#endif
-
-/* this is also used by gencgc, in alloc() */
-boolean
-interrupt_maybe_gc_int(int signal, siginfo_t *info, void *void_context)
-{
-    os_context_t *context=(os_context_t *) void_context;
-#ifndef LISP_FEATURE_WIN32
-    struct thread *thread=arch_os_get_current_thread();
-#endif
-
-    fake_foreign_function_call(context);
-
-    /* SUB-GC may return without GCing if *GC-INHIBIT* is set, in
-     * which case we will be running with no gc trigger barrier
-     * thing for a while.  But it shouldn't be long until the end
-     * of WITHOUT-GCING.
-     *
-     * FIXME: It would be good to protect the end of dynamic space
-     * and signal a storage condition from there.
-     */
-
-    /* Restore the signal mask from the interrupted context before
-     * calling into Lisp if interrupts are enabled. Why not always?
-     *
-     * Suppose there is a WITHOUT-INTERRUPTS block far, far out. If an
-     * interrupt hits while in SUB-GC, it is deferred and the
-     * os_context_sigmask of that interrupt is set to block further
-     * deferrable interrupts (until the first one is
-     * handled). Unfortunately, that context refers to this place and
-     * when we return from here the signals will not be blocked.
-     *
-     * A kludgy alternative is to propagate the sigmask change to the
-     * outer context.
-     */
-#ifndef LISP_FEATURE_WIN32
-    if(SymbolValue(INTERRUPTS_ENABLED,thread)!=NIL) {
-        thread_sigmask(SIG_SETMASK, os_context_sigmask_addr(context), 0);
-        check_gc_signals_unblocked_or_lose();
-    }
-    else
-        unblock_gc_signals();
-#endif
-    funcall0(SymbolFunction(SUB_GC));
-    undo_fake_foreign_function_call(context);
-    return 1;
-}
-
 \f
 /*
  * noise to install handlers
index ee13671..405b354 100644 (file)
@@ -68,8 +68,6 @@ extern void interrupt_handle_now(int, siginfo_t*, void*);
 extern void interrupt_handle_pending(os_context_t*);
 extern void interrupt_internal_error(os_context_t*, boolean continuable);
 extern boolean handle_guard_page_triggered(os_context_t *,os_vm_address_t);
-extern boolean interrupt_maybe_gc(int, siginfo_t*, void*);
-extern boolean interrupt_maybe_gc_int(int, siginfo_t *, void *);
 extern boolean maybe_defer_handler(void *handler, struct interrupt_data *data,
                                    int signal, siginfo_t *info,
                                    os_context_t *context);
index 6724eb1..236a33e 100644 (file)
@@ -389,7 +389,7 @@ sigsegv_handler(int signal, siginfo_t *info, void* void_context)
 #ifdef LISP_FEATURE_GENCGC
     if (!gencgc_handle_wp_violation(addr))
 #else
-    if (!interrupt_maybe_gc(signal, info, context))
+    if (!cheneygc_handle_wp_violation(context, addr))
 #endif
         if (!handle_guard_page_triggered(context, addr))
 #ifdef LISP_FEATURE_C_STACK_IS_CONTROL_STACK
index f2a40b7..baba3bf 100644 (file)
@@ -133,7 +133,7 @@ sigsegv_handler(int signal, siginfo_t *info, void* void_context)
         /* this is lifted from linux-os.c, so violates OOAO */
         *os_context_register_addr(context,reg_ALLOC) -= (1L<<63);
         interrupt_handle_pending(context);
-    } else if (!interrupt_maybe_gc(signal, info, context)) {
+    } else if (!cheneygc_handle_wp_violation(context, addr)) {
         if(!handle_guard_page_triggered(context,addr))
             interrupt_handle_now(signal, info, context);
     }
index 35dc843..28c364b 100644 (file)
@@ -99,7 +99,7 @@ arch_clear_pseudo_atomic_interrupted(os_context_t *context)
     *os_context_register_addr(context,reg_ALLOC) &= ~1;
 }
 
-unsigned int
+unsigned int 
 arch_install_breakpoint(void *pc)
 {
     unsigned int *ptr = (unsigned int *)pc;
@@ -137,9 +137,9 @@ static unsigned int *skipped_break_addr, displaced_after_inst;
 static sigset_t orig_sigmask;
 
 void
-arch_do_displaced_inst(os_context_t *context,unsigned int orig_inst)
+arch_do_displaced_inst(os_context_t *context, unsigned int orig_inst)
 {
-    /* not sure how we ensure that we get the breakpoint reinstalled
+    /* not sure how we ensure that we get the breakpoint reinstalled 
      * after doing this -dan */
     unsigned int *pc = (unsigned int *)(*os_context_pc_addr(context));
 
@@ -149,6 +149,10 @@ arch_do_displaced_inst(os_context_t *context,unsigned int orig_inst)
     *pc = orig_inst;
     os_flush_icache((os_vm_address_t) pc, sizeof(unsigned int));
     skipped_break_addr = pc;
+
+    /* FIXME: we should apparently be installing the after-breakpoint
+     * here, but would need to find the next instruction address for
+     * it first. alpha-arch.c shows how to do it. --NS 2007-04-02 */
 }
 
 #ifdef LISP_FEATURE_GENCGC
@@ -231,10 +235,8 @@ handle_allocation_trap(os_context_t * context)
     fprintf(stderr, "In handle_allocation_trap\n");
 #endif
 
-    /*
-     * I don't think it's possible for us NOT to be in lisp when we get
-     * here.  Remove this later?
-     */
+    /* I don't think it's possible for us NOT to be in lisp when we get
+     * here.  Remove this later? */
     were_in_lisp = !foreign_function_call_active;
 
     if (were_in_lisp) {
@@ -387,9 +389,6 @@ arch_handle_fun_end_breakpoint(os_context_t *context)
         =(int)handle_fun_end_breakpoint(context);
 }
 
-/* FIXME: AFTER-BREAKPOINT-TRAP is defined for PPC, but never
- * emitted as far as I can see. Should it be emitted, do removed
- * entirely? */
 void
 arch_handle_after_breakpoint(os_context_t *context)
 {
index e753c13..91b4232 100644 (file)
@@ -37,8 +37,6 @@
 
 #define PRINTNOISE
 
-extern unsigned long bytes_consed_between_gcs;
-
 static lispobj *dynamic_space_purify_pointer;
 
 \f
index bc4d397..8d8bb28 100644 (file)
@@ -217,11 +217,10 @@ static void
 sigsegv_handler(int signal, siginfo_t *info, void* void_context)
 {
     os_context_t *context = arch_os_get_context(&void_context);
-    os_vm_address_t addr;
+    os_vm_address_t addr = arch_get_bad_addr(signal, info, context);
 
-    addr = arch_get_bad_addr(signal, info, context);
-    if(!interrupt_maybe_gc(signal, info, context)) {
-        if(!handle_guard_page_triggered(context,addr))
+    if (!cheneygc_handle_wp_violation(context, addr)) {
+        if (!handle_guard_page_triggered(context,addr))
             interrupt_handle_now(signal, info, context);
     }
 }
index ca2b2d6..c4d2f5e 100644 (file)
@@ -88,7 +88,6 @@
 #endif
 
        .text
-       .globl  GNAME(foreign_function_call_active)
        .globl  GNAME(all_threads)
 \f
 /*
        .globl GNAME(call_into_c)
        TYPE(GNAME(call_into_c))
 GNAME(call_into_c):
-       movl    $1,GNAME(foreign_function_call_active)
-
 /* Save the return Lisp address in ebx. */
        popl    %ebx
 
@@ -154,7 +151,6 @@ GNAME(call_into_c):
 /* Restore the return value. */
        movl    %ecx,%eax       # maybe return value
 
-       movl    $0,GNAME(foreign_function_call_active)
 /* Return. */
        jmp     *%ebx
 
@@ -172,7 +168,6 @@ Lfp_rtn_value:
 
 /* We don't need to restore eax, because the result is in st(0). */
 
-       movl    $0,GNAME(foreign_function_call_active)
 /* Return. */  
        jmp     *%ebx
 
@@ -252,8 +247,6 @@ Lstack:
        xorl    %esi,%esi       # third arg
 
 /* no longer in function call */
-       movl    %eax, GNAME(foreign_function_call_active)
-
        movl    %esp,%ebx       # remember current stack
        pushl   %ebx            # Save entry stack on (maybe) new stack.
 
index 1754cd8..4b8e5c5 100644 (file)
@@ -17,4 +17,4 @@
 ;;; checkins which aren't released. (And occasionally for internal
 ;;; versions, especially for internal versions off the main CVS
 ;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".)
-"1.0.4.15"
+"1.0.4.16"