diff options
Diffstat (limited to 'src/alloc.c')
| -rw-r--r-- | src/alloc.c | 114 |
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 | ||
| 2873 | DEFUN ("make-list", Fmake_list, Smake_list, 2, 2, 0, | 2873 | DEFUN ("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. */ | ||
| 5439 | static struct Lisp_Hash_Table * | ||
| 5440 | purecopy_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 | |||
| 5467 | DEFUN ("purecopy", Fpurecopy, Spurecopy, 1, 1, 0, | 5468 | DEFUN ("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. |
| 5469 | Recursively copies contents of vectors and cons cells. | 5470 | Recursively 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 | ||
| 5483 | struct pinned_object | ||
| 5484 | { | ||
| 5485 | Lisp_Object object; | ||
| 5486 | struct pinned_object *next; | ||
| 5487 | }; | ||
| 5488 | |||
| 5489 | /* Pinned objects are marked before every GC cycle. */ | ||
| 5490 | static struct pinned_object *pinned_objects; | ||
| 5491 | |||
| 5483 | static Lisp_Object | 5492 | static Lisp_Object |
| 5484 | purecopy (Lisp_Object obj) | 5493 | purecopy (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 | ||
| 5726 | static void | 5755 | static void |
| 5756 | mark_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 | |||
| 5765 | static void | ||
| 5727 | mark_pinned_symbols (void) | 5766 | mark_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 (); |