aboutsummaryrefslogtreecommitdiffstats
path: root/src/alloc.c
diff options
context:
space:
mode:
authorTom Tromey2012-08-15 13:01:36 -0600
committerTom Tromey2012-08-15 13:01:36 -0600
commit2d525b793f1b0fd2b6f66881310bec8684bceffe (patch)
tree932fb8b75974ac4c16ecfc5bc216fe362b0a4d27 /src/alloc.c
parent68b32482437e05f0994c4dd0ab5b0c27d39f0f6d (diff)
downloademacs-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.c78
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
388static struct Lisp_Vector *allocate_vectorlike (ptrdiff_t); 388static struct Lisp_Vector *allocate_vectorlike (ptrdiff_t);
389static void lisp_free (void *); 389static void lisp_free (void *);
390static void mark_stack (void);
391static int live_vector_p (struct mem_node *, void *); 390static int live_vector_p (struct mem_node *, void *);
392static int live_buffer_p (struct mem_node *, void *); 391static int live_buffer_p (struct mem_node *, void *);
393static int live_string_p (struct mem_node *, void *); 392static 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
4868static void 4867void
4869mark_stack (void) 4868mark_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
4886void
4887flush_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