aboutsummaryrefslogtreecommitdiffstats
path: root/src/alloc.c
diff options
context:
space:
mode:
authorStefan Monnier2004-05-29 00:00:17 +0000
committerStefan Monnier2004-05-29 00:00:17 +0000
commitc37adf23e8607a6479a950c7f6b41ca819b7c73c (patch)
tree2347a5736c09eeab6d1942fb308245d9f9f32e1f /src/alloc.c
parent138c4b3d36b8390387da752825f98d56535f6459 (diff)
downloademacs-c37adf23e8607a6479a950c7f6b41ca819b7c73c.tar.gz
emacs-c37adf23e8607a6479a950c7f6b41ca819b7c73c.zip
Undo Kim's recent changes and fix the same bug differently.
(marker_blocks_pending_free): Remove. (Fgarbage_collect): Sweep after cleaning up undo-lists. Mark the undo lists after claning them up. Don't free block in marker_blocks_pending_free. (mark_buffer): Don't mark undo_list. (gc_sweep): Sweep hash-tables and strings first. Do free marker blocks that are empty.
Diffstat (limited to 'src/alloc.c')
-rw-r--r--src/alloc.c120
1 files changed, 32 insertions, 88 deletions
diff --git a/src/alloc.c b/src/alloc.c
index 452a1fbb2a1..0a0b25bcb7d 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -2866,10 +2866,6 @@ int marker_block_index;
2866 2866
2867union Lisp_Misc *marker_free_list; 2867union Lisp_Misc *marker_free_list;
2868 2868
2869/* Marker blocks which should be freed at end of GC. */
2870
2871struct marker_block *marker_blocks_pending_free;
2872
2873/* Total number of marker blocks now in use. */ 2869/* Total number of marker blocks now in use. */
2874 2870
2875int n_marker_blocks; 2871int n_marker_blocks;
@@ -2880,7 +2876,6 @@ init_marker ()
2880 marker_block = NULL; 2876 marker_block = NULL;
2881 marker_block_index = MARKER_BLOCK_SIZE; 2877 marker_block_index = MARKER_BLOCK_SIZE;
2882 marker_free_list = 0; 2878 marker_free_list = 0;
2883 marker_blocks_pending_free = 0;
2884 n_marker_blocks = 0; 2879 n_marker_blocks = 0;
2885} 2880}
2886 2881
@@ -4459,42 +4454,36 @@ returns nil, because real GC can't be done. */)
4459 } 4454 }
4460#endif 4455#endif
4461 4456
4462 gc_sweep (); 4457 /* Everything is now marked, except for the things that require special
4463 4458 finalization, i.e. the undo_list.
4464 /* Look thru every buffer's undo list for elements that used to 4459 Look thru every buffer's undo list
4465 contain update markers that were changed to Lisp_Misc_Free 4460 for elements that update markers that were not marked,
4466 objects and delete them. This may leave a few cons cells 4461 and delete them. */
4467 unchained, but we will get those on the next sweep. */
4468 { 4462 {
4469 register struct buffer *nextb = all_buffers; 4463 register struct buffer *nextb = all_buffers;
4470 4464
4471 while (nextb) 4465 while (nextb)
4472 { 4466 {
4473 /* If a buffer's undo list is Qt, that means that undo is 4467 /* If a buffer's undo list is Qt, that means that undo is
4474 turned off in that buffer. */ 4468 turned off in that buffer. Calling truncate_undo_list on
4469 Qt tends to return NULL, which effectively turns undo back on.
4470 So don't call truncate_undo_list if undo_list is Qt. */
4475 if (! EQ (nextb->undo_list, Qt)) 4471 if (! EQ (nextb->undo_list, Qt))
4476 { 4472 {
4477 Lisp_Object tail, prev, elt, car; 4473 Lisp_Object tail, prev;
4478 tail = nextb->undo_list; 4474 tail = nextb->undo_list;
4479 prev = Qnil; 4475 prev = Qnil;
4480 while (CONSP (tail)) 4476 while (CONSP (tail))
4481 { 4477 {
4482 if ((elt = XCAR (tail), GC_CONSP (elt)) 4478 if (GC_CONSP (XCAR (tail))
4483 && (car = XCAR (elt), GC_MISCP (car)) 4479 && GC_MARKERP (XCAR (XCAR (tail)))
4484 && XMISCTYPE (car) == Lisp_Misc_Free) 4480 && !XMARKER (XCAR (XCAR (tail)))->gcmarkbit)
4485 { 4481 {
4486 Lisp_Object cdr = XCDR (tail);
4487 /* Do not use free_cons here, as we don't know if
4488 anybody else has a pointer to these conses. */
4489 XSETCAR (elt, Qnil);
4490 XSETCDR (elt, Qnil);
4491 XSETCAR (tail, Qnil);
4492 XSETCDR (tail, Qnil);
4493 if (NILP (prev)) 4482 if (NILP (prev))
4494 nextb->undo_list = tail = cdr; 4483 nextb->undo_list = tail = XCDR (tail);
4495 else 4484 else
4496 { 4485 {
4497 tail = cdr; 4486 tail = XCDR (tail);
4498 XSETCDR (prev, tail); 4487 XSETCDR (prev, tail);
4499 } 4488 }
4500 } 4489 }
@@ -4505,22 +4494,15 @@ returns nil, because real GC can't be done. */)
4505 } 4494 }
4506 } 4495 }
4507 } 4496 }
4497 /* Now that we have stripped the elements that need not be in the
4498 undo_list any more, we can finally mark the list. */
4499 mark_object (nextb->undo_list);
4508 4500
4509 nextb = nextb->next; 4501 nextb = nextb->next;
4510 } 4502 }
4511 } 4503 }
4512 4504
4513 /* Undo lists have been cleaned up, so we can free marker blocks now. */ 4505 gc_sweep ();
4514
4515 {
4516 struct marker_block *mblk;
4517
4518 while ((mblk = marker_blocks_pending_free) != 0)
4519 {
4520 marker_blocks_pending_free = mblk->next;
4521 lisp_free (mblk);
4522 }
4523 }
4524 4506
4525 /* Clear the mark bits that we set in certain root slots. */ 4507 /* Clear the mark bits that we set in certain root slots. */
4526 4508
@@ -5088,41 +5070,9 @@ mark_buffer (buf)
5088 5070
5089 MARK_INTERVAL_TREE (BUF_INTERVALS (buffer)); 5071 MARK_INTERVAL_TREE (BUF_INTERVALS (buffer));
5090 5072
5091 if (CONSP (buffer->undo_list)) 5073 /* For now, we just don't mark the undo_list. It's done later in
5092 { 5074 a special way just before the sweep phase, and after stripping
5093 Lisp_Object tail; 5075 some of its elements that are not needed any more. */
5094 tail = buffer->undo_list;
5095
5096 /* We mark the undo list specially because
5097 its pointers to markers should be weak. */
5098
5099 while (CONSP (tail))
5100 {
5101 register struct Lisp_Cons *ptr = XCONS (tail);
5102
5103 if (CONS_MARKED_P (ptr))
5104 break;
5105 CONS_MARK (ptr);
5106 if (GC_CONSP (ptr->car)
5107 && !CONS_MARKED_P (XCONS (ptr->car))
5108 && GC_MARKERP (XCAR (ptr->car)))
5109 {
5110 CONS_MARK (XCONS (ptr->car));
5111 mark_object (XCDR (ptr->car));
5112 }
5113 else
5114 mark_object (ptr->car);
5115
5116 if (CONSP (ptr->cdr))
5117 tail = ptr->cdr;
5118 else
5119 break;
5120 }
5121
5122 mark_object (XCDR (tail));
5123 }
5124 else
5125 mark_object (buffer->undo_list);
5126 5076
5127 if (buffer->overlays_before) 5077 if (buffer->overlays_before)
5128 { 5078 {
@@ -5202,6 +5152,16 @@ survives_gc_p (obj)
5202static void 5152static void
5203gc_sweep () 5153gc_sweep ()
5204{ 5154{
5155 /* Remove or mark entries in weak hash tables.
5156 This must be done before any object is unmarked. */
5157 sweep_weak_hash_tables ();
5158
5159 sweep_strings ();
5160#ifdef GC_CHECK_STRING_BYTES
5161 if (!noninteractive)
5162 check_string_bytes (1);
5163#endif
5164
5205 /* Put all unmarked conses on free list */ 5165 /* Put all unmarked conses on free list */
5206 { 5166 {
5207 register struct cons_block *cblk; 5167 register struct cons_block *cblk;
@@ -5252,16 +5212,6 @@ gc_sweep ()
5252 total_free_conses = num_free; 5212 total_free_conses = num_free;
5253 } 5213 }
5254 5214
5255 /* Remove or mark entries in weak hash tables.
5256 This must be done before any object is unmarked. */
5257 sweep_weak_hash_tables ();
5258
5259 sweep_strings ();
5260#ifdef GC_CHECK_STRING_BYTES
5261 if (!noninteractive)
5262 check_string_bytes (1);
5263#endif
5264
5265 /* Put all unmarked floats on free list */ 5215 /* Put all unmarked floats on free list */
5266 { 5216 {
5267 register struct float_block *fblk; 5217 register struct float_block *fblk;
@@ -5430,7 +5380,6 @@ gc_sweep ()
5430 register int num_free = 0, num_used = 0; 5380 register int num_free = 0, num_used = 0;
5431 5381
5432 marker_free_list = 0; 5382 marker_free_list = 0;
5433 marker_blocks_pending_free = 0;
5434 5383
5435 for (mblk = marker_block; mblk; mblk = *mprev) 5384 for (mblk = marker_block; mblk; mblk = *mprev)
5436 { 5385 {
@@ -5466,13 +5415,8 @@ gc_sweep ()
5466 *mprev = mblk->next; 5415 *mprev = mblk->next;
5467 /* Unhook from the free list. */ 5416 /* Unhook from the free list. */
5468 marker_free_list = mblk->markers[0].u_free.chain; 5417 marker_free_list = mblk->markers[0].u_free.chain;
5418 lisp_free (mblk);
5469 n_marker_blocks--; 5419 n_marker_blocks--;
5470
5471 /* It is not safe to free the marker block at this stage,
5472 since there may still be pointers to these markers from
5473 a buffer's undo list. KFS 2004-05-25. */
5474 mblk->next = marker_blocks_pending_free;
5475 marker_blocks_pending_free = mblk;
5476 } 5420 }
5477 else 5421 else
5478 { 5422 {