emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master e080d01: Re-port alloc.c to Solaris sparc and simpl


From: Paul Eggert
Subject: [Emacs-diffs] master e080d01: Re-port alloc.c to Solaris sparc and simplify
Date: Fri, 3 Feb 2017 06:58:33 +0000 (UTC)

branch: master
commit e080d019f41d2738ba0db721c1b89ea57413439b
Author: Paul Eggert <address@hidden>
Commit: Paul Eggert <address@hidden>

    Re-port alloc.c to Solaris sparc and simplify
    
    alloc.c had bitrotted a bit, and used an undefined symbol
    stack_base when Emacs was built on Solaris sparc, leading to
    compilation failures.  Also, code related to __builtin_unwind_init
    was unnecessarily duplicated.  Fix the bitrot and remove some
    duplication.
    * src/alloc.c: Remove uses of GC_SAVE_REGISTERS_ON_STACK, since it
    is never defined.
    (test_setjmp) [!HAVE___BUILTIN_UNWIND_INIT && GC_SETJMP_WORKS]:
    Define a no-op dummy, to simplify use.
    (test_setjmp) [!GC_SETJMP_WORKS]: Test setjmp_tested_p here rather
    than in the caller, to simplify use.
    (stacktop_sentry): New type.
    (__builtin_unwind_init) [!HAVE___BUILTIN_UNWIND_INIT]: New macro.
    (SET_STACK_TOP_ADDRESS): New macro, containing code that was duplicated.
    (flush_stack_call_func, Fgarbage_collect): Use it.
    (init_alloc): Omit unnecessary initialization.
    After dumping, Emacs need not re-test setjmp.
---
 src/alloc.c |  189 ++++++++++++++++++++++-------------------------------------
 1 file changed, 69 insertions(+), 120 deletions(-)

diff --git a/src/alloc.c b/src/alloc.c
index e909d31..62f4366 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -4887,12 +4887,19 @@ mark_memory (void *start, void *end)
     }
 }
 
-#if !defined GC_SAVE_REGISTERS_ON_STACK && !defined GC_SETJMP_WORKS
+#ifndef HAVE___BUILTIN_UNWIND_INIT
+
+# ifdef GC_SETJMP_WORKS
+static void
+test_setjmp (void)
+{
+}
+# else
 
 static bool setjmp_tested_p;
 static int longjmps_done;
 
-#define SETJMP_WILL_LIKELY_WORK "\
+#  define SETJMP_WILL_LIKELY_WORK "\
 \n\
 Emacs garbage collector has been changed to use conservative stack\n\
 marking.  Emacs has determined that the method it uses to do the\n\
@@ -4905,7 +4912,7 @@ verify that the methods used are appropriate for your 
system.\n\
 Please mail the result to <address@hidden>.\n\
 "
 
-#define SETJMP_WILL_NOT_WORK "\
+#  define SETJMP_WILL_NOT_WORK "\
 \n\
 Emacs garbage collector has been changed to use conservative stack\n\
 marking.  Emacs has determined that the default method it uses to do the\n\
@@ -4931,6 +4938,9 @@ Please mail the result to <address@hidden>.\n\
 static void
 test_setjmp (void)
 {
+  if (setjmp_tested_p)
+    return;
+  setjmp_tested_p = true;
   char buf[10];
   register int x;
   sys_jmp_buf jbuf;
@@ -4967,9 +4977,60 @@ test_setjmp (void)
   if (longjmps_done == 1)
     sys_longjmp (jbuf, 1);
 }
+# endif /* ! GC_SETJMP_WORKS */
+#endif /* ! HAVE___BUILTIN_UNWIND_INIT */
 
