diff options
| author | Eli Zaretskii | 2016-12-04 19:59:17 +0200 |
|---|---|---|
| committer | Eli Zaretskii | 2016-12-04 19:59:17 +0200 |
| commit | de4624c99ea5bbe38ad5aff7b6461cc5c740d0be (patch) | |
| tree | 1b57de9e769cdb695cb2cecf157b50f7dea9cfe5 /src/alloc.c | |
| parent | a486fabb41cdbaa5813c2687fd4008945297d71d (diff) | |
| parent | e7bde34e939451d87fb42a36195086bdbe48b5e1 (diff) | |
| download | emacs-de4624c99ea5bbe38ad5aff7b6461cc5c740d0be.tar.gz emacs-de4624c99ea5bbe38ad5aff7b6461cc5c740d0be.zip | |
Merge branch 'concurrency'
Conflicts (resolved):
configure.ac
src/Makefile.in
src/alloc.c
src/bytecode.c
src/emacs.c
src/eval.c
src/lisp.h
src/process.c
src/regex.c
src/regex.h
Diffstat (limited to 'src/alloc.c')
| -rw-r--r-- | src/alloc.c | 110 |
1 files changed, 89 insertions, 21 deletions
diff --git a/src/alloc.c b/src/alloc.c index 6eced7bab18..f2b7682b05d 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -438,10 +438,6 @@ struct mem_node | |||
| 438 | enum mem_type type; | 438 | enum mem_type type; |
| 439 | }; | 439 | }; |
| 440 | 440 | ||
| 441 | /* Base address of stack. Set in main. */ | ||
| 442 | |||
| 443 | Lisp_Object *stack_base; | ||
| 444 | |||
| 445 | /* Root of the tree describing allocated Lisp memory. */ | 441 | /* Root of the tree describing allocated Lisp memory. */ |
| 446 | 442 | ||
| 447 | static struct mem_node *mem_root; | 443 | static struct mem_node *mem_root; |
| @@ -3190,8 +3186,7 @@ vector_nbytes (struct Lisp_Vector *v) | |||
| 3190 | } | 3186 | } |
| 3191 | 3187 | ||
| 3192 | /* Release extra resources still in use by VECTOR, which may be any | 3188 | /* Release extra resources still in use by VECTOR, which may be any |
| 3193 | vector-like object. For now, this is used just to free data in | 3189 | vector-like object. */ |
| 3194 | font objects. */ | ||
| 3195 | 3190 | ||
| 3196 | static void | 3191 | static void |
| 3197 | cleanup_vector (struct Lisp_Vector *vector) | 3192 | cleanup_vector (struct Lisp_Vector *vector) |
| @@ -3212,6 +3207,13 @@ cleanup_vector (struct Lisp_Vector *vector) | |||
| 3212 | drv->close ((struct font *) vector); | 3207 | drv->close ((struct font *) vector); |
| 3213 | } | 3208 | } |
| 3214 | } | 3209 | } |
| 3210 | |||
| 3211 | if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_THREAD)) | ||
| 3212 | finalize_one_thread ((struct thread_state *) vector); | ||
| 3213 | else if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_MUTEX)) | ||
| 3214 | finalize_one_mutex ((struct Lisp_Mutex *) vector); | ||
| 3215 | else if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_CONDVAR)) | ||
| 3216 | finalize_one_condvar ((struct Lisp_CondVar *) vector); | ||
| 3215 | } | 3217 | } |
| 3216 | 3218 | ||
| 3217 | /* Reclaim space used by unmarked vectors. */ | 3219 | /* Reclaim space used by unmarked vectors. */ |
| @@ -5047,14 +5049,13 @@ test_setjmp (void) | |||
| 5047 | would be necessary, each one starting with one byte more offset | 5049 | would be necessary, each one starting with one byte more offset |
| 5048 | from the stack start. */ | 5050 | from the stack start. */ |
| 5049 | 5051 | ||
| 5050 | static void | 5052 | void |
| 5051 | mark_stack (void *end) | 5053 | mark_stack (char *bottom, char *end) |
| 5052 | { | 5054 | { |
| 5053 | |||
| 5054 | /* This assumes that the stack is a contiguous region in memory. If | 5055 | /* This assumes that the stack is a contiguous region in memory. If |
| 5055 | that's not the case, something has to be done here to iterate | 5056 | that's not the case, something has to be done here to iterate |
| 5056 | over the stack segments. */ | 5057 | over the stack segments. */ |
| 5057 | mark_memory (stack_base, end); | 5058 | mark_memory (bottom, end); |
| 5058 | 5059 | ||
| 5059 | /* Allow for marking a secondary stack, like the register stack on the | 5060 | /* Allow for marking a secondary stack, like the register stack on the |
| 5060 | ia64. */ | 5061 | ia64. */ |
| @@ -5063,6 +5064,81 @@ mark_stack (void *end) | |||
| 5063 | #endif | 5064 | #endif |
| 5064 | } | 5065 | } |
| 5065 | 5066 | ||
| 5067 | /* This is a trampoline function that flushes registers to the stack, | ||
| 5068 | and then calls FUNC. ARG is passed through to FUNC verbatim. | ||
| 5069 | |||
| 5070 | This function must be called whenever Emacs is about to release the | ||
| 5071 | global interpreter lock. This lets the garbage collector easily | ||
| 5072 | find roots in registers on threads that are not actively running | ||
| 5073 | Lisp. | ||
| 5074 | |||
| 5075 | It is invalid to run any Lisp code or to allocate any GC memory | ||
| 5076 | from FUNC. */ | ||
| 5077 | |||
| 5078 | void | ||
| 5079 | flush_stack_call_func (void (*func) (void *arg), void *arg) | ||
| 5080 | { | ||
| 5081 | void *end; | ||
| 5082 | struct thread_state *self = current_thread; | ||
| 5083 | |||
| 5084 | #ifdef HAVE___BUILTIN_UNWIND_INIT | ||
| 5085 | /* Force callee-saved registers and register windows onto the stack. | ||
| 5086 | This is the preferred method if available, obviating the need for | ||
| 5087 | machine dependent methods. */ | ||
| 5088 | __builtin_unwind_init (); | ||
| 5089 | end = &end; | ||
| 5090 | #else /* not HAVE___BUILTIN_UNWIND_INIT */ | ||
| 5091 | #ifndef GC_SAVE_REGISTERS_ON_STACK | ||
| 5092 | /* jmp_buf may not be aligned enough on darwin-ppc64 */ | ||
| 5093 | union aligned_jmpbuf { | ||
| 5094 | Lisp_Object o; | ||
| 5095 | sys_jmp_buf j; | ||
| 5096 | } j; | ||
| 5097 | volatile bool stack_grows_down_p = (char *) &j > (char *) stack_bottom; | ||
| 5098 | #endif | ||
| 5099 | /* This trick flushes the register windows so that all the state of | ||
| 5100 | the process is contained in the stack. */ | ||
| 5101 | /* Fixme: Code in the Boehm GC suggests flushing (with `flushrs') is | ||
| 5102 | needed on ia64 too. See mach_dep.c, where it also says inline | ||
| 5103 | assembler doesn't work with relevant proprietary compilers. */ | ||
| 5104 | #ifdef __sparc__ | ||
| 5105 | #if defined (__sparc64__) && defined (__FreeBSD__) | ||
| 5106 | /* FreeBSD does not have a ta 3 handler. */ | ||
| 5107 | asm ("flushw"); | ||
| 5108 | #else | ||
| 5109 | asm ("ta 3"); | ||
| 5110 | #endif | ||
| 5111 | #endif | ||
| 5112 | |||
| 5113 | /* Save registers that we need to see on the stack. We need to see | ||
| 5114 | registers used to hold register variables and registers used to | ||
| 5115 | pass parameters. */ | ||
| 5116 | #ifdef GC_SAVE_REGISTERS_ON_STACK | ||
| 5117 | GC_SAVE_REGISTERS_ON_STACK (end); | ||
| 5118 | #else /* not GC_SAVE_REGISTERS_ON_STACK */ | ||
| 5119 | |||
| 5120 | #ifndef GC_SETJMP_WORKS /* If it hasn't been checked yet that | ||
| 5121 | setjmp will definitely work, test it | ||
| 5122 | and print a message with the result | ||
| 5123 | of the test. */ | ||
| 5124 | if (!setjmp_tested_p) | ||
| 5125 | { | ||
| 5126 | setjmp_tested_p = 1; | ||
| 5127 | test_setjmp (); | ||
| 5128 | } | ||
| 5129 | #endif /* GC_SETJMP_WORKS */ | ||
| 5130 | |||
| 5131 | sys_setjmp (j.j); | ||
| 5132 | end = stack_grows_down_p ? (char *) &j + sizeof j : (char *) &j; | ||
| 5133 | #endif /* not GC_SAVE_REGISTERS_ON_STACK */ | ||
| 5134 | #endif /* not HAVE___BUILTIN_UNWIND_INIT */ | ||
| 5135 | |||
| 5136 | self->stack_top = end; | ||
| 5137 | (*func) (arg); | ||
| 5138 | |||
| 5139 | eassert (current_thread == self); | ||
| 5140 | } | ||
| 5141 | |||
| 5066 | static bool | 5142 | static bool |
| 5067 | c_symbol_p (struct Lisp_Symbol *sym) | 5143 | c_symbol_p (struct Lisp_Symbol *sym) |
| 5068 | { | 5144 | { |
| @@ -5768,24 +5844,14 @@ garbage_collect_1 (void *end) | |||
| 5768 | mark_object (*staticvec[i]); | 5844 | mark_object (*staticvec[i]); |
| 5769 | 5845 | ||
| 5770 | mark_pinned_symbols (); | 5846 | mark_pinned_symbols (); |
| 5771 | mark_specpdl (); | ||
| 5772 | mark_terminals (); | 5847 | mark_terminals (); |
| 5773 | mark_kboards (); | 5848 | mark_kboards (); |
| 5849 | mark_threads (); | ||
| 5774 | 5850 | ||
| 5775 | #ifdef USE_GTK | 5851 | #ifdef USE_GTK |
| 5776 | xg_mark_data (); | 5852 | xg_mark_data (); |
| 5777 | #endif | 5853 | #endif |
| 5778 | 5854 | ||
| 5779 | mark_stack (end); | ||
| 5780 | |||
| 5781 | { | ||
| 5782 | struct handler *handler; | ||
| 5783 | for (handler = handlerlist; handler; handler = handler->next) | ||
| 5784 | { | ||
| 5785 | mark_object (handler->tag_or_ch); | ||
| 5786 | mark_object (handler->val); | ||
| 5787 | } | ||
| 5788 | } | ||
| 5789 | #ifdef HAVE_WINDOW_SYSTEM | 5855 | #ifdef HAVE_WINDOW_SYSTEM |
| 5790 | mark_fringe_data (); | 5856 | mark_fringe_data (); |
| 5791 | #endif | 5857 | #endif |
| @@ -5817,6 +5883,8 @@ garbage_collect_1 (void *end) | |||
| 5817 | 5883 | ||
| 5818 | gc_sweep (); | 5884 | gc_sweep (); |
| 5819 | 5885 | ||
| 5886 | unmark_threads (); | ||
| 5887 | |||
| 5820 | /* Clear the mark bits that we set in certain root slots. */ | 5888 | /* Clear the mark bits that we set in certain root slots. */ |
| 5821 | VECTOR_UNMARK (&buffer_defaults); | 5889 | VECTOR_UNMARK (&buffer_defaults); |
| 5822 | VECTOR_UNMARK (&buffer_local_symbols); | 5890 | VECTOR_UNMARK (&buffer_local_symbols); |