[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;
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Emacs-diffs] master e080d01: Re-port alloc.c to Solaris sparc and simplify,
Paul Eggert <=