aboutsummaryrefslogtreecommitdiffstats
path: root/src/alloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/alloc.c')
-rw-r--r--src/alloc.c147
1 files changed, 90 insertions, 57 deletions
diff --git a/src/alloc.c b/src/alloc.c
index ecea3e8ac7d..712c8f771f7 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -263,23 +263,6 @@ no_sanitize_memcpy (void *dest, void const *src, size_t size)
263 263
264#endif /* MAX_SAVE_STACK > 0 */ 264#endif /* MAX_SAVE_STACK > 0 */
265 265
266static Lisp_Object Qconses;
267static Lisp_Object Qsymbols;
268static Lisp_Object Qmiscs;
269static Lisp_Object Qstrings;
270static Lisp_Object Qvectors;
271static Lisp_Object Qfloats;
272static Lisp_Object Qintervals;
273static Lisp_Object Qbuffers;
274static Lisp_Object Qstring_bytes, Qvector_slots, Qheap;
275static Lisp_Object Qgc_cons_threshold;
276Lisp_Object Qautomatic_gc;
277Lisp_Object Qchar_table_extra_slots;
278
279/* Hook run after GC has finished. */
280
281static Lisp_Object Qpost_gc_hook;
282
283static void mark_terminals (void); 266static void mark_terminals (void);
284static void gc_sweep (void); 267static void gc_sweep (void);
285static Lisp_Object make_pure_vector (ptrdiff_t); 268static Lisp_Object make_pure_vector (ptrdiff_t);
@@ -3410,13 +3393,29 @@ set_symbol_name (Lisp_Object sym, Lisp_Object name)
3410 XSYMBOL (sym)->name = name; 3393 XSYMBOL (sym)->name = name;
3411} 3394}
3412 3395
3396void
3397init_symbol (Lisp_Object val, Lisp_Object name)
3398{
3399 struct Lisp_Symbol *p = XSYMBOL (val);
3400 set_symbol_name (val, name);
3401 set_symbol_plist (val, Qnil);
3402 p->redirect = SYMBOL_PLAINVAL;
3403 SET_SYMBOL_VAL (p, Qunbound);
3404 set_symbol_function (val, Qnil);
3405 set_symbol_next (val, NULL);
3406 p->gcmarkbit = false;
3407 p->interned = SYMBOL_UNINTERNED;
3408 p->constant = 0;
3409 p->declared_special = false;
3410 p->pinned = false;
3411}
3412
3413DEFUN ("make-symbol", Fmake_symbol, Smake_symbol, 1, 1, 0, 3413DEFUN ("make-symbol", Fmake_symbol, Smake_symbol, 1, 1, 0,
3414 doc: /* Return a newly allocated uninterned symbol whose name is NAME. 3414 doc: /* Return a newly allocated uninterned symbol whose name is NAME.
3415Its value is void, and its function definition and property list are nil. */) 3415Its value is void, and its function definition and property list are nil. */)
3416 (Lisp_Object name) 3416 (Lisp_Object name)
3417{ 3417{
3418 register Lisp_Object val; 3418 Lisp_Object val;
3419 register struct Lisp_Symbol *p;
3420 3419
3421 CHECK_STRING (name); 3420 CHECK_STRING (name);
3422 3421
@@ -3444,18 +3443,7 @@ Its value is void, and its function definition and property list are nil. */)
3444 3443
3445 MALLOC_UNBLOCK_INPUT; 3444 MALLOC_UNBLOCK_INPUT;
3446 3445
3447 p = XSYMBOL (val); 3446 init_symbol (val, name);
3448 set_symbol_name (val, name);
3449 set_symbol_plist (val, Qnil);
3450 p->redirect = SYMBOL_PLAINVAL;
3451 SET_SYMBOL_VAL (p, Qunbound);
3452 set_symbol_function (val, Qnil);
3453 set_symbol_next (val, NULL);
3454 p->gcmarkbit = false;
3455 p->interned = SYMBOL_UNINTERNED;
3456 p->constant = 0;
3457 p->declared_special = false;
3458 p->pinned = false;
3459 consing_since_gc += sizeof (struct Lisp_Symbol); 3447 consing_since_gc += sizeof (struct Lisp_Symbol);
3460 symbols_consed++; 3448 symbols_consed++;
3461 total_free_symbols--; 3449 total_free_symbols--;
@@ -4925,6 +4913,14 @@ mark_stack (void *end)
4925 4913
4926#endif /* GC_MARK_STACK != 0 */ 4914#endif /* GC_MARK_STACK != 0 */
4927 4915
4916static bool
4917c_symbol_p (struct Lisp_Symbol *sym)
4918{
4919 char *lispsym_ptr = (char *) lispsym;
4920 char *sym_ptr = (char *) sym;
4921 ptrdiff_t lispsym_offset = sym_ptr - lispsym_ptr;
4922 return 0 <= lispsym_offset && lispsym_offset < sizeof lispsym;
4923}
4928 4924
4929/* Determine whether it is safe to access memory at address P. */ 4925/* Determine whether it is safe to access memory at address P. */
4930static int 4926static int
@@ -4978,6 +4974,9 @@ valid_lisp_object_p (Lisp_Object obj)
4978 if (PURE_POINTER_P (p)) 4974 if (PURE_POINTER_P (p))
4979 return 1; 4975 return 1;
4980 4976
4977 if (SYMBOLP (obj) && c_symbol_p (p))
4978 return ((char *) p - (char *) lispsym) % sizeof lispsym[0] == 0;
4979
4981 if (p == &buffer_defaults || p == &buffer_local_symbols) 4980 if (p == &buffer_defaults || p == &buffer_local_symbols)
4982 return 2; 4981 return 2;
4983 4982
@@ -5343,7 +5342,7 @@ purecopy (Lisp_Object obj)
5343 } 5342 }
5344 else if (SYMBOLP (obj)) 5343 else if (SYMBOLP (obj))
5345 { 5344 {
5346 if (!XSYMBOL (obj)->pinned) 5345 if (!XSYMBOL (obj)->pinned && !c_symbol_p (XSYMBOL (obj)))
5347 { /* We can't purify them, but they appear in many pure objects. 5346 { /* We can't purify them, but they appear in many pure objects.
5348 Mark them as `pinned' so we know to mark them at every GC cycle. */ 5347 Mark them as `pinned' so we know to mark them at every GC cycle. */
5349 XSYMBOL (obj)->pinned = true; 5348 XSYMBOL (obj)->pinned = true;
@@ -5532,7 +5531,7 @@ mark_pinned_symbols (void)
5532 union aligned_Lisp_Symbol *sym = sblk->symbols, *end = sym + lim; 5531 union aligned_Lisp_Symbol *sym = sblk->symbols, *end = sym + lim;
5533 for (; sym < end; ++sym) 5532 for (; sym < end; ++sym)
5534 if (sym->s.pinned) 5533 if (sym->s.pinned)
5535 mark_object (make_lisp_ptr (&sym->s, Lisp_Symbol)); 5534 mark_object (make_lisp_symbol (&sym->s));
5536 5535
5537 lim = SYMBOL_BLOCK_SIZE; 5536 lim = SYMBOL_BLOCK_SIZE;
5538 } 5537 }
@@ -5566,7 +5565,7 @@ garbage_collect_1 (void *end)
5566 return Qnil; 5565 return Qnil;
5567 5566
5568 /* Record this function, so it appears on the profiler's backtraces. */ 5567 /* Record this function, so it appears on the profiler's backtraces. */
5569 record_in_backtrace (Qautomatic_gc, &Qnil, 0); 5568 record_in_backtrace (Qautomatic_gc, 0, 0);
5570 5569
5571 check_cons_list (); 5570 check_cons_list ();
5572 5571
@@ -5630,6 +5629,9 @@ garbage_collect_1 (void *end)
5630 mark_buffer (&buffer_defaults); 5629 mark_buffer (&buffer_defaults);
5631 mark_buffer (&buffer_local_symbols); 5630 mark_buffer (&buffer_local_symbols);
5632 5631
5632 for (i = 0; i < ARRAYELTS (lispsym); i++)
5633 mark_object (make_lisp_symbol (&lispsym[i]));
5634
5633 for (i = 0; i < staticidx; i++) 5635 for (i = 0; i < staticidx; i++)
5634 mark_object (*staticvec[i]); 5636 mark_object (*staticvec[i]);
5635 5637
@@ -6193,17 +6195,28 @@ mark_object (Lisp_Object arg)
6193 emacs_abort (); \ 6195 emacs_abort (); \
6194 } while (0) 6196 } while (0)
6195 6197
6196 /* Check both of the above conditions. */ 6198 /* Check both of the above conditions, for non-symbols. */
6197#define CHECK_ALLOCATED_AND_LIVE(LIVEP) \ 6199#define CHECK_ALLOCATED_AND_LIVE(LIVEP) \
6198 do { \ 6200 do { \
6199 CHECK_ALLOCATED (); \ 6201 CHECK_ALLOCATED (); \
6200 CHECK_LIVE (LIVEP); \ 6202 CHECK_LIVE (LIVEP); \
6201 } while (0) \ 6203 } while (0) \
6202 6204
6205 /* Check both of the above conditions, for symbols. */
6206#define CHECK_ALLOCATED_AND_LIVE_SYMBOL() \
6207 do { \
6208 if (!c_symbol_p (ptr)) \
6209 { \
6210 CHECK_ALLOCATED (); \
6211 CHECK_LIVE (live_symbol_p); \
6212 } \
6213 } while (0) \
6214
6203#else /* not GC_CHECK_MARKED_OBJECTS */ 6215#else /* not GC_CHECK_MARKED_OBJECTS */
6204 6216
6205#define CHECK_LIVE(LIVEP) ((void) 0) 6217#define CHECK_LIVE(LIVEP) ((void) 0)
6206#define CHECK_ALLOCATED_AND_LIVE(LIVEP) ((void) 0) 6218#define CHECK_ALLOCATED_AND_LIVE(LIVEP) ((void) 0)
6219#define CHECK_ALLOCATED_AND_LIVE_SYMBOL() ((void) 0)
6207 6220
6208#endif /* not GC_CHECK_MARKED_OBJECTS */ 6221#endif /* not GC_CHECK_MARKED_OBJECTS */
6209 6222
@@ -6363,7 +6376,7 @@ mark_object (Lisp_Object arg)
6363 nextsym: 6376 nextsym:
6364 if (ptr->gcmarkbit) 6377 if (ptr->gcmarkbit)
6365 break; 6378 break;
6366 CHECK_ALLOCATED_AND_LIVE (live_symbol_p); 6379 CHECK_ALLOCATED_AND_LIVE_SYMBOL ();
6367 ptr->gcmarkbit = 1; 6380 ptr->gcmarkbit = 1;
6368 /* Attempt to catch bogus objects. */ 6381 /* Attempt to catch bogus objects. */
6369 eassert (valid_lisp_object_p (ptr->function)); 6382 eassert (valid_lisp_object_p (ptr->function));
@@ -6720,13 +6733,16 @@ NO_INLINE /* For better stack traces */
6720static void 6733static void
6721sweep_symbols (void) 6734sweep_symbols (void)
6722{ 6735{
6723 register struct symbol_block *sblk; 6736 struct symbol_block *sblk;
6724 struct symbol_block **sprev = &symbol_block; 6737 struct symbol_block **sprev = &symbol_block;
6725 register int lim = symbol_block_index; 6738 int lim = symbol_block_index;
6726 EMACS_INT num_free = 0, num_used = 0; 6739 EMACS_INT num_free = 0, num_used = ARRAYELTS (lispsym);
6727 6740
6728 symbol_free_list = NULL; 6741 symbol_free_list = NULL;
6729 6742
6743 for (int i = 0; i < ARRAYELTS (lispsym); i++)
6744 lispsym[i].gcmarkbit = 0;
6745
6730 for (sblk = symbol_block; sblk; sblk = *sprev) 6746 for (sblk = symbol_block; sblk; sblk = *sprev)
6731 { 6747 {
6732 int this_free = 0; 6748 int this_free = 0;
@@ -6974,6 +6990,21 @@ Frames, windows, buffers, and subprocesses count as vectors
6974 bounded_number (strings_consed)); 6990 bounded_number (strings_consed));
6975} 6991}
6976 6992
6993static bool
6994symbol_uses_obj (Lisp_Object symbol, Lisp_Object obj)
6995{
6996 struct Lisp_Symbol *sym = XSYMBOL (symbol);
6997 Lisp_Object val = find_symbol_value (symbol);
6998 return (EQ (val, obj)
6999 || EQ (sym->function, obj)
7000 || (!NILP (sym->function)
7001 && COMPILEDP (sym->function)
7002 && EQ (AREF (sym->function, COMPILED_BYTECODE), obj))
7003 || (!NILP (val)
7004 && COMPILEDP (val)
7005 && EQ (AREF (val, COMPILED_BYTECODE), obj)));
7006}
7007
6977/* Find at most FIND_MAX symbols which have OBJ as their value or 7008/* Find at most FIND_MAX symbols which have OBJ as their value or
6978 function. This is used in gdbinit's `xwhichsymbols' command. */ 7009 function. This is used in gdbinit's `xwhichsymbols' command. */
6979 7010
@@ -6986,6 +7017,17 @@ which_symbols (Lisp_Object obj, EMACS_INT find_max)
6986 7017
6987 if (! DEADP (obj)) 7018 if (! DEADP (obj))
6988 { 7019 {
7020 for (int i = 0; i < ARRAYELTS (lispsym); i++)
7021 {
7022 Lisp_Object sym = make_lisp_symbol (&lispsym[i]);
7023 if (symbol_uses_obj (sym, obj))
7024 {
7025 found = Fcons (sym, found);
7026 if (--find_max == 0)
7027 goto out;
7028 }
7029 }
7030
6989 for (sblk = symbol_block; sblk; sblk = sblk->next) 7031 for (sblk = symbol_block; sblk; sblk = sblk->next)
6990 { 7032 {
6991 union aligned_Lisp_Symbol *aligned_sym = sblk->symbols; 7033 union aligned_Lisp_Symbol *aligned_sym = sblk->symbols;
@@ -6993,25 +7035,13 @@ which_symbols (Lisp_Object obj, EMACS_INT find_max)
6993 7035
6994 for (bn = 0; bn < SYMBOL_BLOCK_SIZE; bn++, aligned_sym++) 7036 for (bn = 0; bn < SYMBOL_BLOCK_SIZE; bn++, aligned_sym++)
6995 { 7037 {
6996 struct Lisp_Symbol *sym = &aligned_sym->s;
6997 Lisp_Object val;
6998 Lisp_Object tem;
6999
7000 if (sblk == symbol_block && bn >= symbol_block_index) 7038 if (sblk == symbol_block && bn >= symbol_block_index)
7001 break; 7039 break;
7002 7040
7003 XSETSYMBOL (tem, sym); 7041 Lisp_Object sym = make_lisp_symbol (&aligned_sym->s);
7004 val = find_symbol_value (tem); 7042 if (symbol_uses_obj (sym, obj))
7005 if (EQ (val, obj)
7006 || EQ (sym->function, obj)
7007 || (!NILP (sym->function)
7008 && COMPILEDP (sym->function)
7009 && EQ (AREF (sym->function, COMPILED_BYTECODE), obj))
7010 || (!NILP (val)
7011 && COMPILEDP (val)
7012 && EQ (AREF (val, COMPILED_BYTECODE), obj)))
7013 { 7043 {
7014 found = Fcons (tem, found); 7044 found = Fcons (sym, found);
7015 if (--find_max == 0) 7045 if (--find_max == 0)
7016 goto out; 7046 goto out;
7017 } 7047 }
@@ -7154,7 +7184,9 @@ verify_alloca (void)
7154void 7184void
7155init_alloc_once (void) 7185init_alloc_once (void)
7156{ 7186{
7157 /* Used to do Vpurify_flag = Qt here, but Qt isn't set up yet! */ 7187 /* Even though Qt's contents are not set up, its address is known. */
7188 Vpurify_flag = Qt;
7189
7158 purebeg = PUREBEG; 7190 purebeg = PUREBEG;
7159 pure_size = PURESIZE; 7191 pure_size = PURESIZE;
7160 7192
@@ -7230,6 +7262,7 @@ If this portion is smaller than `gc-cons-threshold', this is ignored. */);
7230 7262
7231 DEFVAR_INT ("symbols-consed", symbols_consed, 7263 DEFVAR_INT ("symbols-consed", symbols_consed,
7232 doc: /* Number of symbols that have been consed so far. */); 7264 doc: /* Number of symbols that have been consed so far. */);
7265 symbols_consed += ARRAYELTS (lispsym);
7233 7266
7234 DEFVAR_INT ("string-chars-consed", string_chars_consed, 7267 DEFVAR_INT ("string-chars-consed", string_chars_consed,
7235 doc: /* Number of string characters that have been consed so far. */); 7268 doc: /* Number of string characters that have been consed so far. */);