diff options
Diffstat (limited to 'src/alloc.c')
| -rw-r--r-- | src/alloc.c | 274 |
1 files changed, 35 insertions, 239 deletions
diff --git a/src/alloc.c b/src/alloc.c index 522547661a5..62d82664ac6 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -34,7 +34,6 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 34 | #include "bignum.h" | 34 | #include "bignum.h" |
| 35 | #include "dispextern.h" | 35 | #include "dispextern.h" |
| 36 | #include "intervals.h" | 36 | #include "intervals.h" |
| 37 | #include "puresize.h" | ||
| 38 | #include "sheap.h" | 37 | #include "sheap.h" |
| 39 | #include "sysstdio.h" | 38 | #include "sysstdio.h" |
| 40 | #include "systime.h" | 39 | #include "systime.h" |
| @@ -334,33 +333,6 @@ static char *spare_memory[7]; | |||
| 334 | 333 | ||
| 335 | #define SPARE_MEMORY (1 << 14) | 334 | #define SPARE_MEMORY (1 << 14) |
| 336 | 335 | ||
| 337 | /* Initialize it to a nonzero value to force it into data space | ||
| 338 | (rather than bss space). That way unexec will remap it into text | ||
| 339 | space (pure), on some systems. We have not implemented the | ||
| 340 | remapping on more recent systems because this is less important | ||
| 341 | nowadays than in the days of small memories and timesharing. */ | ||
| 342 | |||
| 343 | EMACS_INT pure[(PURESIZE + sizeof (EMACS_INT) - 1) / sizeof (EMACS_INT)] = {1,}; | ||
| 344 | #define PUREBEG (char *) pure | ||
| 345 | |||
| 346 | /* Pointer to the pure area, and its size. */ | ||
| 347 | |||
| 348 | static char *purebeg; | ||
| 349 | static ptrdiff_t pure_size; | ||
| 350 | |||
| 351 | /* Number of bytes of pure storage used before pure storage overflowed. | ||
| 352 | If this is non-zero, this implies that an overflow occurred. */ | ||
| 353 | |||
| 354 | static ptrdiff_t pure_bytes_used_before_overflow; | ||
| 355 | |||
| 356 | /* Index in pure at which next pure Lisp object will be allocated.. */ | ||
| 357 | |||
| 358 | static ptrdiff_t pure_bytes_used_lisp; | ||
| 359 | |||
| 360 | /* Number of bytes allocated for non-Lisp objects in pure storage. */ | ||
| 361 | |||
| 362 | static ptrdiff_t pure_bytes_used_non_lisp; | ||
| 363 | |||
| 364 | /* If positive, garbage collection is inhibited. Otherwise, zero. */ | 336 | /* If positive, garbage collection is inhibited. Otherwise, zero. */ |
| 365 | 337 | ||
| 366 | static intptr_t garbage_collection_inhibited; | 338 | static intptr_t garbage_collection_inhibited; |
| @@ -561,16 +533,6 @@ Lisp_Object const *staticvec[NSTATICS] | |||
| 561 | 533 | ||
| 562 | int staticidx; | 534 | int staticidx; |
| 563 | 535 | ||
| 564 | static void *pure_alloc (size_t, int); | ||
| 565 | |||
| 566 | /* Return PTR rounded up to the next multiple of ALIGNMENT. */ | ||
| 567 | |||
| 568 | static void * | ||
| 569 | pointer_align (void *ptr, int alignment) | ||
| 570 | { | ||
| 571 | return (void *) ROUNDUP ((uintptr_t) ptr, alignment); | ||
| 572 | } | ||
| 573 | |||
| 574 | /* Extract the pointer hidden within O. */ | 536 | /* Extract the pointer hidden within O. */ |
| 575 | 537 | ||
| 576 | static ATTRIBUTE_NO_SANITIZE_UNDEFINED void * | 538 | static ATTRIBUTE_NO_SANITIZE_UNDEFINED void * |
| @@ -1152,6 +1114,16 @@ struct ablocks | |||
| 1152 | (1 & (intptr_t) ABLOCKS_BUSY (abase) ? abase : ((void **) (abase))[-1]) | 1114 | (1 & (intptr_t) ABLOCKS_BUSY (abase) ? abase : ((void **) (abase))[-1]) |
| 1153 | #endif | 1115 | #endif |
| 1154 | 1116 | ||
| 1117 | /* Return PTR rounded up to the next multiple of ALIGNMENT. */ | ||
| 1118 | |||
| 1119 | #ifndef USE_ALIGNED_ALLOC | ||
| 1120 | static void * | ||
| 1121 | pointer_align (void *ptr, int alignment) | ||
| 1122 | { | ||
| 1123 | return (void *) ROUNDUP ((uintptr_t) ptr, alignment); | ||
| 1124 | } | ||
| 1125 | #endif | ||
| 1126 | |||
| 1155 | /* The list of free ablock. */ | 1127 | /* The list of free ablock. */ |
| 1156 | static struct ablock *free_ablock; | 1128 | static struct ablock *free_ablock; |
| 1157 | 1129 | ||
| @@ -1714,7 +1686,7 @@ string_bytes (struct Lisp_String *s) | |||
| 1714 | ptrdiff_t nbytes = | 1686 | ptrdiff_t nbytes = |
| 1715 | (s->u.s.size_byte < 0 ? s->u.s.size & ~ARRAY_MARK_FLAG : s->u.s.size_byte); | 1687 | (s->u.s.size_byte < 0 ? s->u.s.size & ~ARRAY_MARK_FLAG : s->u.s.size_byte); |
| 1716 | 1688 | ||
| 1717 | if (!PURE_P (s) && !pdumper_object_p (s) && s->u.s.data | 1689 | if (!pdumper_object_p (s) && s->u.s.data |
| 1718 | && nbytes != SDATA_NBYTES (SDATA_OF_STRING (s))) | 1690 | && nbytes != SDATA_NBYTES (SDATA_OF_STRING (s))) |
| 1719 | emacs_abort (); | 1691 | emacs_abort (); |
| 1720 | return nbytes; | 1692 | return nbytes; |
| @@ -2529,7 +2501,7 @@ pin_string (Lisp_Object string) | |||
| 2529 | unsigned char *data = s->u.s.data; | 2501 | unsigned char *data = s->u.s.data; |
| 2530 | 2502 | ||
| 2531 | if (!(size > LARGE_STRING_BYTES | 2503 | if (!(size > LARGE_STRING_BYTES |
| 2532 | || PURE_P (data) || pdumper_object_p (data) | 2504 | || pdumper_object_p (data) |
| 2533 | || s->u.s.size_byte == -3)) | 2505 | || s->u.s.size_byte == -3)) |
| 2534 | { | 2506 | { |
| 2535 | eassert (s->u.s.size_byte == -1); | 2507 | eassert (s->u.s.size_byte == -1); |
| @@ -2789,17 +2761,16 @@ list5 (Lisp_Object arg1, Lisp_Object arg2, Lisp_Object arg3, Lisp_Object arg4, | |||
| 2789 | } | 2761 | } |
| 2790 | 2762 | ||
| 2791 | /* Make a list of COUNT Lisp_Objects, where ARG is the first one. | 2763 | /* Make a list of COUNT Lisp_Objects, where ARG is the first one. |
| 2792 | Use CONS to construct the pairs. AP has any remaining args. */ | 2764 | AP has any remaining args. */ |
| 2793 | static Lisp_Object | 2765 | static Lisp_Object |
| 2794 | cons_listn (ptrdiff_t count, Lisp_Object arg, | 2766 | cons_listn (ptrdiff_t count, Lisp_Object arg, va_list ap) |
| 2795 | Lisp_Object (*cons) (Lisp_Object, Lisp_Object), va_list ap) | ||
| 2796 | { | 2767 | { |
| 2797 | eassume (0 < count); | 2768 | eassume (0 < count); |
| 2798 | Lisp_Object val = cons (arg, Qnil); | 2769 | Lisp_Object val = Fcons (arg, Qnil); |
| 2799 | Lisp_Object tail = val; | 2770 | Lisp_Object tail = val; |
| 2800 | for (ptrdiff_t i = 1; i < count; i++) | 2771 | for (ptrdiff_t i = 1; i < count; i++) |
| 2801 | { | 2772 | { |
| 2802 | Lisp_Object elem = cons (va_arg (ap, Lisp_Object), Qnil); | 2773 | Lisp_Object elem = Fcons (va_arg (ap, Lisp_Object), Qnil); |
| 2803 | XSETCDR (tail, elem); | 2774 | XSETCDR (tail, elem); |
| 2804 | tail = elem; | 2775 | tail = elem; |
| 2805 | } | 2776 | } |
| @@ -2812,18 +2783,7 @@ listn (ptrdiff_t count, Lisp_Object arg1, ...) | |||
| 2812 | { | 2783 | { |
| 2813 | va_list ap; | 2784 | va_list ap; |
| 2814 | va_start (ap, arg1); | 2785 | va_start (ap, arg1); |
| 2815 | Lisp_Object val = cons_listn (count, arg1, Fcons, ap); | 2786 | Lisp_Object val = cons_listn (count, arg1, ap); |
| 2816 | va_end (ap); | ||
| 2817 | return val; | ||
| 2818 | } | ||
| 2819 | |||
| 2820 | /* Make a pure list of COUNT Lisp_Objects, where ARG1 is the first one. */ | ||
| 2821 | Lisp_Object | ||
| 2822 | pure_listn (ptrdiff_t count, Lisp_Object arg1, ...) | ||
| 2823 | { | ||
| 2824 | va_list ap; | ||
| 2825 | va_start (ap, arg1); | ||
| 2826 | Lisp_Object val = cons_listn (count, arg1, pure_cons, ap); | ||
| 2827 | va_end (ap); | 2787 | va_end (ap); |
| 2828 | return val; | 2788 | return val; |
| 2829 | } | 2789 | } |
| @@ -2989,7 +2949,7 @@ static struct Lisp_Vector *vector_free_lists[VECTOR_MAX_FREE_LIST_INDEX]; | |||
| 2989 | 2949 | ||
| 2990 | static struct large_vector *large_vectors; | 2950 | static struct large_vector *large_vectors; |
| 2991 | 2951 | ||
| 2992 | /* The only vector with 0 slots, allocated from pure space. */ | 2952 | /* The only vector with 0 slots. */ |
| 2993 | 2953 | ||
| 2994 | Lisp_Object zero_vector; | 2954 | Lisp_Object zero_vector; |
| 2995 | 2955 | ||
| @@ -3628,13 +3588,6 @@ struct symbol_block | |||
| 3628 | 3588 | ||
| 3629 | static struct symbol_block *symbol_block; | 3589 | static struct symbol_block *symbol_block; |
| 3630 | static int symbol_block_index = SYMBOL_BLOCK_SIZE; | 3590 | static int symbol_block_index = SYMBOL_BLOCK_SIZE; |
| 3631 | /* Pointer to the first symbol_block that contains pinned symbols. | ||
| 3632 | Tests for 24.4 showed that at dump-time, Emacs contains about 15K symbols, | ||
| 3633 | 10K of which are pinned (and all but 250 of them are interned in obarray), | ||
| 3634 | whereas a "typical session" has in the order of 30K symbols. | ||
| 3635 | `symbol_block_pinned' lets mark_pinned_symbols scan only 15K symbols rather | ||
| 3636 | than 30K to find the 10K symbols we need to mark. */ | ||
| 3637 | static struct symbol_block *symbol_block_pinned; | ||
| 3638 | 3591 | ||
| 3639 | /* List of free symbols. */ | 3592 | /* List of free symbols. */ |
| 3640 | 3593 | ||
| @@ -3660,7 +3613,6 @@ init_symbol (Lisp_Object val, Lisp_Object name) | |||
| 3660 | p->u.s.interned = SYMBOL_UNINTERNED; | 3613 | p->u.s.interned = SYMBOL_UNINTERNED; |
| 3661 | p->u.s.trapped_write = SYMBOL_UNTRAPPED_WRITE; | 3614 | p->u.s.trapped_write = SYMBOL_UNTRAPPED_WRITE; |
| 3662 | p->u.s.declared_special = false; | 3615 | p->u.s.declared_special = false; |
| 3663 | p->u.s.pinned = false; | ||
| 3664 | } | 3616 | } |
| 3665 | 3617 | ||
| 3666 | DEFUN ("make-symbol", Fmake_symbol, Smake_symbol, 1, 1, 0, | 3618 | DEFUN ("make-symbol", Fmake_symbol, Smake_symbol, 1, 1, 0, |
| @@ -5268,8 +5220,6 @@ valid_lisp_object_p (Lisp_Object obj) | |||
| 5268 | return 1; | 5220 | return 1; |
| 5269 | 5221 | ||
| 5270 | void *p = XPNTR (obj); | 5222 | void *p = XPNTR (obj); |
| 5271 | if (PURE_P (p)) | ||
| 5272 | return 1; | ||
| 5273 | 5223 | ||
| 5274 | if (BARE_SYMBOL_P (obj) && c_symbol_p (p)) | 5224 | if (BARE_SYMBOL_P (obj) && c_symbol_p (p)) |
| 5275 | return ((char *) p - (char *) lispsym) % sizeof lispsym[0] == 0; | 5225 | return ((char *) p - (char *) lispsym) % sizeof lispsym[0] == 0; |
| @@ -5325,121 +5275,8 @@ valid_lisp_object_p (Lisp_Object obj) | |||
| 5325 | return 0; | 5275 | return 0; |
| 5326 | } | 5276 | } |
| 5327 | 5277 | ||
| 5328 | /*********************************************************************** | ||
| 5329 | Pure Storage Management | ||
| 5330 | ***********************************************************************/ | ||
| 5331 | |||
| 5332 | /* Allocate room for SIZE bytes from pure Lisp storage and return a | ||
| 5333 | pointer to it. TYPE is the Lisp type for which the memory is | ||
| 5334 | allocated. TYPE < 0 means it's not used for a Lisp object, | ||
| 5335 | and that the result should have an alignment of -TYPE. | ||
| 5336 | |||
| 5337 | The bytes are initially zero. | ||
| 5338 | |||
| 5339 | If pure space is exhausted, allocate space from the heap. This is | ||
| 5340 | merely an expedient to let Emacs warn that pure space was exhausted | ||
| 5341 | and that Emacs should be rebuilt with a larger pure space. */ | ||
| 5342 | |||
| 5343 | static void * | ||
| 5344 | pure_alloc (size_t size, int type) | ||
| 5345 | { | ||
| 5346 | void *result; | ||
| 5347 | |||
| 5348 | again: | ||
| 5349 | if (type >= 0) | ||
| 5350 | { | ||
| 5351 | /* Allocate space for a Lisp object from the beginning of the free | ||
| 5352 | space with taking account of alignment. */ | ||
| 5353 | result = pointer_align (purebeg + pure_bytes_used_lisp, LISP_ALIGNMENT); | ||
| 5354 | pure_bytes_used_lisp = ((char *)result - (char *)purebeg) + size; | ||
| 5355 | } | ||
| 5356 | else | ||
| 5357 | { | ||
| 5358 | /* Allocate space for a non-Lisp object from the end of the free | ||
| 5359 | space. */ | ||
| 5360 | ptrdiff_t unaligned_non_lisp = pure_bytes_used_non_lisp + size; | ||
| 5361 | char *unaligned = purebeg + pure_size - unaligned_non_lisp; | ||
| 5362 | int decr = (intptr_t) unaligned & (-1 - type); | ||
| 5363 | pure_bytes_used_non_lisp = unaligned_non_lisp + decr; | ||
| 5364 | result = unaligned - decr; | ||
| 5365 | } | ||
| 5366 | pure_bytes_used = pure_bytes_used_lisp + pure_bytes_used_non_lisp; | ||
| 5367 | |||
| 5368 | if (pure_bytes_used <= pure_size) | ||
| 5369 | return result; | ||
| 5370 | |||
| 5371 | /* Don't allocate a large amount here, | ||
| 5372 | because it might get mmap'd and then its address | ||
| 5373 | might not be usable. */ | ||
| 5374 | int small_amount = 10000; | ||
| 5375 | eassert (size <= small_amount - LISP_ALIGNMENT); | ||
| 5376 | purebeg = xzalloc (small_amount); | ||
| 5377 | pure_size = small_amount; | ||
| 5378 | pure_bytes_used_before_overflow += pure_bytes_used - size; | ||
| 5379 | pure_bytes_used = 0; | ||
| 5380 | pure_bytes_used_lisp = pure_bytes_used_non_lisp = 0; | ||
| 5381 | |||
| 5382 | /* Can't GC if pure storage overflowed because we can't determine | ||
| 5383 | if something is a pure object or not. */ | ||
| 5384 | garbage_collection_inhibited++; | ||
| 5385 | goto again; | ||
| 5386 | } | ||
| 5387 | |||
| 5388 | |||
| 5389 | #ifdef HAVE_UNEXEC | ||
| 5390 | |||
| 5391 | /* Print a warning if PURESIZE is too small. */ | ||
| 5392 | |||
| 5393 | void | ||
| 5394 | check_pure_size (void) | ||
| 5395 | { | ||
| 5396 | if (pure_bytes_used_before_overflow) | ||
| 5397 | message (("emacs:0:Pure Lisp storage overflow (approx. %"pI"d" | ||
| 5398 | " bytes needed)"), | ||
| 5399 | pure_bytes_used + pure_bytes_used_before_overflow); | ||
| 5400 | } | ||
| 5401 | #endif | ||
| 5402 | |||
| 5403 | |||
| 5404 | /* Return a string allocated in pure space. DATA is a buffer holding | ||
| 5405 | NCHARS characters, and NBYTES bytes of string data. MULTIBYTE | ||
| 5406 | means make the result string multibyte. | ||
| 5407 | |||
| 5408 | Must get an error if pure storage is full, since if it cannot hold | ||
| 5409 | a large string it may be able to hold conses that point to that | ||
| 5410 | string; then the string is not protected from gc. */ | ||
| 5411 | |||
| 5412 | Lisp_Object | ||
| 5413 | make_pure_string (const char *data, | ||
| 5414 | ptrdiff_t nchars, ptrdiff_t nbytes, bool multibyte) | ||
| 5415 | { | ||
| 5416 | if (multibyte) | ||
| 5417 | return make_multibyte_string (data, nchars, nbytes); | ||
| 5418 | else | ||
| 5419 | return make_unibyte_string (data, nchars); | ||
| 5420 | } | ||
| 5421 | |||
| 5422 | /* Return a string allocated in pure space. Do not | ||
| 5423 | allocate the string data, just point to DATA. */ | ||
| 5424 | |||
| 5425 | Lisp_Object | ||
| 5426 | make_pure_c_string (const char *data, ptrdiff_t nchars) | ||
| 5427 | { | ||
| 5428 | return make_unibyte_string (data, nchars); | ||
| 5429 | } | ||
| 5430 | |||
| 5431 | static Lisp_Object purecopy (Lisp_Object obj); | 5278 | static Lisp_Object purecopy (Lisp_Object obj); |
| 5432 | 5279 | ||
| 5433 | /* Return a cons allocated from pure space. Give it pure copies | ||
| 5434 | of CAR as car and CDR as cdr. */ | ||
| 5435 | |||
| 5436 | Lisp_Object | ||
| 5437 | pure_cons (Lisp_Object car, Lisp_Object cdr) | ||
| 5438 | { | ||
| 5439 | return Fcons (car, cdr); | ||
| 5440 | } | ||
| 5441 | |||
| 5442 | |||
| 5443 | DEFUN ("purecopy", Fpurecopy, Spurecopy, 1, 1, 0, | 5280 | DEFUN ("purecopy", Fpurecopy, Spurecopy, 1, 1, 0, |
| 5444 | doc: /* Make a copy of object OBJ in pure storage. | 5281 | doc: /* Make a copy of object OBJ in pure storage. |
| 5445 | Recursively copies contents of vectors and cons cells. | 5282 | Recursively copies contents of vectors and cons cells. |
| @@ -5455,19 +5292,10 @@ Does not copy symbols. Copies strings without text properties. */) | |||
| 5455 | return purecopy (obj); | 5292 | return purecopy (obj); |
| 5456 | } | 5293 | } |
| 5457 | 5294 | ||
| 5458 | /* Pinned objects are marked before every GC cycle. */ | ||
| 5459 | static struct pinned_object | ||
| 5460 | { | ||
| 5461 | Lisp_Object object; | ||
| 5462 | struct pinned_object *next; | ||
| 5463 | } *pinned_objects; | ||
| 5464 | |||
| 5465 | static Lisp_Object | 5295 | static Lisp_Object |
| 5466 | purecopy (Lisp_Object obj) | 5296 | purecopy (Lisp_Object obj) |
| 5467 | { | 5297 | { |
| 5468 | if (FIXNUMP (obj) | 5298 | if (FIXNUMP (obj) || SUBRP (obj)) |
| 5469 | || (! SYMBOLP (obj) && PURE_P (XPNTR (obj))) | ||
| 5470 | || SUBRP (obj)) | ||
| 5471 | return obj; /* Already pure. */ | 5299 | return obj; /* Already pure. */ |
| 5472 | 5300 | ||
| 5473 | if (HASH_TABLE_P (Vpurify_flag)) /* Hash consing. */ | 5301 | if (HASH_TABLE_P (Vpurify_flag)) /* Hash consing. */ |
| @@ -5475,12 +5303,12 @@ purecopy (Lisp_Object obj) | |||
| 5475 | Lisp_Object tmp = Fgethash (obj, Vpurify_flag, Qnil); | 5303 | Lisp_Object tmp = Fgethash (obj, Vpurify_flag, Qnil); |
| 5476 | if (!NILP (tmp)) | 5304 | if (!NILP (tmp)) |
| 5477 | return tmp; | 5305 | return tmp; |
| 5306 | Fputhash (obj, obj, Vpurify_flag); | ||
| 5478 | } | 5307 | } |
| 5479 | 5308 | ||
| 5480 | return obj; | 5309 | return obj; |
| 5481 | } | 5310 | } |
| 5482 | 5311 | ||
| 5483 | |||
| 5484 | 5312 | ||
| 5485 | /*********************************************************************** | 5313 | /*********************************************************************** |
| 5486 | Protection from GC | 5314 | Protection from GC |
| @@ -5672,31 +5500,6 @@ compact_undo_list (Lisp_Object list) | |||
| 5672 | } | 5500 | } |
| 5673 | 5501 | ||
| 5674 | static void | 5502 | static void |
| 5675 | mark_pinned_objects (void) | ||
| 5676 | { | ||
| 5677 | for (struct pinned_object *pobj = pinned_objects; pobj; pobj = pobj->next) | ||
| 5678 | mark_object (pobj->object); | ||
| 5679 | } | ||
| 5680 | |||
| 5681 | static void | ||
| 5682 | mark_pinned_symbols (void) | ||
| 5683 | { | ||
| 5684 | struct symbol_block *sblk; | ||
| 5685 | int lim = (symbol_block_pinned == symbol_block | ||
| 5686 | ? symbol_block_index : SYMBOL_BLOCK_SIZE); | ||
| 5687 | |||
| 5688 | for (sblk = symbol_block_pinned; sblk; sblk = sblk->next) | ||
| 5689 | { | ||
| 5690 | struct Lisp_Symbol *sym = sblk->symbols, *end = sym + lim; | ||
| 5691 | for (; sym < end; ++sym) | ||
| 5692 | if (sym->u.s.pinned) | ||
| 5693 | mark_object (make_lisp_symbol (sym)); | ||
| 5694 | |||
| 5695 | lim = SYMBOL_BLOCK_SIZE; | ||
| 5696 | } | ||
| 5697 | } | ||
| 5698 | |||
| 5699 | static void | ||
| 5700 | visit_vectorlike_root (struct gc_root_visitor visitor, | 5503 | visit_vectorlike_root (struct gc_root_visitor visitor, |
| 5701 | struct Lisp_Vector *ptr, | 5504 | struct Lisp_Vector *ptr, |
| 5702 | enum gc_root_type type) | 5505 | enum gc_root_type type) |
| @@ -5960,8 +5763,6 @@ garbage_collect (void) | |||
| 5960 | struct gc_root_visitor visitor = { .visit = mark_object_root_visitor }; | 5763 | struct gc_root_visitor visitor = { .visit = mark_object_root_visitor }; |
| 5961 | visit_static_gc_roots (visitor); | 5764 | visit_static_gc_roots (visitor); |
| 5962 | 5765 | ||
| 5963 | mark_pinned_objects (); | ||
| 5964 | mark_pinned_symbols (); | ||
| 5965 | mark_lread (); | 5766 | mark_lread (); |
| 5966 | mark_terminals (); | 5767 | mark_terminals (); |
| 5967 | mark_kboards (); | 5768 | mark_kboards (); |
| @@ -6088,10 +5889,6 @@ where each entry has the form (NAME SIZE USED FREE), where: | |||
| 6088 | keeps around for future allocations (maybe because it does not know how | 5889 | keeps around for future allocations (maybe because it does not know how |
| 6089 | to return them to the OS). | 5890 | to return them to the OS). |
| 6090 | 5891 | ||
| 6091 | However, if there was overflow in pure space, and Emacs was dumped | ||
| 6092 | using the \"unexec\" method, `garbage-collect' returns nil, because | ||
| 6093 | real GC can't be done. | ||
| 6094 | |||
| 6095 | Note that calling this function does not guarantee that absolutely all | 5892 | Note that calling this function does not guarantee that absolutely all |
| 6096 | unreachable objects will be garbage-collected. Emacs uses a | 5893 | unreachable objects will be garbage-collected. Emacs uses a |
| 6097 | mark-and-sweep garbage collector, but is conservative when it comes to | 5894 | mark-and-sweep garbage collector, but is conservative when it comes to |
| @@ -6519,8 +6316,6 @@ process_mark_stack (ptrdiff_t base_sp) | |||
| 6519 | Lisp_Object obj = mark_stack_pop (); | 6316 | Lisp_Object obj = mark_stack_pop (); |
| 6520 | mark_obj: ; | 6317 | mark_obj: ; |
| 6521 | void *po = XPNTR (obj); | 6318 | void *po = XPNTR (obj); |
| 6522 | if (PURE_P (po)) | ||
| 6523 | continue; | ||
| 6524 | 6319 | ||
| 6525 | #if GC_REMEMBER_LAST_MARKED | 6320 | #if GC_REMEMBER_LAST_MARKED |
| 6526 | last_marked[last_marked_index++] = obj; | 6321 | last_marked[last_marked_index++] = obj; |
| @@ -6746,8 +6541,7 @@ process_mark_stack (ptrdiff_t base_sp) | |||
| 6746 | break; | 6541 | break; |
| 6747 | default: emacs_abort (); | 6542 | default: emacs_abort (); |
| 6748 | } | 6543 | } |
| 6749 | if (!PURE_P (XSTRING (ptr->u.s.name))) | 6544 | set_string_marked (XSTRING (ptr->u.s.name)); |
| 6750 | set_string_marked (XSTRING (ptr->u.s.name)); | ||
| 6751 | mark_interval_tree (string_intervals (ptr->u.s.name)); | 6545 | mark_interval_tree (string_intervals (ptr->u.s.name)); |
| 6752 | /* Inner loop to mark next symbol in this bucket, if any. */ | 6546 | /* Inner loop to mark next symbol in this bucket, if any. */ |
| 6753 | po = ptr = ptr->u.s.next; | 6547 | po = ptr = ptr->u.s.next; |
| @@ -6881,7 +6675,7 @@ survives_gc_p (Lisp_Object obj) | |||
| 6881 | emacs_abort (); | 6675 | emacs_abort (); |
| 6882 | } | 6676 | } |
| 6883 | 6677 | ||
| 6884 | return survives_p || PURE_P (XPNTR (obj)); | 6678 | return survives_p; |
| 6885 | } | 6679 | } |
| 6886 | 6680 | ||
| 6887 | 6681 | ||
| @@ -7482,7 +7276,7 @@ init_alloc_once (void) | |||
| 7482 | { | 7276 | { |
| 7483 | gc_cons_threshold = GC_DEFAULT_THRESHOLD; | 7277 | gc_cons_threshold = GC_DEFAULT_THRESHOLD; |
| 7484 | /* Even though Qt's contents are not set up, its address is known. */ | 7278 | /* Even though Qt's contents are not set up, its address is known. */ |
| 7485 | Vpurify_flag = Qt; | 7279 | Vpurify_flag = Qt; /* FIXME: Redundant with setting in lread.c. */ |
| 7486 | 7280 | ||
| 7487 | PDUMPER_REMEMBER_SCALAR (buffer_defaults.header); | 7281 | PDUMPER_REMEMBER_SCALAR (buffer_defaults.header); |
| 7488 | PDUMPER_REMEMBER_SCALAR (buffer_local_symbols.header); | 7282 | PDUMPER_REMEMBER_SCALAR (buffer_local_symbols.header); |
| @@ -7501,8 +7295,6 @@ init_alloc_once (void) | |||
| 7501 | static void | 7295 | static void |
| 7502 | init_alloc_once_for_pdumper (void) | 7296 | init_alloc_once_for_pdumper (void) |
| 7503 | { | 7297 | { |
| 7504 | purebeg = PUREBEG; | ||
| 7505 | pure_size = PURESIZE; | ||
| 7506 | mem_init (); | 7298 | mem_init (); |
| 7507 | 7299 | ||
| 7508 | #ifdef DOUG_LEA_MALLOC | 7300 | #ifdef DOUG_LEA_MALLOC |
| @@ -7546,7 +7338,7 @@ If this portion is smaller than `gc-cons-threshold', this is ignored. */); | |||
| 7546 | Vgc_cons_percentage = make_float (0.1); | 7338 | Vgc_cons_percentage = make_float (0.1); |
| 7547 | 7339 | ||
| 7548 | DEFVAR_INT ("pure-bytes-used", pure_bytes_used, | 7340 | DEFVAR_INT ("pure-bytes-used", pure_bytes_used, |
| 7549 | doc: /* Number of bytes of shareable Lisp data allocated so far. */); | 7341 | doc: /* No longer used. */); |
| 7550 | 7342 | ||
| 7551 | DEFVAR_INT ("cons-cells-consed", cons_cells_consed, | 7343 | DEFVAR_INT ("cons-cells-consed", cons_cells_consed, |
| 7552 | doc: /* Number of cons cells that have been consed so far. */); | 7344 | doc: /* Number of cons cells that have been consed so far. */); |
| @@ -7572,9 +7364,13 @@ If this portion is smaller than `gc-cons-threshold', this is ignored. */); | |||
| 7572 | 7364 | ||
| 7573 | DEFVAR_LISP ("purify-flag", Vpurify_flag, | 7365 | DEFVAR_LISP ("purify-flag", Vpurify_flag, |
| 7574 | doc: /* Non-nil means loading Lisp code in order to dump an executable. | 7366 | doc: /* Non-nil means loading Lisp code in order to dump an executable. |
| 7575 | This means that certain objects should be allocated in shared (pure) space. | 7367 | This used to mean that certain objects should be allocated in shared (pure) |
| 7576 | It can also be set to a hash-table, in which case this table is used to | 7368 | space. It can also be set to a hash-table, in which case this table is used |
| 7577 | do hash-consing of the objects allocated to pure space. */); | 7369 | to do hash-consing of the objects allocated to pure space. |
| 7370 | The hash-consing may still apply, but objects are not allocated in purespace | ||
| 7371 | any more. | ||
| 7372 | This flag is still used in a few places not to decide where objects are | ||
| 7373 | allocated but to know if we're in the preload phase of Emacs's build. */); | ||
| 7578 | 7374 | ||
| 7579 | DEFVAR_BOOL ("garbage-collection-messages", garbage_collection_messages, | 7375 | DEFVAR_BOOL ("garbage-collection-messages", garbage_collection_messages, |
| 7580 | doc: /* Non-nil means display messages at start and end of garbage collection. */); | 7376 | doc: /* Non-nil means display messages at start and end of garbage collection. */); |
| @@ -7590,10 +7386,10 @@ do hash-consing of the objects allocated to pure space. */); | |||
| 7590 | /* We build this in advance because if we wait until we need it, we might | 7386 | /* We build this in advance because if we wait until we need it, we might |
| 7591 | not be able to allocate the memory to hold it. */ | 7387 | not be able to allocate the memory to hold it. */ |
| 7592 | Vmemory_signal_data | 7388 | Vmemory_signal_data |
| 7593 | = pure_list (Qerror, | 7389 | = list (Qerror, |
| 7594 | build_pure_c_string ("Memory exhausted--use" | 7390 | build_string ("Memory exhausted--use" |
| 7595 | " M-x save-some-buffers then" | 7391 | " M-x save-some-buffers then" |
| 7596 | " exit and restart Emacs")); | 7392 | " exit and restart Emacs")); |
| 7597 | 7393 | ||
| 7598 | DEFVAR_LISP ("memory-full", Vmemory_full, | 7394 | DEFVAR_LISP ("memory-full", Vmemory_full, |
| 7599 | doc: /* Non-nil means Emacs cannot get much more Lisp memory. */); | 7395 | doc: /* Non-nil means Emacs cannot get much more Lisp memory. */); |