diff options
| author | Vibhav Pant | 2017-02-05 23:08:53 +0530 |
|---|---|---|
| committer | Vibhav Pant | 2017-02-05 23:08:53 +0530 |
| commit | ad70ca1dad26da79f0a95cc0ec687902ef20fa9b (patch) | |
| tree | 732e8e9ace1fdd7aaf982f0fa5ac6c8e4eb5f7c7 /src/alloc.c | |
| parent | 2db473bda8be72cf3c1e4694d70ce48f60492b0e (diff) | |
| parent | 148100d98319499f0ac6f57b8be08cbd14884a5c (diff) | |
| download | emacs-ad70ca1dad26da79f0a95cc0ec687902ef20fa9b.tar.gz emacs-ad70ca1dad26da79f0a95cc0ec687902ef20fa9b.zip | |
Merge remote-tracking branch 'origin/master' into feature/byte-switch
Diffstat (limited to 'src/alloc.c')
| -rw-r--r-- | src/alloc.c | 215 |
1 files changed, 80 insertions, 135 deletions
diff --git a/src/alloc.c b/src/alloc.c index dd2b688f91e..62f43669f2a 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -2880,7 +2880,7 @@ DEFUN ("make-list", Fmake_list, Smake_list, 2, 2, 0, | |||
| 2880 | for (EMACS_INT size = XFASTINT (length); 0 < size; size--) | 2880 | for (EMACS_INT size = XFASTINT (length); 0 < size; size--) |
| 2881 | { | 2881 | { |
| 2882 | val = Fcons (init, val); | 2882 | val = Fcons (init, val); |
| 2883 | maybe_quit (); | 2883 | rarely_quit (size); |
| 2884 | } | 2884 | } |
| 2885 | 2885 | ||
| 2886 | return val; | 2886 | return val; |
| @@ -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 | ||
| 4893 | static void | ||
| 4894 | test_setjmp (void) | ||
| 4895 | { | ||
| 4896 | } | ||
| 4897 | # else | ||
| 4891 | 4898 | ||
| 4892 | static bool setjmp_tested_p; | 4899 | static bool setjmp_tested_p; |
| 4893 | static int longjmps_done; | 4900 | static int longjmps_done; |
| 4894 | 4901 | ||
| 4895 | #define SETJMP_WILL_LIKELY_WORK "\ | 4902 | # define SETJMP_WILL_LIKELY_WORK "\ |
| 4896 | \n\ | 4903 | \n\ |
| 4897 | Emacs garbage collector has been changed to use conservative stack\n\ | 4904 | Emacs garbage collector has been changed to use conservative stack\n\ |
| 4898 | marking. Emacs has determined that the method it uses to do the\n\ | 4905 | 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\ | |||
| 4905 | Please mail the result to <emacs-devel@gnu.org>.\n\ | 4912 | Please 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\ |
| 4910 | Emacs garbage collector has been changed to use conservative stack\n\ | 4917 | Emacs garbage collector has been changed to use conservative stack\n\ |
| 4911 | marking. Emacs has determined that the default method it uses to do the\n\ | 4918 | marking. 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\ | |||
| 4931 | static void | 4938 | static void |
| 4932 | test_setjmp (void) | 4939 | test_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. */ | ||
| 4985 | typedef 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 | ||
| @@ -5437,7 +5440,8 @@ make_pure_vector (ptrdiff_t len) | |||
| 5437 | /* Copy all contents and parameters of TABLE to a new table allocated | 5440 | /* Copy all contents and parameters of TABLE to a new table allocated |
| 5438 | from pure space, return the purified table. */ | 5441 | from pure space, return the purified table. */ |
| 5439 | static struct Lisp_Hash_Table * | 5442 | static struct Lisp_Hash_Table * |
| 5440 | purecopy_hash_table (struct Lisp_Hash_Table *table) { | 5443 | purecopy_hash_table (struct Lisp_Hash_Table *table) |
| 5444 | { | ||
| 5441 | eassert (NILP (table->weak)); | 5445 | eassert (NILP (table->weak)); |
| 5442 | eassert (!NILP (table->pure)); | 5446 | eassert (!NILP (table->pure)); |
| 5443 | 5447 | ||
| @@ -5480,14 +5484,12 @@ Does not copy symbols. Copies strings without text properties. */) | |||
| 5480 | return purecopy (obj); | 5484 | return purecopy (obj); |
| 5481 | } | 5485 | } |
| 5482 | 5486 | ||
| 5483 | struct pinned_object | 5487 | /* Pinned objects are marked before every GC cycle. */ |
| 5488 | static struct pinned_object | ||
| 5484 | { | 5489 | { |
| 5485 | Lisp_Object object; | 5490 | Lisp_Object object; |
| 5486 | struct pinned_object *next; | 5491 | struct pinned_object *next; |
| 5487 | }; | 5492 | } *pinned_objects; |
| 5488 | |||
| 5489 | /* Pinned objects are marked before every GC cycle. */ | ||
| 5490 | static struct pinned_object *pinned_objects; | ||
| 5491 | 5493 | ||
| 5492 | static Lisp_Object | 5494 | static Lisp_Object |
| 5493 | purecopy (Lisp_Object obj) | 5495 | purecopy (Lisp_Object obj) |
| @@ -5519,13 +5521,13 @@ purecopy (Lisp_Object obj) | |||
| 5519 | else if (HASH_TABLE_P (obj)) | 5521 | else if (HASH_TABLE_P (obj)) |
| 5520 | { | 5522 | { |
| 5521 | struct Lisp_Hash_Table *table = XHASH_TABLE (obj); | 5523 | struct Lisp_Hash_Table *table = XHASH_TABLE (obj); |
| 5522 | /* We cannot purify hash tables which haven't been defined with | 5524 | /* Do not purify hash tables which haven't been defined with |
| 5523 | :purecopy as non-nil or are weak - they aren't guaranteed to | 5525 | :purecopy as non-nil or are weak - they aren't guaranteed to |
| 5524 | not change. */ | 5526 | not change. */ |
| 5525 | if (!NILP (table->weak) || NILP (table->pure)) | 5527 | if (!NILP (table->weak) || NILP (table->pure)) |
| 5526 | { | 5528 | { |
| 5527 | /* Instead, the hash table is added to the list of pinned objects, | 5529 | /* Instead, add the hash table to the list of pinned objects, |
| 5528 | and is marked before GC. */ | 5530 | so that it will be marked during GC. */ |
| 5529 | struct pinned_object *o = xmalloc (sizeof *o); | 5531 | struct pinned_object *o = xmalloc (sizeof *o); |
| 5530 | o->object = obj; | 5532 | o->object = obj; |
| 5531 | o->next = pinned_objects; | 5533 | o->next = pinned_objects; |
| @@ -5755,11 +5757,8 @@ compact_undo_list (Lisp_Object list) | |||
| 5755 | static void | 5757 | static void |
| 5756 | mark_pinned_objects (void) | 5758 | mark_pinned_objects (void) |
| 5757 | { | 5759 | { |
| 5758 | struct pinned_object *pobj; | 5760 | for (struct pinned_object *pobj = pinned_objects; pobj; pobj = pobj->next) |
| 5759 | for (pobj = pinned_objects; pobj; pobj = pobj->next) | 5761 | mark_object (pobj->object); |
| 5760 | { | ||
| 5761 | mark_object (pobj->object); | ||
| 5762 | } | ||
| 5763 | } | 5762 | } |
| 5764 | 5763 | ||
| 5765 | static void | 5764 | static void |
| @@ -6051,58 +6050,7 @@ See Info node `(elisp)Garbage Collection'. */) | |||
| 6051 | (void) | 6050 | (void) |
| 6052 | { | 6051 | { |
| 6053 | void *end; | 6052 | void *end; |
| 6054 | 6053 | SET_STACK_TOP_ADDRESS (&end); | |
| 6055 | #ifdef HAVE___BUILTIN_UNWIND_INIT | ||
| 6056 | /* Force callee-saved registers and register windows onto the stack. | ||
| 6057 | This is the preferred method if available, obviating the need for | ||
| 6058 | machine dependent methods. */ | ||
| 6059 | __builtin_unwind_init (); | ||
| 6060 | end = &end; | ||
| 6061 | #else /* not HAVE___BUILTIN_UNWIND_INIT */ | ||
| 6062 | #ifndef GC_SAVE_REGISTERS_ON_STACK | ||
| 6063 | /* jmp_buf may not be aligned enough on darwin-ppc64 */ | ||
| 6064 | union aligned_jmpbuf { | ||
| 6065 | Lisp_Object o; | ||
| 6066 | sys_jmp_buf j; | ||
| 6067 | } j; | ||
| 6068 | volatile bool stack_grows_down_p = (char *) &j > (char *) stack_base; | ||
| 6069 | #endif | ||
| 6070 | /* This trick flushes the register windows so that all the state of | ||
| 6071 | the process is contained in the stack. */ | ||
| 6072 | /* Fixme: Code in the Boehm GC suggests flushing (with `flushrs') is | ||
| 6073 | needed on ia64 too. See mach_dep.c, where it also says inline | ||
| 6074 | assembler doesn't work with relevant proprietary compilers. */ | ||
| 6075 | #ifdef __sparc__ | ||
| 6076 | #if defined (__sparc64__) && defined (__FreeBSD__) | ||
| 6077 | /* FreeBSD does not have a ta 3 handler. */ | ||
| 6078 | asm ("flushw"); | ||
| 6079 | #else | ||
| 6080 | asm ("ta 3"); | ||
| 6081 | #endif | ||
| 6082 | #endif | ||
| 6083 | |||
| 6084 | /* Save registers that we need to see on the stack. We need to see | ||
| 6085 | registers used to hold register variables and registers used to | ||
| 6086 | pass parameters. */ | ||
| 6087 | #ifdef GC_SAVE_REGISTERS_ON_STACK | ||
| 6088 | GC_SAVE_REGISTERS_ON_STACK (end); | ||
| 6089 | #else /* not GC_SAVE_REGISTERS_ON_STACK */ | ||
| 6090 | |||
| 6091 | #ifndef GC_SETJMP_WORKS /* If it hasn't been checked yet that | ||
| 6092 | setjmp will definitely work, test it | ||
| 6093 | and print a message with the result | ||
| 6094 | of the test. */ | ||
| 6095 | if (!setjmp_tested_p) | ||
| 6096 | { | ||
| 6097 | setjmp_tested_p = 1; | ||
| 6098 | test_setjmp (); | ||
| 6099 | } | ||
| 6100 | #endif /* GC_SETJMP_WORKS */ | ||
| 6101 | |||
| 6102 | sys_setjmp (j.j); | ||
| 6103 | end = stack_grows_down_p ? (char *) &j + sizeof j : (char *) &j; | ||
| 6104 | #endif /* not GC_SAVE_REGISTERS_ON_STACK */ | ||
| 6105 | #endif /* not HAVE___BUILTIN_UNWIND_INIT */ | ||
| 6106 | return garbage_collect_1 (end); | 6054 | return garbage_collect_1 (end); |
| 6107 | } | 6055 | } |
| 6108 | 6056 | ||
| @@ -7412,9 +7360,6 @@ init_alloc_once (void) | |||
| 7412 | void | 7360 | void |
| 7413 | init_alloc (void) | 7361 | init_alloc (void) |
| 7414 | { | 7362 | { |
| 7415 | #if !defined GC_SAVE_REGISTERS_ON_STACK && !defined GC_SETJMP_WORKS | ||
| 7416 | setjmp_tested_p = longjmps_done = 0; | ||
| 7417 | #endif | ||
| 7418 | Vgc_elapsed = make_float (0.0); | 7363 | Vgc_elapsed = make_float (0.0); |
| 7419 | gcs_done = 0; | 7364 | gcs_done = 0; |
| 7420 | 7365 | ||