aboutsummaryrefslogtreecommitdiffstats
path: root/src/alloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/alloc.c')
-rw-r--r--src/alloc.c520
1 files changed, 66 insertions, 454 deletions
diff --git a/src/alloc.c b/src/alloc.c
index 642cccc97c6..a9df5ca885f 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -33,7 +33,6 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
33#include "bignum.h" 33#include "bignum.h"
34#include "dispextern.h" 34#include "dispextern.h"
35#include "intervals.h" 35#include "intervals.h"
36#include "puresize.h"
37#include "sysstdio.h" 36#include "sysstdio.h"
38#include "systime.h" 37#include "systime.h"
39#include "character.h" 38#include "character.h"
@@ -380,33 +379,6 @@ static char *spare_memory[7];
380 379
381#define SPARE_MEMORY (1 << 14) 380#define SPARE_MEMORY (1 << 14)
382 381
383/* Initialize it to a nonzero value to force it into data space
384 (rather than bss space). That way unexec will remap it into text
385 space (pure), on some systems. We have not implemented the
386 remapping on more recent systems because this is less important
387 nowadays than in the days of small memories and timesharing. */
388
389EMACS_INT pure[(PURESIZE + sizeof (EMACS_INT) - 1) / sizeof (EMACS_INT)] = {1,};
390#define PUREBEG (char *) pure
391
392/* Pointer to the pure area, and its size. */
393
394static char *purebeg;
395static ptrdiff_t pure_size;
396
397/* Number of bytes of pure storage used before pure storage overflowed.
398 If this is non-zero, this implies that an overflow occurred. */
399
400static ptrdiff_t pure_bytes_used_before_overflow;
401
402/* Index in pure at which next pure Lisp object will be allocated.. */
403
404static ptrdiff_t pure_bytes_used_lisp;
405
406/* Number of bytes allocated for non-Lisp objects in pure storage. */
407
408static ptrdiff_t pure_bytes_used_non_lisp;
409
410/* If positive, garbage collection is inhibited. Otherwise, zero. */ 382/* If positive, garbage collection is inhibited. Otherwise, zero. */
411 383
412intptr_t garbage_collection_inhibited; 384intptr_t garbage_collection_inhibited;
@@ -457,7 +429,6 @@ static struct Lisp_Vector *allocate_clear_vector (ptrdiff_t, bool);
457static void unchain_finalizer (struct Lisp_Finalizer *); 429static void unchain_finalizer (struct Lisp_Finalizer *);
458static void mark_terminals (void); 430static void mark_terminals (void);
459static void gc_sweep (void); 431static void gc_sweep (void);
460static Lisp_Object make_pure_vector (ptrdiff_t);
461static void mark_buffer (struct buffer *); 432static void mark_buffer (struct buffer *);
462 433
463#if !defined REL_ALLOC || defined SYSTEM_MALLOC 434#if !defined REL_ALLOC || defined SYSTEM_MALLOC
@@ -578,15 +549,13 @@ Lisp_Object const *staticvec[NSTATICS];
578 549
579int staticidx; 550int staticidx;
580 551
581static void *pure_alloc (size_t, int); 552#ifndef HAVE_ALIGNED_ALLOC
582
583/* Return PTR rounded up to the next multiple of ALIGNMENT. */
584
585static void * 553static void *
586pointer_align (void *ptr, int alignment) 554pointer_align (void *ptr, int alignment)
587{ 555{
588 return (void *) ROUNDUP ((uintptr_t) ptr, alignment); 556 return (void *) ROUNDUP ((uintptr_t) ptr, alignment);
589} 557}
558#endif
590 559
591/* Extract the pointer hidden within O. */ 560/* Extract the pointer hidden within O. */
592 561
@@ -1720,12 +1689,30 @@ static ptrdiff_t const STRING_BYTES_MAX =
1720 1689
1721/* Initialize string allocation. Called from init_alloc_once. */ 1690/* Initialize string allocation. Called from init_alloc_once. */
1722 1691
1692static struct Lisp_String *allocate_string (void);
1693static void
1694allocate_string_data (struct Lisp_String *s,
1695 EMACS_INT nchars, EMACS_INT nbytes, bool clearit,
1696 bool immovable);
1697
1723static void 1698static void
1724init_strings (void) 1699init_strings (void)
1725{ 1700{
1726 empty_unibyte_string = make_pure_string ("", 0, 0, 0); 1701 /* String allocation code will return one of 'empty_*ibyte_string'
1702 when asked to construct a new 0-length string, so in order to build
1703 those special cases, we have to do it "by hand". */
1704 struct Lisp_String *ems = allocate_string ();
1705 struct Lisp_String *eus = allocate_string ();
1706 ems->u.s.intervals = NULL;
1707 eus->u.s.intervals = NULL;
1708 allocate_string_data (ems, 0, 0, false, false);
1709 allocate_string_data (eus, 0, 0, false, false);
1710 /* We can't use 'STRING_SET_UNIBYTE' because this one includes a hack
1711 * to redirect its arg to 'empty_unibyte_string' when nbytes == 0. */
1712 eus->u.s.size_byte = -1;
1713 XSETSTRING (empty_multibyte_string, ems);
1714 XSETSTRING (empty_unibyte_string, eus);
1727 staticpro (&empty_unibyte_string); 1715 staticpro (&empty_unibyte_string);
1728 empty_multibyte_string = make_pure_string ("", 0, 0, 1);
1729 staticpro (&empty_multibyte_string); 1716 staticpro (&empty_multibyte_string);
1730} 1717}
1731 1718
@@ -2924,17 +2911,16 @@ list5 (Lisp_Object arg1, Lisp_Object arg2, Lisp_Object arg3, Lisp_Object arg4,
2924} 2911}
2925 2912
2926/* Make a list of COUNT Lisp_Objects, where ARG is the first one. 2913/* Make a list of COUNT Lisp_Objects, where ARG is the first one.
2927 Use CONS to construct the pairs. AP has any remaining args. */ 2914 AP has any remaining args. */
2928static Lisp_Object 2915static Lisp_Object
2929cons_listn (ptrdiff_t count, Lisp_Object arg, 2916cons_listn (ptrdiff_t count, Lisp_Object arg, va_list ap)
2930 Lisp_Object (*cons) (Lisp_Object, Lisp_Object), va_list ap)
2931{ 2917{
2932 eassume (0 < count); 2918 eassume (0 < count);
2933 Lisp_Object val = cons (arg, Qnil); 2919 Lisp_Object val = Fcons (arg, Qnil);
2934 Lisp_Object tail = val; 2920 Lisp_Object tail = val;
2935 for (ptrdiff_t i = 1; i < count; i++) 2921 for (ptrdiff_t i = 1; i < count; i++)
2936 { 2922 {
2937 Lisp_Object elem = cons (va_arg (ap, Lisp_Object), Qnil); 2923 Lisp_Object elem = Fcons (va_arg (ap, Lisp_Object), Qnil);
2938 XSETCDR (tail, elem); 2924 XSETCDR (tail, elem);
2939 tail = elem; 2925 tail = elem;
2940 } 2926 }
@@ -2947,18 +2933,7 @@ listn (ptrdiff_t count, Lisp_Object arg1, ...)
2947{ 2933{
2948 va_list ap; 2934 va_list ap;
2949 va_start (ap, arg1); 2935 va_start (ap, arg1);
2950 Lisp_Object val = cons_listn (count, arg1, Fcons, ap); 2936 Lisp_Object val = cons_listn (count, arg1, ap);
2951 va_end (ap);
2952 return val;
2953}
2954
2955/* Make a pure list of COUNT Lisp_Objects, where ARG1 is the first one. */
2956Lisp_Object
2957pure_listn (ptrdiff_t count, Lisp_Object arg1, ...)
2958{
2959 va_list ap;
2960 va_start (ap, arg1);
2961 Lisp_Object val = cons_listn (count, arg1, pure_cons, ap);
2962 va_end (ap); 2937 va_end (ap);
2963 return val; 2938 return val;
2964} 2939}
@@ -3139,7 +3114,7 @@ static ptrdiff_t last_inserted_vector_free_idx = VECTOR_FREE_LIST_ARRAY_SIZE;
3139 3114
3140static struct large_vector *large_vectors; 3115static struct large_vector *large_vectors;
3141 3116
3142/* The only vector with 0 slots, allocated from pure space. */ 3117/* The only vector with 0 slots. */
3143 3118
3144Lisp_Object zero_vector; 3119Lisp_Object zero_vector;
3145 3120
@@ -3191,14 +3166,8 @@ allocate_vector_block (void)
3191 return block; 3166 return block;
3192} 3167}
3193 3168
3194/* Called once to initialize vector allocation. */ 3169static struct Lisp_Vector *
3195 3170allocate_vector_from_block (ptrdiff_t nbytes);
3196static void
3197init_vectors (void)
3198{
3199 zero_vector = make_pure_vector (0);
3200 staticpro (&zero_vector);
3201}
3202 3171
3203/* Memory footprint in bytes of a pseudovector other than a bool-vector. */ 3172/* Memory footprint in bytes of a pseudovector other than a bool-vector. */
3204static ptrdiff_t 3173static ptrdiff_t
@@ -3211,6 +3180,31 @@ pseudovector_nbytes (const union vectorlike_header *hdr)
3211 return vroundup (header_size + word_size * nwords); 3180 return vroundup (header_size + word_size * nwords);
3212} 3181}
3213 3182
3183/* Called once to initialize vector allocation. */
3184
3185static void
3186init_vectors (void)
3187{
3188 /* The normal vector allocation code refuses to allocate a 0-length vector
3189 because we use the first field of vectors internally when they're on
3190 the free list, so we can't put a zero-length vector on the free list.
3191 This is not a problem for 'zero_vector' since it's always reachable.
3192 An alternative approach would be to allocate zero_vector outside of the
3193 normal heap, e.g. as a static object, and then to "hide" it from the GC,
3194 for example by marking it by hand at the beginning of the GC and unmarking
3195 it by hand at the end. */
3196 struct vector_block *block = allocate_vector_block ();
3197 struct Lisp_Vector *zv = (struct Lisp_Vector *)block->data;
3198 zv->header.size = 0;
3199 ssize_t nbytes = pseudovector_nbytes (&zv->header);
3200 ssize_t restbytes = VECTOR_BLOCK_BYTES - nbytes;
3201 eassert (restbytes % roundup_size == 0);
3202 setup_on_free_list (ADVANCE (zv, nbytes), restbytes);
3203
3204 zero_vector = make_lisp_ptr (zv, Lisp_Vectorlike);
3205 staticpro (&zero_vector);
3206}
3207
3214/* Allocate vector from a vector block. */ 3208/* Allocate vector from a vector block. */
3215 3209
3216static struct Lisp_Vector * 3210static struct Lisp_Vector *
@@ -5657,320 +5651,8 @@ hash_table_free_bytes (void *p, ptrdiff_t nbytes)
5657} 5651}
5658 5652
5659 5653
5660/***********************************************************************
5661 Pure Storage Management
5662 ***********************************************************************/
5663
5664/* Allocate room for SIZE bytes from pure Lisp storage and return a
5665 pointer to it. TYPE is the Lisp type for which the memory is
5666 allocated. TYPE < 0 means it's not used for a Lisp object,
5667 and that the result should have an alignment of -TYPE.
5668
5669 The bytes are initially zero.
5670
5671 If pure space is exhausted, allocate space from the heap. This is
5672 merely an expedient to let Emacs warn that pure space was exhausted
5673 and that Emacs should be rebuilt with a larger pure space. */
5674
5675static void *
5676pure_alloc (size_t size, int type)
5677{
5678 void *result;
5679 static bool pure_overflow_warned = false;
5680
5681 again:
5682 if (type >= 0)
5683 {
5684 /* Allocate space for a Lisp object from the beginning of the free
5685 space with taking account of alignment. */
5686 result = pointer_align (purebeg + pure_bytes_used_lisp, LISP_ALIGNMENT);
5687 pure_bytes_used_lisp = ((char *)result - (char *)purebeg) + size;
5688 }
5689 else
5690 {
5691 /* Allocate space for a non-Lisp object from the end of the free
5692 space. */
5693 ptrdiff_t unaligned_non_lisp = pure_bytes_used_non_lisp + size;
5694 char *unaligned = purebeg + pure_size - unaligned_non_lisp;
5695 int decr = (intptr_t) unaligned & (-1 - type);
5696 pure_bytes_used_non_lisp = unaligned_non_lisp + decr;
5697 result = unaligned - decr;
5698 }
5699 pure_bytes_used = pure_bytes_used_lisp + pure_bytes_used_non_lisp;
5700
5701 if (pure_bytes_used <= pure_size)
5702 return result;
5703
5704 if (!pure_overflow_warned)
5705 {
5706 message ("Pure Lisp storage overflowed");
5707 pure_overflow_warned = true;
5708 }
5709
5710 /* Don't allocate a large amount here,
5711 because it might get mmap'd and then its address
5712 might not be usable. */
5713 int small_amount = 10000;
5714 eassert (size <= small_amount - LISP_ALIGNMENT);
5715 purebeg = xzalloc (small_amount);
5716 pure_size = small_amount;
5717 pure_bytes_used_before_overflow += pure_bytes_used - size;
5718 pure_bytes_used = 0;
5719 pure_bytes_used_lisp = pure_bytes_used_non_lisp = 0;
5720
5721 /* Can't GC if pure storage overflowed because we can't determine
5722 if something is a pure object or not. */
5723 garbage_collection_inhibited++;
5724 goto again;
5725}
5726
5727/* Print a warning if PURESIZE is too small. */
5728
5729void
5730check_pure_size (void)
5731{
5732 if (pure_bytes_used_before_overflow)
5733 message (("emacs:0:Pure Lisp storage overflow (approx. %jd"
5734 " bytes needed)"),
5735 pure_bytes_used + pure_bytes_used_before_overflow);
5736}
5737
5738/* Find the byte sequence {DATA[0], ..., DATA[NBYTES-1], '\0'} from
5739 the non-Lisp data pool of the pure storage, and return its start
5740 address. Return NULL if not found. */
5741
5742static char *
5743find_string_data_in_pure (const char *data, ptrdiff_t nbytes)
5744{
5745 int i;
5746 ptrdiff_t skip, bm_skip[256], last_char_skip, infinity, start, start_max;
5747 const unsigned char *p;
5748 char *non_lisp_beg;
5749
5750 if (pure_bytes_used_non_lisp <= nbytes)
5751 return NULL;
5752
5753 /* The Android GCC generates code like:
5754
5755 0xa539e755 <+52>: lea 0x430(%esp),%esi
5756=> 0xa539e75c <+59>: movdqa %xmm0,0x0(%ebp)
5757 0xa539e761 <+64>: add $0x10,%ebp
5758
5759 but data is not aligned appropriately, so a GP fault results. */
5760
5761#if defined __i386__ \
5762 && defined HAVE_ANDROID \
5763 && !defined ANDROID_STUBIFY \
5764 && !defined (__clang__)
5765 if ((intptr_t) data & 15)
5766 return NULL;
5767#endif
5768
5769 /* Set up the Boyer-Moore table. */
5770 skip = nbytes + 1;
5771 for (i = 0; i < 256; i++)
5772 bm_skip[i] = skip;
5773
5774 p = (const unsigned char *) data;
5775 while (--skip > 0)
5776 bm_skip[*p++] = skip;
5777
5778 last_char_skip = bm_skip['\0'];
5779
5780 non_lisp_beg = purebeg + pure_size - pure_bytes_used_non_lisp;
5781 start_max = pure_bytes_used_non_lisp - (nbytes + 1);
5782
5783 /* See the comments in the function `boyer_moore' (search.c) for the
5784 use of `infinity'. */
5785 infinity = pure_bytes_used_non_lisp + 1;
5786 bm_skip['\0'] = infinity;
5787
5788 p = (const unsigned char *) non_lisp_beg + nbytes;
5789 start = 0;
5790 do
5791 {
5792 /* Check the last character (== '\0'). */
5793 do
5794 {
5795 start += bm_skip[*(p + start)];
5796 }
5797 while (start <= start_max);
5798
5799 if (start < infinity)
5800 /* Couldn't find the last character. */
5801 return NULL;
5802
5803 /* No less than `infinity' means we could find the last
5804 character at `p[start - infinity]'. */
5805 start -= infinity;
5806
5807 /* Check the remaining characters. */
5808 if (memcmp (data, non_lisp_beg + start, nbytes) == 0)
5809 /* Found. */
5810 return non_lisp_beg + start;
5811
5812 start += last_char_skip;
5813 }
5814 while (start <= start_max);
5815
5816 return NULL;
5817}
5818
5819
5820/* Return a string allocated in pure space. DATA is a buffer holding
5821 NCHARS characters, and NBYTES bytes of string data. MULTIBYTE
5822 means make the result string multibyte.
5823
5824 Must get an error if pure storage is full, since if it cannot hold
5825 a large string it may be able to hold conses that point to that
5826 string; then the string is not protected from gc. */
5827
5828Lisp_Object
5829make_pure_string (const char *data,
5830 ptrdiff_t nchars, ptrdiff_t nbytes, bool multibyte)
5831{
5832 Lisp_Object string;
5833 struct Lisp_String *s = pure_alloc (sizeof *s, Lisp_String);
5834 s->u.s.data = (unsigned char *) find_string_data_in_pure (data, nbytes);
5835 if (s->u.s.data == NULL)
5836 {
5837 s->u.s.data = pure_alloc (nbytes + 1, -1);
5838 memcpy (s->u.s.data, data, nbytes);
5839 s->u.s.data[nbytes] = '\0';
5840 }
5841 s->u.s.size = nchars;
5842 s->u.s.size_byte = multibyte ? nbytes : -1;
5843 s->u.s.intervals = NULL;
5844 XSETSTRING (string, s);
5845 return string;
5846}
5847
5848/* Return a string allocated in pure space. Do not
5849 allocate the string data, just point to DATA. */
5850
5851Lisp_Object
5852make_pure_c_string (const char *data, ptrdiff_t nchars)
5853{
5854 Lisp_Object string;
5855 struct Lisp_String *s = pure_alloc (sizeof *s, Lisp_String);
5856 s->u.s.size = nchars;
5857 s->u.s.size_byte = -2;
5858 s->u.s.data = (unsigned char *) data;
5859 s->u.s.intervals = NULL;
5860 XSETSTRING (string, s);
5861 return string;
5862}
5863
5864static Lisp_Object purecopy (Lisp_Object obj); 5654static Lisp_Object purecopy (Lisp_Object obj);
5865 5655
5866/* Return a cons allocated from pure space. Give it pure copies
5867 of CAR as car and CDR as cdr. */
5868
5869Lisp_Object
5870pure_cons (Lisp_Object car, Lisp_Object cdr)
5871{
5872 Lisp_Object new;
5873 struct Lisp_Cons *p = pure_alloc (sizeof *p, Lisp_Cons);
5874 XSETCONS (new, p);
5875 XSETCAR (new, purecopy (car));
5876 XSETCDR (new, purecopy (cdr));
5877 return new;
5878}
5879
5880
5881/* Value is a float object with value NUM allocated from pure space. */
5882
5883static Lisp_Object
5884make_pure_float (double num)
5885{
5886 Lisp_Object new;
5887 struct Lisp_Float *p = pure_alloc (sizeof *p, Lisp_Float);
5888 XSETFLOAT (new, p);
5889 XFLOAT_INIT (new, num);
5890 return new;
5891}
5892
5893/* Value is a bignum object with value VALUE allocated from pure
5894 space. */
5895
5896static Lisp_Object
5897make_pure_bignum (Lisp_Object value)
5898{
5899 mpz_t const *n = xbignum_val (value);
5900 size_t i, nlimbs = mpz_size (*n);
5901 size_t nbytes = nlimbs * sizeof (mp_limb_t);
5902 mp_limb_t *pure_limbs;
5903 mp_size_t new_size;
5904
5905 struct Lisp_Bignum *b = pure_alloc (sizeof *b, Lisp_Vectorlike);
5906 XSETPVECTYPESIZE (b, PVEC_BIGNUM, 0, VECSIZE (struct Lisp_Bignum));
5907
5908 int limb_alignment = alignof (mp_limb_t);
5909 pure_limbs = pure_alloc (nbytes, - limb_alignment);
5910 for (i = 0; i < nlimbs; ++i)
5911 pure_limbs[i] = mpz_getlimbn (*n, i);
5912
5913 new_size = nlimbs;
5914 if (mpz_sgn (*n) < 0)
5915 new_size = -new_size;
5916
5917 mpz_roinit_n (b->value, pure_limbs, new_size);
5918
5919 return make_lisp_ptr (b, Lisp_Vectorlike);
5920}
5921
5922/* Return a vector with room for LEN Lisp_Objects allocated from
5923 pure space. */
5924
5925static Lisp_Object
5926make_pure_vector (ptrdiff_t len)
5927{
5928 Lisp_Object new;
5929 size_t size = header_size + len * word_size;
5930 struct Lisp_Vector *p = pure_alloc (size, Lisp_Vectorlike);
5931 XSETVECTOR (new, p);
5932 XVECTOR (new)->header.size = len;
5933 return new;
5934}
5935
5936/* Copy all contents and parameters of TABLE to a new table allocated
5937 from pure space, return the purified table. */
5938static struct Lisp_Hash_Table *
5939purecopy_hash_table (struct Lisp_Hash_Table *table)
5940{
5941 eassert (table->weakness == Weak_None);
5942 eassert (table->purecopy);
5943
5944 struct Lisp_Hash_Table *pure = pure_alloc (sizeof *pure, Lisp_Vectorlike);
5945 *pure = *table;
5946 pure->mutable = false;
5947
5948 if (table->table_size > 0)
5949 {
5950 ptrdiff_t hash_bytes = table->table_size * sizeof *table->hash;
5951 pure->hash = pure_alloc (hash_bytes, -(int)sizeof *table->hash);
5952 memcpy (pure->hash, table->hash, hash_bytes);
5953
5954 ptrdiff_t next_bytes = table->table_size * sizeof *table->next;
5955 pure->next = pure_alloc (next_bytes, -(int)sizeof *table->next);
5956 memcpy (pure->next, table->next, next_bytes);
5957
5958 ptrdiff_t nvalues = table->table_size * 2;
5959 ptrdiff_t kv_bytes = nvalues * sizeof *table->key_and_value;
5960 pure->key_and_value = pure_alloc (kv_bytes,
5961 -(int)sizeof *table->key_and_value);
5962 for (ptrdiff_t i = 0; i < nvalues; i++)
5963 pure->key_and_value[i] = purecopy (table->key_and_value[i]);
5964
5965 ptrdiff_t index_bytes = hash_table_index_size (table)
5966 * sizeof *table->index;
5967 pure->index = pure_alloc (index_bytes, -(int)sizeof *table->index);
5968 memcpy (pure->index, table->index, index_bytes);
5969 }
5970
5971 return pure;
5972}
5973
5974DEFUN ("purecopy", Fpurecopy, Spurecopy, 1, 1, 0, 5656DEFUN ("purecopy", Fpurecopy, Spurecopy, 1, 1, 0,
5975 doc: /* Make a copy of object OBJ in pure storage. 5657 doc: /* Make a copy of object OBJ in pure storage.
5976Recursively copies contents of vectors and cons cells. 5658Recursively copies contents of vectors and cons cells.
@@ -5996,89 +5678,17 @@ static struct pinned_object
5996static Lisp_Object 5678static Lisp_Object
5997purecopy (Lisp_Object obj) 5679purecopy (Lisp_Object obj)
5998{ 5680{
5999 if (FIXNUMP (obj) 5681 if (FIXNUMP (obj) || SUBRP (obj))
6000 || (! SYMBOLP (obj) && PURE_P (XPNTR (obj))) 5682 return obj; /* No need to hash. */
6001 || SUBRP (obj))
6002 return obj; /* Already pure. */
6003
6004 if (STRINGP (obj) && XSTRING (obj)->u.s.intervals)
6005 message_with_string ("Dropping text-properties while making string `%s' pure",
6006 obj, true);
6007 5683
6008 if (HASH_TABLE_P (Vpurify_flag)) /* Hash consing. */ 5684 if (HASH_TABLE_P (Vpurify_flag)) /* Hash consing. */
6009 { 5685 {
6010 Lisp_Object tmp = Fgethash (obj, Vpurify_flag, Qnil); 5686 Lisp_Object tmp = Fgethash (obj, Vpurify_flag, Qnil);
6011 if (!NILP (tmp)) 5687 if (!NILP (tmp))
6012 return tmp; 5688 return tmp;
5689 Fputhash (obj, obj, Vpurify_flag);
6013 } 5690 }
6014 5691
6015 if (CONSP (obj))
6016 obj = pure_cons (XCAR (obj), XCDR (obj));
6017 else if (FLOATP (obj))
6018 obj = make_pure_float (XFLOAT_DATA (obj));
6019 else if (STRINGP (obj))
6020 obj = make_pure_string (SSDATA (obj), SCHARS (obj),
6021 SBYTES (obj),
6022 STRING_MULTIBYTE (obj));
6023 else if (HASH_TABLE_P (obj))
6024 {
6025 struct Lisp_Hash_Table *table = XHASH_TABLE (obj);
6026 /* Do not purify hash tables which haven't been defined with
6027 :purecopy as non-nil or are weak - they aren't guaranteed to
6028 not change. */
6029 if (table->weakness != Weak_None || !table->purecopy)
6030 {
6031 /* Instead, add the hash table to the list of pinned objects,
6032 so that it will be marked during GC. */
6033 struct pinned_object *o = xmalloc (sizeof *o);
6034 o->object = obj;
6035 o->next = pinned_objects;
6036 pinned_objects = o;
6037 return obj; /* Don't hash cons it. */
6038 }
6039
6040 obj = make_lisp_hash_table (purecopy_hash_table (table));
6041 }
6042 else if (CLOSUREP (obj) || VECTORP (obj) || RECORDP (obj))
6043 {
6044 struct Lisp_Vector *objp = XVECTOR (obj);
6045 ptrdiff_t nbytes = vector_nbytes (objp);
6046 struct Lisp_Vector *vec = pure_alloc (nbytes, Lisp_Vectorlike);
6047 register ptrdiff_t i;
6048 ptrdiff_t size = ASIZE (obj);
6049 if (size & PSEUDOVECTOR_FLAG)
6050 size &= PSEUDOVECTOR_SIZE_MASK;
6051 memcpy (vec, objp, nbytes);
6052 for (i = 0; i < size; i++)
6053 vec->contents[i] = purecopy (vec->contents[i]);
6054 /* Byte code strings must be pinned. */
6055 if (CLOSUREP (obj) && size >= 2 && STRINGP (vec->contents[1])
6056 && !STRING_MULTIBYTE (vec->contents[1]))
6057 pin_string (vec->contents[1]);
6058 XSETVECTOR (obj, vec);
6059 }
6060 else if (BARE_SYMBOL_P (obj))
6061 {
6062 if (!XBARE_SYMBOL (obj)->u.s.pinned && !c_symbol_p (XBARE_SYMBOL (obj)))
6063 { /* We can't purify them, but they appear in many pure objects.
6064 Mark them as `pinned' so we know to mark them at every GC cycle. */
6065 XBARE_SYMBOL (obj)->u.s.pinned = true;
6066 symbol_block_pinned = symbol_block;
6067 }
6068 /* Don't hash-cons it. */
6069 return obj;
6070 }
6071 else if (BIGNUMP (obj))
6072 obj = make_pure_bignum (obj);
6073 else
6074 {
6075 AUTO_STRING (fmt, "Don't know how to purify: %S");
6076 Fsignal (Qerror, list1 (CALLN (Fformat, fmt, obj)));
6077 }
6078
6079 if (HASH_TABLE_P (Vpurify_flag)) /* Hash consing. */
6080 Fputhash (obj, obj, Vpurify_flag);
6081
6082 return obj; 5692 return obj;
6083} 5693}
6084 5694
@@ -8093,8 +7703,6 @@ init_alloc_once (void)
8093static void 7703static void
8094init_alloc_once_for_pdumper (void) 7704init_alloc_once_for_pdumper (void)
8095{ 7705{
8096 purebeg = PUREBEG;
8097 pure_size = PURESIZE;
8098 mem_init (); 7706 mem_init ();
8099 7707
8100#ifdef DOUG_LEA_MALLOC 7708#ifdef DOUG_LEA_MALLOC
@@ -8148,7 +7756,7 @@ If this portion is smaller than `gc-cons-threshold', this is ignored. */);
8148 Vgc_cons_percentage = make_float (0.1); 7756 Vgc_cons_percentage = make_float (0.1);
8149 7757
8150 DEFVAR_INT ("pure-bytes-used", pure_bytes_used, 7758 DEFVAR_INT ("pure-bytes-used", pure_bytes_used,
8151 doc: /* Number of bytes of shareable Lisp data allocated so far. */); 7759 doc: /* No longer used. */);
8152 7760
8153 DEFVAR_INT ("cons-cells-consed", cons_cells_consed, 7761 DEFVAR_INT ("cons-cells-consed", cons_cells_consed,
8154 doc: /* Number of cons cells that have been consed so far. */); 7762 doc: /* Number of cons cells that have been consed so far. */);
@@ -8174,9 +7782,13 @@ If this portion is smaller than `gc-cons-threshold', this is ignored. */);
8174 7782
8175 DEFVAR_LISP ("purify-flag", Vpurify_flag, 7783 DEFVAR_LISP ("purify-flag", Vpurify_flag,
8176 doc: /* Non-nil means loading Lisp code in order to dump an executable. 7784 doc: /* Non-nil means loading Lisp code in order to dump an executable.
8177This means that certain objects should be allocated in shared (pure) space. 7785This used to mean that certain objects should be allocated in shared (pure)
8178It can also be set to a hash-table, in which case this table is used to 7786space. It can also be set to a hash-table, in which case this table is used
8179do hash-consing of the objects allocated to pure space. */); 7787to do hash-consing of the objects allocated to pure space.
7788The hash-consing still applies, but objects are not allocated in pure
7789storage any more.
7790This flag is still used in a few places not to decide where objects are
7791allocated but to know if we're in the preload phase of Emacs's build. */);
8180 7792
8181 DEFVAR_BOOL ("garbage-collection-messages", garbage_collection_messages, 7793 DEFVAR_BOOL ("garbage-collection-messages", garbage_collection_messages,
8182 doc: /* Non-nil means display messages at start and end of garbage collection. */); 7794 doc: /* Non-nil means display messages at start and end of garbage collection. */);