aboutsummaryrefslogtreecommitdiffstats
path: root/src/alloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/alloc.c')
-rw-r--r--src/alloc.c114
1 files changed, 77 insertions, 37 deletions
diff --git a/src/alloc.c b/src/alloc.c
index 1a6d4e2d565..dd2b688f91e 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -2872,45 +2872,15 @@ usage: (list &rest OBJECTS) */)
2872 2872
2873DEFUN ("make-list", Fmake_list, Smake_list, 2, 2, 0, 2873DEFUN ("make-list", Fmake_list, Smake_list, 2, 2, 0,
2874 doc: /* Return a newly created list of length LENGTH, with each element being INIT. */) 2874 doc: /* Return a newly created list of length LENGTH, with each element being INIT. */)
2875 (register Lisp_Object length, Lisp_Object init) 2875 (Lisp_Object length, Lisp_Object init)
2876{ 2876{
2877 register Lisp_Object val; 2877 Lisp_Object val = Qnil;
2878 register EMACS_INT size;
2879
2880 CHECK_NATNUM (length); 2878 CHECK_NATNUM (length);
2881 size = XFASTINT (length);
2882 2879
2883 val = Qnil; 2880 for (EMACS_INT size = XFASTINT (length); 0 < size; size--)
2884 while (size > 0)
2885 { 2881 {
2886 val = Fcons (init, val); 2882 val = Fcons (init, val);
2887 --size; 2883 maybe_quit ();
2888
2889 if (size > 0)
2890 {
2891 val = Fcons (init, val);
2892 --size;
2893
2894 if (size > 0)
2895 {
2896 val = Fcons (init, val);
2897 --size;
2898
2899 if (size > 0)
2900 {
2901 val = Fcons (init, val);
2902 --size;
2903
2904 if (size > 0)
2905 {
2906 val = Fcons (init, val);
2907 --size;
2908 }
2909 }
2910 }
2911 }
2912
2913 QUIT;
2914 } 2884 }
2915 2885
2916 return val; 2886 return val;
@@ -5464,6 +5434,37 @@ make_pure_vector (ptrdiff_t len)
5464 return new; 5434 return new;
5465} 5435}
5466 5436
5437/* Copy all contents and parameters of TABLE to a new table allocated
5438 from pure space, return the purified table. */
5439static struct Lisp_Hash_Table *
5440purecopy_hash_table (struct Lisp_Hash_Table *table) {
5441 eassert (NILP (table->weak));
5442 eassert (!NILP (table->pure));
5443
5444 struct Lisp_Hash_Table *pure = pure_alloc (sizeof *pure, Lisp_Vectorlike);
5445 struct hash_table_test pure_test = table->test;
5446
5447 /* Purecopy the hash table test. */
5448 pure_test.name = purecopy (table->test.name);
5449 pure_test.user_hash_function = purecopy (table->test.user_hash_function);
5450 pure_test.user_cmp_function = purecopy (table->test.user_cmp_function);
5451
5452 pure->test = pure_test;
5453 pure->header = table->header;
5454 pure->weak = purecopy (Qnil);
5455 pure->rehash_size = purecopy (table->rehash_size);
5456 pure->rehash_threshold = purecopy (table->rehash_threshold);
5457 pure->hash = purecopy (table->hash);
5458 pure->next = purecopy (table->next);
5459 pure->next_free = purecopy (table->next_free);
5460 pure->index = purecopy (table->index);
5461 pure->count = table->count;
5462 pure->key_and_value = purecopy (table->key_and_value);
5463 pure->pure = purecopy (table->pure);
5464
5465 return pure;
5466}
5467
5467DEFUN ("purecopy", Fpurecopy, Spurecopy, 1, 1, 0, 5468DEFUN ("purecopy", Fpurecopy, Spurecopy, 1, 1, 0,
5468 doc: /* Make a copy of object OBJ in pure storage. 5469 doc: /* Make a copy of object OBJ in pure storage.
5469Recursively copies contents of vectors and cons cells. 5470Recursively copies contents of vectors and cons cells.
@@ -5472,14 +5473,22 @@ Does not copy symbols. Copies strings without text properties. */)
5472{ 5473{
5473 if (NILP (Vpurify_flag)) 5474 if (NILP (Vpurify_flag))
5474 return obj; 5475 return obj;
5475 else if (MARKERP (obj) || OVERLAYP (obj) 5476 else if (MARKERP (obj) || OVERLAYP (obj) || SYMBOLP (obj))
5476 || HASH_TABLE_P (obj) || SYMBOLP (obj))
5477 /* Can't purify those. */ 5477 /* Can't purify those. */
5478 return obj; 5478 return obj;
5479 else 5479 else
5480 return purecopy (obj); 5480 return purecopy (obj);
5481} 5481}
5482 5482
5483struct pinned_object
5484{
5485 Lisp_Object object;
5486 struct pinned_object *next;
5487};
5488
5489/* Pinned objects are marked before every GC cycle. */
5490static struct pinned_object *pinned_objects;
5491
5483static Lisp_Object 5492static Lisp_Object
5484purecopy (Lisp_Object obj) 5493purecopy (Lisp_Object obj)
5485{ 5494{
@@ -5507,7 +5516,27 @@ purecopy (Lisp_Object obj)
5507 obj = make_pure_string (SSDATA (obj), SCHARS (obj), 5516 obj = make_pure_string (SSDATA (obj), SCHARS (obj),
5508 SBYTES (obj), 5517 SBYTES (obj),
5509 STRING_MULTIBYTE (obj)); 5518 STRING_MULTIBYTE (obj));
5510 else if (COMPILEDP (obj) || VECTORP (obj) || HASH_TABLE_P (obj)) 5519 else if (HASH_TABLE_P (obj))
5520 {
5521 struct Lisp_Hash_Table *table = XHASH_TABLE (obj);
5522 /* We cannot purify hash tables which haven't been defined with
5523 :purecopy as non-nil or are weak - they aren't guaranteed to
5524 not change. */
5525 if (!NILP (table->weak) || NILP (table->pure))
5526 {
5527 /* Instead, the hash table is added to the list of pinned objects,
5528 and is marked before GC. */
5529 struct pinned_object *o = xmalloc (sizeof *o);
5530 o->object = obj;
5531 o->next = pinned_objects;
5532 pinned_objects = o;
5533 return obj; /* Don't hash cons it. */
5534 }
5535
5536 struct Lisp_Hash_Table *h = purecopy_hash_table (table);
5537 XSET_HASH_TABLE (obj, h);
5538 }
5539 else if (COMPILEDP (obj) || VECTORP (obj))
5511 { 5540 {
5512 struct Lisp_Vector *objp = XVECTOR (obj); 5541 struct Lisp_Vector *objp = XVECTOR (obj);
5513 ptrdiff_t nbytes = vector_nbytes (objp); 5542 ptrdiff_t nbytes = vector_nbytes (objp);
@@ -5724,6 +5753,16 @@ compact_undo_list (Lisp_Object list)
5724} 5753}
5725 5754
5726static void 5755static void
5756mark_pinned_objects (void)
5757{
5758 struct pinned_object *pobj;
5759 for (pobj = pinned_objects; pobj; pobj = pobj->next)
5760 {
5761 mark_object (pobj->object);
5762 }
5763}
5764
5765static void
5727mark_pinned_symbols (void) 5766mark_pinned_symbols (void)
5728{ 5767{
5729 struct symbol_block *sblk; 5768 struct symbol_block *sblk;
@@ -5843,6 +5882,7 @@ garbage_collect_1 (void *end)
5843 for (i = 0; i < staticidx; i++) 5882 for (i = 0; i < staticidx; i++)
5844 mark_object (*staticvec[i]); 5883 mark_object (*staticvec[i]);
5845 5884
5885 mark_pinned_objects ();
5846 mark_pinned_symbols (); 5886 mark_pinned_symbols ();
5847 mark_terminals (); 5887 mark_terminals ();
5848 mark_kboards (); 5888 mark_kboards ();