aboutsummaryrefslogtreecommitdiffstats
path: root/src/alloc.c
diff options
context:
space:
mode:
authorEli Zaretskii2016-12-04 19:59:17 +0200
committerEli Zaretskii2016-12-04 19:59:17 +0200
commitde4624c99ea5bbe38ad5aff7b6461cc5c740d0be (patch)
tree1b57de9e769cdb695cb2cecf157b50f7dea9cfe5 /src/alloc.c
parenta486fabb41cdbaa5813c2687fd4008945297d71d (diff)
parente7bde34e939451d87fb42a36195086bdbe48b5e1 (diff)
downloademacs-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.c110
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
443Lisp_Object *stack_base;
444
445/* Root of the tree describing allocated Lisp memory. */ 441/* Root of the tree describing allocated Lisp memory. */
446 442
447static struct mem_node *mem_root; 443static 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
3196static void 3191static void
3197cleanup_vector (struct Lisp_Vector *vector) 3192cleanup_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
5050static void 5052void
5051mark_stack (void *end) 5053mark_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
5078void
5079flush_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
5066static bool 5142static bool
5067c_symbol_p (struct Lisp_Symbol *sym) 5143c_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);