-#endif /* not GC_SAVE_REGISTERS_ON_STACK && not GC_SETJMP_WORKS */
+/* The type of an object near the stack top, whose address can be used
+   as a stack scan limit.  */
+typedef union
+{
+  /* Align the stack top properly.  Even if !HAVE___BUILTIN_UNWIND_INIT,
+     jmp_buf may not be aligned enough on darwin-ppc64.  */
+  max_align_t o;
+#ifndef HAVE___BUILTIN_UNWIND_INIT
+  sys_jmp_buf j;
+  char c;
+#endif
+} stacktop_sentry;
+
+/* Force callee-saved registers and register windows onto the stack.
+   Use the platform-defined __builtin_unwind_init if available,
+   obviating the need for machine dependent methods.  */
+#ifndef HAVE___BUILTIN_UNWIND_INIT
+# ifdef __sparc__
+   /* This trick flushes the register windows so that all the state of
+      the process is contained in the stack.
+      FreeBSD does not have a ta 3 handler, so handle it specially.
+      FIXME: Code in the Boehm GC suggests flushing (with 'flushrs') is
+      needed on ia64 too.  See mach_dep.c, where it also says inline
+      assembler doesn't work with relevant proprietary compilers.  */
+#  if defined __sparc64__ && defined __FreeBSD__
+#   define __builtin_unwind_init() asm ("flushw")
+#  else
+#   define __builtin_unwind_init() asm ("ta 3")
+#  endif
+# else
+#  define __builtin_unwind_init() ((void) 0)
+# endif
+#endif
 
+/* Set *P to the address of the top of the stack.  This must be a
+   macro, not a function, so that it is executed in the caller’s
+   environment.  It is not inside a do-while so that its storage
+   survives the macro.  */
+#ifdef HAVE___BUILTIN_UNWIND_INIT
+# define SET_STACK_TOP_ADDRESS(p)      \
+   stacktop_sentry sentry;             \
+   __builtin_unwind_init ();           \
+   *(p) = &sentry
+#else
+# define SET_STACK_TOP_ADDRESS(p)              \
+   stacktop_sentry sentry;                     \
+   __builtin_unwind_init ();                   \
+   test_setjmp ();                             \
+   sys_setjmp (sentry.j);                      \
+   *(p) = &sentry + (stack_bottom < &sentry.c)
+#endif
 
 /* Mark live Lisp objects on the C stack.
 
@@ -4981,12 +5042,7 @@ test_setjmp (void)
    We have to mark Lisp objects in CPU registers that can hold local
    variables or are used to pass parameters.
 
-   If GC_SAVE_REGISTERS_ON_STACK is defined, it should expand to
-   something that either saves relevant registers on the stack, or
-   calls mark_maybe_object passing it each register's contents.
-
-   If GC_SAVE_REGISTERS_ON_STACK is not defined, the current
-   implementation assumes that calling setjmp saves registers we need
+   This code assumes that calling setjmp saves registers we need
    to see in a jmp_buf which itself lies on the stack.  This doesn't
    have to be true!  It must be verified for each system, possibly
    by taking a look at the source code of setjmp.
@@ -5050,62 +5106,9 @@ flush_stack_call_func (void (*func) (void *arg), void 
*arg)
 {
   void *end;
   struct thread_state *self = current_thread;
-
-#ifdef HAVE___BUILTIN_UNWIND_INIT
-  /* Force callee-saved registers and register windows onto the stack.
-     This is the preferred method if available, obviating the need for
-     machine dependent methods.  */
-  __builtin_unwind_init ();
-  end = &end;
-#else /* not HAVE___BUILTIN_UNWIND_INIT */
-#ifndef GC_SAVE_REGISTERS_ON_STACK
-  /* jmp_buf may not be aligned enough on darwin-ppc64 */
-  union aligned_jmpbuf {
-    Lisp_Object o;
-    sys_jmp_buf j;
-  } j;
-  volatile bool stack_grows_down_p = (char *) &j > (char *) stack_bottom;
-#endif
-  /* This trick flushes the register windows so that all the state of
-     the process is contained in the stack.  */
-  /* Fixme: Code in the Boehm GC suggests flushing (with `flushrs') is
-     needed on ia64 too.  See mach_dep.c, where it also says inline
-     assembler doesn't work with relevant proprietary compilers.  */
-#ifdef __sparc__
-#if defined (__sparc64__) && defined (__FreeBSD__)
-  /* FreeBSD does not have a ta 3 handler.  */
-  asm ("flushw");
-#else
-  asm ("ta 3");
-#endif
-#endif
-
-  /* Save registers that we need to see on the stack.  We need to see
-     registers used to hold register variables and registers used to
-     pass parameters.  */
-#ifdef GC_SAVE_REGISTERS_ON_STACK
-  GC_SAVE_REGISTERS_ON_STACK (end);
-#else /* not GC_SAVE_REGISTERS_ON_STACK */
-
-#ifndef GC_SETJMP_WORKS  /* If it hasn't been checked yet that
-                           setjmp will definitely work, test it
-                           and print a message with the result
-                           of the test.  */
-  if (!setjmp_tested_p)
-    {
-      setjmp_tested_p = 1;
-      test_setjmp ();
-    }
-#endif /* GC_SETJMP_WORKS */
-
-  sys_setjmp (j.j);
-  end = stack_grows_down_p ? (char *) &j + sizeof j : (char *) &j;
-#endif /* not GC_SAVE_REGISTERS_ON_STACK */
-#endif /* not HAVE___BUILTIN_UNWIND_INIT */
-
+  SET_STACK_TOP_ADDRESS (&end);
   self->stack_top = end;
