diff options
| author | Tom Tromey | 2012-08-15 13:01:36 -0600 |
|---|---|---|
| committer | Tom Tromey | 2012-08-15 13:01:36 -0600 |
| commit | 2d525b793f1b0fd2b6f66881310bec8684bceffe (patch) | |
| tree | 932fb8b75974ac4c16ecfc5bc216fe362b0a4d27 /src/alloc.c | |
| parent | 68b32482437e05f0994c4dd0ab5b0c27d39f0f6d (diff) | |
| download | emacs-2d525b793f1b0fd2b6f66881310bec8684bceffe.tar.gz emacs-2d525b793f1b0fd2b6f66881310bec8684bceffe.zip | |
This parameterizes the GC a bit to make it thread-ready.
The basic idea is that whenever a thread "exits lisp" -- that is,
releases the global lock in favor of another thread -- it must save
its stack boundaries in the thread object. This way the boundaries
are always available for marking. This is the purpose of
flush_stack_call_func.
I haven't tested this under all the possible GC configurations.
There is a new FIXME in a spot that i didn't convert.
Arguably all_threads should go in the previous patch.
Diffstat (limited to 'src/alloc.c')
| -rw-r--r-- | src/alloc.c | 78 |
1 files changed, 26 insertions, 52 deletions
diff --git a/src/alloc.c b/src/alloc.c index bdf7b24af04..dfae2d1ef67 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -387,7 +387,6 @@ static struct mem_node mem_z; | |||
| 387 | 387 | ||
| 388 | static struct Lisp_Vector *allocate_vectorlike (ptrdiff_t); | 388 | static struct Lisp_Vector *allocate_vectorlike (ptrdiff_t); |
| 389 | static void lisp_free (void *); | 389 | static void lisp_free (void *); |
| 390 | static void mark_stack (void); | ||
| 391 | static int live_vector_p (struct mem_node *, void *); | 390 | static int live_vector_p (struct mem_node *, void *); |
| 392 | static int live_buffer_p (struct mem_node *, void *); | 391 | static int live_buffer_p (struct mem_node *, void *); |
| 393 | static int live_string_p (struct mem_node *, void *); | 392 | static int live_string_p (struct mem_node *, void *); |
| @@ -4865,8 +4864,27 @@ dump_zombies (void) | |||
| 4865 | would be necessary, each one starting with one byte more offset | 4864 | would be necessary, each one starting with one byte more offset |
| 4866 | from the stack start. */ | 4865 | from the stack start. */ |
| 4867 | 4866 | ||
| 4868 | static void | 4867 | void |
| 4869 | mark_stack (void) | 4868 | mark_stack (char *bottom, char *end) |
| 4869 | { | ||
| 4870 | /* This assumes that the stack is a contiguous region in memory. If | ||
| 4871 | that's not the case, something has to be done here to iterate | ||
| 4872 | over the stack segments. */ | ||
| 4873 | mark_memory (bottom, end); | ||
| 4874 | |||
| 4875 | /* Allow for marking a secondary stack, like the register stack on the | ||
| 4876 | ia64. */ | ||
| 4877 | #ifdef GC_MARK_SECONDARY_STACK | ||
| 4878 | GC_MARK_SECONDARY_STACK (); | ||
| 4879 | #endif | ||
| 4880 | |||
| 4881 | #if GC_MARK_STACK == GC_MARK_STACK_CHECK_GCPROS | ||
| 4882 | check_gcpros (); | ||
| 4883 | #endif | ||
| 4884 | } | ||
| 4885 | |||
| 4886 | void | ||
| 4887 | flush_stack_call_func (void (*func) (void *arg), void *arg) | ||
| 4870 | { | 4888 | { |
| 4871 | void *end; | 4889 | void *end; |
| 4872 | 4890 | ||
| @@ -4922,20 +4940,8 @@ mark_stack (void) | |||
| 4922 | #endif /* not GC_SAVE_REGISTERS_ON_STACK */ | 4940 | #endif /* not GC_SAVE_REGISTERS_ON_STACK */ |
| 4923 | #endif /* not HAVE___BUILTIN_UNWIND_INIT */ | 4941 | #endif /* not HAVE___BUILTIN_UNWIND_INIT */ |
| 4924 | 4942 | ||
| 4925 | /* This assumes that the stack is a contiguous region in memory. If | 4943 | current_thread->stack_top = end; |
| 4926 | that's not the case, something has to be done here to iterate | 4944 | (*func) (arg); |
| 4927 | over the stack segments. */ | ||
| 4928 | mark_memory (stack_bottom, end); | ||
| 4929 | |||
| 4930 | /* Allow for marking a secondary stack, like the register stack on the | ||
| 4931 | ia64. */ | ||
| 4932 | #ifdef GC_MARK_SECONDARY_STACK | ||
| 4933 | GC_MARK_SECONDARY_STACK (); | ||
| 4934 | #endif | ||
| 4935 | |||
| 4936 | #if GC_MARK_STACK == GC_MARK_STACK_CHECK_GCPROS | ||
| 4937 | check_gcpros (); | ||
| 4938 | #endif | ||
| 4939 | } | 4945 | } |
| 4940 | 4946 | ||
| 4941 | #endif /* GC_MARK_STACK != 0 */ | 4947 | #endif /* GC_MARK_STACK != 0 */ |
| @@ -5457,11 +5463,7 @@ See Info node `(elisp)Garbage Collection'. */) | |||
| 5457 | for (i = 0; i < staticidx; i++) | 5463 | for (i = 0; i < staticidx; i++) |
| 5458 | mark_object (*staticvec[i]); | 5464 | mark_object (*staticvec[i]); |
| 5459 | 5465 | ||
| 5460 | for (bind = specpdl; bind != specpdl_ptr; bind++) | 5466 | mark_threads (); |
| 5461 | { | ||
| 5462 | mark_object (bind->symbol); | ||
| 5463 | mark_object (bind->old_value); | ||
| 5464 | } | ||
| 5465 | mark_terminals (); | 5467 | mark_terminals (); |
| 5466 | mark_kboards (); | 5468 | mark_kboards (); |
| 5467 | mark_ttys (); | 5469 | mark_ttys (); |
| @@ -5473,40 +5475,12 @@ See Info node `(elisp)Garbage Collection'. */) | |||
| 5473 | } | 5475 | } |
| 5474 | #endif | 5476 | #endif |
| 5475 | 5477 | ||
| 5476 | #if (GC_MARK_STACK == GC_MAKE_GCPROS_NOOPS \ | ||
| 5477 | || GC_MARK_STACK == GC_MARK_STACK_CHECK_GCPROS) | ||
| 5478 | mark_stack (); | ||
| 5479 | #else | ||
| 5480 | { | ||
| 5481 | register struct gcpro *tail; | ||
| 5482 | for (tail = gcprolist; tail; tail = tail->next) | ||
| 5483 | for (i = 0; i < tail->nvars; i++) | ||
| 5484 | mark_object (tail->var[i]); | ||
| 5485 | } | ||
| 5486 | mark_byte_stack (); | ||
| 5487 | { | ||
| 5488 | struct catchtag *catch; | ||
| 5489 | struct handler *handler; | ||
| 5490 | |||
| 5491 | for (catch = catchlist; catch; catch = catch->next) | ||
| 5492 | { | ||
| 5493 | mark_object (catch->tag); | ||
| 5494 | mark_object (catch->val); | ||
| 5495 | } | ||
| 5496 | for (handler = handlerlist; handler; handler = handler->next) | ||
| 5497 | { | ||
| 5498 | mark_object (handler->handler); | ||
| 5499 | mark_object (handler->var); | ||
| 5500 | } | ||
| 5501 | } | ||
| 5502 | mark_backtrace (); | ||
| 5503 | #endif | ||
| 5504 | |||
| 5505 | #ifdef HAVE_WINDOW_SYSTEM | 5478 | #ifdef HAVE_WINDOW_SYSTEM |
| 5506 | mark_fringe_data (); | 5479 | mark_fringe_data (); |
| 5507 | #endif | 5480 | #endif |
| 5508 | 5481 | ||
| 5509 | #if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES | 5482 | #if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES |
| 5483 | FIXME; | ||
| 5510 | mark_stack (); | 5484 | mark_stack (); |
| 5511 | #endif | 5485 | #endif |
| 5512 | 5486 | ||
| @@ -5556,7 +5530,7 @@ See Info node `(elisp)Garbage Collection'. */) | |||
| 5556 | 5530 | ||
| 5557 | /* Clear the mark bits that we set in certain root slots. */ | 5531 | /* Clear the mark bits that we set in certain root slots. */ |
| 5558 | 5532 | ||
| 5559 | unmark_byte_stack (); | 5533 | unmark_threads (); |
| 5560 | VECTOR_UNMARK (&buffer_defaults); | 5534 | VECTOR_UNMARK (&buffer_defaults); |
| 5561 | VECTOR_UNMARK (&buffer_local_symbols); | 5535 | VECTOR_UNMARK (&buffer_local_symbols); |
| 5562 | 5536 | ||