aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2017-02-02 21:28:45 -0800
committerPaul Eggert2017-02-02 22:58:20 -0800
commite080d019f41d2738ba0db721c1b89ea57413439b (patch)
tree0112d0f4515e2b2bb2aa599ad9137c309d34cc14 /src
parentce88155d83ba84e84321ed69a39c82f40117dd1f (diff)
downloademacs-e080d019f41d2738ba0db721c1b89ea57413439b.tar.gz
emacs-e080d019f41d2738ba0db721c1b89ea57413439b.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/alloc.c189
1 files changed, 69 insertions, 120 deletions
diff --git a/src/alloc.c b/src/alloc.c
index e909d312c4e..62f43669f2a 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -4887,12 +4887,19 @@ mark_memory (void *start, void *end)
4887 } 4887 }
4888} 4888}
4889 4889
4890#if !defined GC_SAVE_REGISTERS_ON_STACK && !defined GC_SETJMP_WORKS 4890#ifndef HAVE___BUILTIN_UNWIND_INIT
4891
4892# ifdef GC_SETJMP_WORKS
4893static void
4894test_setjmp (void)
4895{
4896}
4897# else
4891 4898
4892static bool setjmp_tested_p; 4899static bool setjmp_tested_p;
4893static int longjmps_done; 4900static int longjmps_done;
4894 4901
4895#define SETJMP_WILL_LIKELY_WORK "\ 4902# define SETJMP_WILL_LIKELY_WORK "\
4896\n\ 4903\n\
4897Emacs garbage collector has been changed to use conservative stack\n\ 4904Emacs garbage collector has been changed to use conservative stack\n\
4898marking. Emacs has determined that the method it uses to do the\n\ 4905marking. 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\
4905Please mail the result to <emacs-devel@gnu.org>.\n\ 4912Please mail the result to <emacs-devel@gnu.org>.\n\
4906" 4913"
4907 4914
4908#define SETJMP_WILL_NOT_WORK "\ 4915# define SETJMP_WILL_NOT_WORK "\
4909\n\ 4916\n\
4910Emacs garbage collector has been changed to use conservative stack\n\ 4917Emacs garbage collector has been changed to use conservative stack\n\
4911marking. Emacs has determined that the default method it uses to do the\n\ 4918marking. Emacs has determined that the default method it uses to do the\n\
@@ -4931,6 +4938,9 @@ Please mail the result to <emacs-devel@gnu.org>.\n\
4931static void 4938static void
4932test_setjmp (void) 4939test_setjmp (void)
4933{ 4940{
4941 if (setjmp_tested_p)
4942 return;
4943 setjmp_tested_p = true;
4934 char buf[10]; 4944 char buf[10];
4935 register int x; 4945 register int x;
4936 sys_jmp_buf jbuf; 4946 sys_jmp_buf jbuf;
@@ -4967,9 +4977,60 @@ test_setjmp (void)
4967 if (longjmps_done == 1) 4977 if (longjmps_done == 1)
4968 sys_longjmp (jbuf, 1); 4978 sys_longjmp (jbuf, 1);
4969} 4979}
4980# endif /* ! GC_SETJMP_WORKS */
4981#endif /* ! HAVE___BUILTIN_UNWIND_INIT */
4970 4982
4971#endif /* not GC_SAVE_REGISTERS_ON_STACK && not GC_SETJMP_WORKS */ 4983/* The type of an object near the stack top, whose address can be used
4984 as a stack scan limit. */
4985typedef union
4986{
4987 /* Align the stack top properly. Even if !HAVE___BUILTIN_UNWIND_INIT,
4988 jmp_buf may not be aligned enough on darwin-ppc64. */
4989 max_align_t o;
4990#ifndef HAVE___BUILTIN_UNWIND_INIT
4991 sys_jmp_buf j;
4992 char c;
4993#endif
4994} stacktop_sentry;
4995
4996/* Force callee-saved registers and register windows onto the stack.
4997 Use the platform-defined __builtin_unwind_init if available,
4998 obviating the need for machine dependent methods. */
4999#ifndef HAVE___BUILTIN_UNWIND_INIT
5000# ifdef __sparc__
5001 /* This trick flushes the register windows so that all the state of
5002 the process is contained in the stack.
5003 FreeBSD does not have a ta 3 handler, so handle it specially.
5004 FIXME: Code in the Boehm GC suggests flushing (with 'flushrs') is
5005 needed on ia64 too. See mach_dep.c, where it also says inline
5006 assembler doesn't work with relevant proprietary compilers. */
5007# if defined __sparc64__ && defined __FreeBSD__
5008# define __builtin_unwind_init() asm ("flushw")
5009# else
5010# define __builtin_unwind_init() asm ("ta 3")
5011# endif
5012# else
5013# define __builtin_unwind_init() ((void) 0)
5014# endif
5015#endif
4972 5016
5017/* Set *P to the address of the top of the stack. This must be a
5018 macro, not a function, so that it is executed in the caller’s
5019 environment. It is not inside a do-while so that its storage
5020 survives the macro. */
5021#ifdef HAVE___BUILTIN_UNWIND_INIT
5022# define SET_STACK_TOP_ADDRESS(p) \
5023 stacktop_sentry sentry; \
5024 __builtin_unwind_init (); \
5025 *(p) = &sentry
5026#else
5027# define SET_STACK_TOP_ADDRESS(p) \
5028 stacktop_sentry sentry; \
5029 __builtin_unwind_init (); \
5030 test_setjmp (); \
5031 sys_setjmp (sentry.j); \
5032 *(p) = &sentry + (stack_bottom < &sentry.c)
5033#endif
4973 5034
4974/* Mark live Lisp objects on the C stack. 5035/* Mark live Lisp objects on the C stack.
4975 5036
@@ -4981,12 +5042,7 @@ test_setjmp (void)
4981 We have to mark Lisp objects in CPU registers that can hold local 5042 We have to mark Lisp objects in CPU registers that can hold local
4982 variables or are used to pass parameters. 5043 variables or are used to pass parameters.
4983 5044
4984 If GC_SAVE_REGISTERS_ON_STACK is defined, it should expand to 5045 This code assumes that calling setjmp saves registers we need
4985 something that either saves relevant registers on the stack, or
4986 calls mark_maybe_object passing it each register's contents.
4987
4988 If GC_SAVE_REGISTERS_ON_STACK is not defined, the current
4989 implementation assumes that calling setjmp saves registers we need
4990 to see in a jmp_buf which itself lies on the stack. This doesn't 5046 to see in a jmp_buf which itself lies on the stack. This doesn't
4991 have to be true! It must be verified for each system, possibly 5047 have to be true! It must be verified for each system, possibly
4992 by taking a look at the source code of setjmp. 5048 by taking a look at the source code of setjmp.
@@ -5050,62 +5106,9 @@ flush_stack_call_func (void (*func) (void *arg), void *arg)
5050{ 5106{
5051 void *end; 5107 void *end;
5052 struct thread_state *self = current_thread; 5108 struct thread_state *self = current_thread;
5053 5109 SET_STACK_TOP_ADDRESS (&end);
5054#ifdef HAVE___BUILTIN_UNWIND_INIT
5055 /* Force callee-saved registers and register windows onto the stack.
5056 This is the preferred method if available, obviating the need for
5057 machine dependent methods. */
5058 __builtin_unwind_init ();
5059 end = &end;
5060#else /* not HAVE___BUILTIN_UNWIND_INIT */
5061#ifndef GC_SAVE_REGISTERS_ON_STACK
5062 /* jmp_buf may not be aligned enough on darwin-ppc64 */
5063 union aligned_jmpbuf {
5064 Lisp_Object o;
5065 sys_jmp_buf j;
5066 } j;
5067 volatile bool stack_grows_down_p = (char *) &j > (char *) stack_bottom;
5068#endif
5069 /* This trick flushes the register windows so that all the state of
5070 the process is contained in the stack. */
5071 /* Fixme: Code in the Boehm GC suggests flushing (with `flushrs') is
5072 needed on ia64 too. See mach_dep.c, where it also says inline
5073 assembler doesn't work with relevant proprietary compilers. */
5074#ifdef __sparc__
5075#if defined (__sparc64__) && defined (__FreeBSD__)
5076 /* FreeBSD does not have a ta 3 handler. */
5077 asm ("flushw");
5078#else
5079 asm ("ta 3");
5080#endif
5081#endif
5082
5083 /* Save registers that we need to see on the stack. We need to see
5084 registers used to hold register variables and registers used to
5085 pass parameters. */
5086#ifdef GC_SAVE_REGISTERS_ON_STACK
5087 GC_SAVE_REGISTERS_ON_STACK (end);
5088#else /* not GC_SAVE_REGISTERS_ON_STACK */
5089
5090#ifndef GC_SETJMP_WORKS /* If it hasn't been checked yet that
5091 setjmp will definitely work, test it
5092 and print a message with the result
5093 of the test. */
5094 if (!setjmp_tested_p)
5095 {
5096 setjmp_tested_p = 1;
5097 test_setjmp ();
5098 }
5099#endif /* GC_SETJMP_WORKS */
5100
5101 sys_setjmp (j.j);
5102 end = stack_grows_down_p ? (char *) &j + sizeof j : (char *) &j;
5103#endif /* not GC_SAVE_REGISTERS_ON_STACK */
5104#endif /* not HAVE___BUILTIN_UNWIND_INIT */
5105
5106 self->stack_top = end; 5110 self->stack_top = end;
5107 (*func) (arg); 5111 func (arg);
5108
5109 eassert (current_thread == self); 5112 eassert (current_thread == self);
5110} 5113}
5111 5114
@@ -6047,58 +6050,7 @@ See Info node `(elisp)Garbage Collection'. */)
6047 (void) 6050 (void)
6048{ 6051{
6049 void *end; 6052 void *end;
6050 6053 SET_STACK_TOP_ADDRESS (&end);
6051#ifdef HAVE___BUILTIN_UNWIND_INIT
6052 /* Force callee-saved registers and register windows onto the stack.
6053 This is the preferred method if available, obviating the need for
6054 machine dependent methods. */
6055 __builtin_unwind_init ();
6056 end = &end;
6057#else /* not HAVE___BUILTIN_UNWIND_INIT */
6058#ifndef GC_SAVE_REGISTERS_ON_STACK
6059 /* jmp_buf may not be aligned enough on darwin-ppc64 */
6060 union aligned_jmpbuf {
6061 Lisp_Object o;
6062 sys_jmp_buf j;
6063 } j;
6064 volatile bool stack_grows_down_p = (char *) &j > (char *) stack_base;
6065#endif
6066 /* This trick flushes the register windows so that all the state of
6067 the process is contained in the stack. */
6068 /* Fixme: Code in the Boehm GC suggests flushing (with `flushrs') is
6069 needed on ia64 too. See mach_dep.c, where it also says inline
6070 assembler doesn't work with relevant proprietary compilers. */
6071#ifdef __sparc__
6072#if defined (__sparc64__) && defined (__FreeBSD__)
6073 /* FreeBSD does not have a ta 3 handler. */
6074 asm ("flushw");
6075#else
6076 asm ("ta 3");
6077#endif
6078#endif
6079
6080 /* Save registers that we need to see on the stack. We need to see
6081 registers used to hold register variables and registers used to
6082 pass parameters. */
6083#ifdef GC_SAVE_REGISTERS_ON_STACK
6084 GC_SAVE_REGISTERS_ON_STACK (end);
6085#else /* not GC_SAVE_REGISTERS_ON_STACK */
6086
6087#ifndef GC_SETJMP_WORKS /* If it hasn't been checked yet that
6088 setjmp will definitely work, test it
6089 and print a message with the result
6090 of the test. */
6091 if (!setjmp_tested_p)
6092 {
6093 setjmp_tested_p = 1;
6094 test_setjmp ();
6095 }
6096#endif /* GC_SETJMP_WORKS */
6097
6098 sys_setjmp (j.j);
6099 end = stack_grows_down_p ? (char *) &j + sizeof j : (char *) &j;
6100#endif /* not GC_SAVE_REGISTERS_ON_STACK */
6101#endif /* not HAVE___BUILTIN_UNWIND_INIT */
6102 return garbage_collect_1 (end); 6054 return garbage_collect_1 (end);
6103} 6055}
6104 6056
@@ -7408,9 +7360,6 @@ init_alloc_once (void)
7408void 7360void
7409init_alloc (void) 7361init_alloc (void)
7410{ 7362{
7411#if !defined GC_SAVE_REGISTERS_ON_STACK && !defined GC_SETJMP_WORKS
7412 setjmp_tested_p = longjmps_done = 0;
7413#endif
7414 Vgc_elapsed = make_float (0.0); 7363 Vgc_elapsed = make_float (0.0);
7415 gcs_done = 0; 7364 gcs_done = 0;
7416 7365