-  (*func) (arg);
-
+  func (arg);
   eassert (current_thread == self);
 }
 
@@ -6047,58 +6050,7 @@ See Info node `(elisp)Garbage Collection'.  */)
   (void)
 {
   void *end;
-
-#ifdef HAVE___BUILTIN_UNWIND_INIT
-  /* Force callee-saved registers and register windows onto the stack.
-     This is the preferred method if available, obviating the need for
-     machine dependent methods.  */
-  __builtin_unwind_init ();
-  end = &end;
-#else /* not HAVE___BUILTIN_UNWIND_INIT */
-#ifndef GC_SAVE_REGISTERS_ON_STACK
-  /* jmp_buf may not be aligned enough on darwin-ppc64 */
-  union aligned_jmpbuf {
-    Lisp_Object o;
-    sys_jmp_buf j;
-  } j;
-  volatile bool stack_grows_down_p = (char *) &j > (char *) stack_base;
-#endif
-  /* This trick flushes the register windows so that all the state of
-     the process is contained in the stack.  */
-  /* Fixme: Code in the Boehm GC suggests flushing (with `flushrs') is
-     needed on ia64 too.  See mach_dep.c, where it also says inline
-     assembler doesn't work with relevant proprietary compilers.  */
-#ifdef __sparc__
-#if defined (__sparc64__) && defined (__FreeBSD__)
-  /* FreeBSD does not have a ta 3 handler.  */
-  asm ("flushw");
-#else
-  asm ("ta 3");
-#endif
-#endif
-
-  /* Save registers that we need to see on the stack.  We need to see
-     registers used to hold register variables and registers used to
-     pass parameters.  */
-#ifdef GC_SAVE_REGISTERS_ON_STACK
-  GC_SAVE_REGISTERS_ON_STACK (end);
-#else /* not GC_SAVE_REGISTERS_ON_STACK */
-
-#ifndef GC_SETJMP_WORKS  /* If it hasn't been checked yet that
-                           setjmp will definitely work, test it
-                           and print a message with the result
-                           of the test.  */
-  if (!setjmp_tested_p)
-    {
-      setjmp_tested_p = 1;
-      test_setjmp ();
-    }
-#endif /* GC_SETJMP_WORKS */
-
-  sys_setjmp (j.j);
-  end = stack_grows_down_p ? (char *) &j + sizeof j : (char *) &j;
-#endif /* not GC_SAVE_REGISTERS_ON_STACK */
-#endif /* not HAVE___BUILTIN_UNWIND_INIT */
+  SET_STACK_TOP_ADDRESS (&end);
   return garbage_collect_1 (end);
 }
 
@@ -7408,9 +7360,6 @@ init_alloc_once (void)
 void
 init_alloc (void)
 {
-#if !defined GC_SAVE_REGISTERS_ON_STACK && !defined GC_SETJMP_WORKS
-  setjmp_tested_p = longjmps_done = 0;
-#endif
   Vgc_elapsed = make_float (0.0);
   gcs_done = 0;
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]