diff options
| author | Andrea Corallo | 2020-04-03 11:15:55 +0100 |
|---|---|---|
| committer | Andrea Corallo | 2020-04-03 11:15:55 +0100 |
| commit | 3cc0438629843e7dbd3bda8bbcf6578b2e7f6200 (patch) | |
| tree | 8ce51634d61a8ebb617454d98ac6047f81da1211 /src/alloc.c | |
| parent | 63af801ed34c8dc59fb13c9e058c49203a1ae55d (diff) | |
| parent | f28166dc9a56111606be8ac50ad38179a66ea636 (diff) | |
| download | emacs-3cc0438629843e7dbd3bda8bbcf6578b2e7f6200.tar.gz emacs-3cc0438629843e7dbd3bda8bbcf6578b2e7f6200.zip | |
Merge remote-tracking branch 'savannah/master' into HEAD
Diffstat (limited to 'src/alloc.c')
| -rw-r--r-- | src/alloc.c | 106 |
1 files changed, 24 insertions, 82 deletions
diff --git a/src/alloc.c b/src/alloc.c index db0646c81e3..147e018095b 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -432,7 +432,6 @@ inline static void set_interval_marked (INTERVAL i); | |||
| 432 | enum mem_type | 432 | enum mem_type |
| 433 | { | 433 | { |
| 434 | MEM_TYPE_NON_LISP, | 434 | MEM_TYPE_NON_LISP, |
| 435 | MEM_TYPE_BUFFER, | ||
| 436 | MEM_TYPE_CONS, | 435 | MEM_TYPE_CONS, |
| 437 | MEM_TYPE_STRING, | 436 | MEM_TYPE_STRING, |
| 438 | MEM_TYPE_SYMBOL, | 437 | MEM_TYPE_SYMBOL, |
| @@ -3339,12 +3338,10 @@ allocate_pseudovector (int memlen, int lisplen, | |||
| 3339 | struct buffer * | 3338 | struct buffer * |
| 3340 | allocate_buffer (void) | 3339 | allocate_buffer (void) |
| 3341 | { | 3340 | { |
| 3342 | struct buffer *b = lisp_malloc (sizeof *b, false, MEM_TYPE_BUFFER); | 3341 | struct buffer *b |
| 3343 | 3342 | = ALLOCATE_PSEUDOVECTOR (struct buffer, cursor_in_non_selected_windows_, | |
| 3343 | PVEC_BUFFER); | ||
| 3344 | BUFFER_PVEC_INIT (b); | 3344 | BUFFER_PVEC_INIT (b); |
| 3345 | /* Put B on the chain of all buffers including killed ones. */ | ||
| 3346 | b->next = all_buffers; | ||
| 3347 | all_buffers = b; | ||
| 3348 | /* Note that the rest fields of B are not initialized. */ | 3345 | /* Note that the rest fields of B are not initialized. */ |
| 3349 | return b; | 3346 | return b; |
| 3350 | } | 3347 | } |
| @@ -4604,40 +4601,6 @@ live_vector_p (struct mem_node *m, void *p) | |||
| 4604 | return !NILP (live_vector_holding (m, p)); | 4601 | return !NILP (live_vector_holding (m, p)); |
| 4605 | } | 4602 | } |
| 4606 | 4603 | ||
| 4607 | /* If P is a pointer into a valid buffer object, return the buffer. | ||
| 4608 | Otherwise, return nil. M is a pointer to the mem_block for P. | ||
| 4609 | If IGNORE_KILLED is non-zero, treat killed buffers as invalid. */ | ||
| 4610 | |||
| 4611 | static Lisp_Object | ||
| 4612 | live_buffer_holding (struct mem_node *m, void *p, bool ignore_killed) | ||
| 4613 | { | ||
| 4614 | /* P must point into the block, and the buffer must not | ||
| 4615 | have been killed unless ALL-BUFFERS is true. */ | ||
| 4616 | if (m->type == MEM_TYPE_BUFFER) | ||
| 4617 | { | ||
| 4618 | struct buffer *b = m->start; | ||
| 4619 | char *cb = m->start; | ||
| 4620 | char *cp = p; | ||
| 4621 | ptrdiff_t offset = cp - cb; | ||
| 4622 | if (0 <= offset && offset < sizeof *b | ||
| 4623 | && !(ignore_killed && NILP (b->name_))) | ||
| 4624 | { | ||
| 4625 | Lisp_Object obj; | ||
| 4626 | XSETBUFFER (obj, b); | ||
| 4627 | return obj; | ||
| 4628 | } | ||
| 4629 | } | ||
| 4630 | return Qnil; | ||
| 4631 | } | ||
| 4632 | |||
| 4633 | /* If P is a pointer into a live (valid and not killed) buffer object, | ||
| 4634 | return non-zero. */ | ||
| 4635 | static bool | ||
| 4636 | live_buffer_p (struct mem_node *m, void *p) | ||
| 4637 | { | ||
| 4638 | return !NILP (live_buffer_holding (m, p, true)); | ||
| 4639 | } | ||
| 4640 | |||
| 4641 | /* Mark OBJ if we can prove it's a Lisp_Object. */ | 4604 | /* Mark OBJ if we can prove it's a Lisp_Object. */ |
| 4642 | 4605 | ||
| 4643 | static void | 4606 | static void |
| @@ -4692,8 +4655,7 @@ mark_maybe_object (Lisp_Object obj) | |||
| 4692 | break; | 4655 | break; |
| 4693 | 4656 | ||
| 4694 | case Lisp_Vectorlike: | 4657 | case Lisp_Vectorlike: |
| 4695 | mark_p = (EQ (obj, live_vector_holding (m, po)) | 4658 | mark_p = (EQ (obj, live_vector_holding (m, po))); |
| 4696 | || EQ (obj, live_buffer_holding (m, po, false))); | ||
| 4697 | break; | 4659 | break; |
| 4698 | 4660 | ||
| 4699 | default: | 4661 | default: |
| @@ -4762,10 +4724,6 @@ mark_maybe_pointer (void *p) | |||
| 4762 | /* Nothing to do; not a pointer to Lisp memory. */ | 4724 | /* Nothing to do; not a pointer to Lisp memory. */ |
| 4763 | break; | 4725 | break; |
| 4764 | 4726 | ||
| 4765 | case MEM_TYPE_BUFFER: | ||
| 4766 | obj = live_buffer_holding (m, p, false); | ||
| 4767 | break; | ||
| 4768 | |||
| 4769 | case MEM_TYPE_CONS: | 4727 | case MEM_TYPE_CONS: |
| 4770 | obj = live_cons_holding (m, p); | 4728 | obj = live_cons_holding (m, p); |
| 4771 | break; | 4729 | break; |
| @@ -5165,9 +5123,6 @@ valid_lisp_object_p (Lisp_Object obj) | |||
| 5165 | case MEM_TYPE_SPARE: | 5123 | case MEM_TYPE_SPARE: |
| 5166 | return 0; | 5124 | return 0; |
| 5167 | 5125 | ||
| 5168 | case MEM_TYPE_BUFFER: | ||
| 5169 | return live_buffer_p (m, p) ? 1 : 2; | ||
| 5170 | |||
| 5171 | case MEM_TYPE_CONS: | 5126 | case MEM_TYPE_CONS: |
| 5172 | return live_cons_p (m, p); | 5127 | return live_cons_p (m, p); |
| 5173 | 5128 | ||
| @@ -5984,7 +5939,7 @@ maybe_garbage_collect (void) | |||
| 5984 | void | 5939 | void |
| 5985 | garbage_collect (void) | 5940 | garbage_collect (void) |
| 5986 | { | 5941 | { |
| 5987 | struct buffer *nextb; | 5942 | Lisp_Object tail, buffer; |
| 5988 | char stack_top_variable; | 5943 | char stack_top_variable; |
| 5989 | bool message_p; | 5944 | bool message_p; |
| 5990 | ptrdiff_t count = SPECPDL_INDEX (); | 5945 | ptrdiff_t count = SPECPDL_INDEX (); |
| @@ -6000,8 +5955,8 @@ garbage_collect (void) | |||
| 6000 | 5955 | ||
| 6001 | /* Don't keep undo information around forever. | 5956 | /* Don't keep undo information around forever. |
| 6002 | Do this early on, so it is no problem if the user quits. */ | 5957 | Do this early on, so it is no problem if the user quits. */ |
| 6003 | FOR_EACH_BUFFER (nextb) | 5958 | FOR_EACH_LIVE_BUFFER (tail, buffer) |
| 6004 | compact_buffer (nextb); | 5959 | compact_buffer (XBUFFER (buffer)); |
| 6005 | 5960 | ||
| 6006 | byte_ct tot_before = (profiler_memory_running | 5961 | byte_ct tot_before = (profiler_memory_running |
| 6007 | ? total_bytes_of_live_objects () | 5962 | ? total_bytes_of_live_objects () |
| @@ -6091,8 +6046,9 @@ garbage_collect (void) | |||
| 6091 | 6046 | ||
| 6092 | compact_font_caches (); | 6047 | compact_font_caches (); |
| 6093 | 6048 | ||
| 6094 | FOR_EACH_BUFFER (nextb) | 6049 | FOR_EACH_LIVE_BUFFER (tail, buffer) |
| 6095 | { | 6050 | { |
| 6051 | struct buffer *nextb = XBUFFER (buffer); | ||
| 6096 | if (!EQ (BVAR (nextb, undo_list), Qt)) | 6052 | if (!EQ (BVAR (nextb, undo_list), Qt)) |
| 6097 | bset_undo_list (nextb, compact_undo_list (BVAR (nextb, undo_list))); | 6053 | bset_undo_list (nextb, compact_undo_list (BVAR (nextb, undo_list))); |
| 6098 | /* Now that we have stripped the elements that need not be | 6054 | /* Now that we have stripped the elements that need not be |
| @@ -6357,7 +6313,12 @@ mark_buffer (struct buffer *buffer) | |||
| 6357 | 6313 | ||
| 6358 | /* For now, we just don't mark the undo_list. It's done later in | 6314 | /* For now, we just don't mark the undo_list. It's done later in |
| 6359 | a special way just before the sweep phase, and after stripping | 6315 | a special way just before the sweep phase, and after stripping |
| 6360 | some of its elements that are not needed any more. */ | 6316 | some of its elements that are not needed any more. |
| 6317 | Note: this later processing is only done for live buffers, so | ||
| 6318 | for dead buffers, the undo_list should be nil (set by Fkill_buffer), | ||
| 6319 | but just to be on the safe side, we mark it here. */ | ||
| 6320 | if (!BUFFER_LIVE_P (buffer)) | ||
| 6321 | mark_object (BVAR (buffer, undo_list)); | ||
| 6361 | 6322 | ||
| 6362 | mark_overlay (buffer->overlays_before); | 6323 | mark_overlay (buffer->overlays_before); |
| 6363 | mark_overlay (buffer->overlays_after); | 6324 | mark_overlay (buffer->overlays_after); |
| @@ -6621,23 +6582,12 @@ mark_object (Lisp_Object arg) | |||
| 6621 | = PSEUDOVECTOR_TYPE (ptr); | 6582 | = PSEUDOVECTOR_TYPE (ptr); |
| 6622 | 6583 | ||
| 6623 | if (pvectype != PVEC_SUBR && | 6584 | if (pvectype != PVEC_SUBR && |
| 6624 | pvectype != PVEC_BUFFER && | ||
| 6625 | !main_thread_p (po)) | 6585 | !main_thread_p (po)) |
| 6626 | CHECK_LIVE (live_vector_p); | 6586 | CHECK_LIVE (live_vector_p); |
| 6627 | 6587 | ||
| 6628 | switch (pvectype) | 6588 | switch (pvectype) |
| 6629 | { | 6589 | { |
| 6630 | case PVEC_BUFFER: | 6590 | case PVEC_BUFFER: |
| 6631 | #if GC_CHECK_MARKED_OBJECTS | ||
| 6632 | { | ||
| 6633 | struct buffer *b; | ||
| 6634 | FOR_EACH_BUFFER (b) | ||
| 6635 | if (b == po) | ||
| 6636 | break; | ||
| 6637 | if (b == NULL) | ||
| 6638 | emacs_abort (); | ||
| 6639 | } | ||
| 6640 | #endif /* GC_CHECK_MARKED_OBJECTS */ | ||
| 6641 | mark_buffer ((struct buffer *) ptr); | 6591 | mark_buffer ((struct buffer *) ptr); |
| 6642 | break; | 6592 | break; |
| 6643 | 6593 | ||
| @@ -7126,25 +7076,17 @@ NO_INLINE /* For better stack traces */ | |||
| 7126 | static void | 7076 | static void |
| 7127 | sweep_buffers (void) | 7077 | sweep_buffers (void) |
| 7128 | { | 7078 | { |
| 7129 | struct buffer *buffer, **bprev = &all_buffers; | 7079 | Lisp_Object tail, buf; |
| 7130 | 7080 | ||
| 7131 | gcstat.total_buffers = 0; | 7081 | gcstat.total_buffers = 0; |
| 7132 | for (buffer = all_buffers; buffer; buffer = *bprev) | 7082 | FOR_EACH_LIVE_BUFFER (tail, buf) |
| 7133 | if (!vectorlike_marked_p (&buffer->header)) | 7083 | { |
| 7134 | { | 7084 | struct buffer *buffer = XBUFFER (buf); |
| 7135 | *bprev = buffer->next; | 7085 | /* Do not use buffer_(set|get)_intervals here. */ |
| 7136 | lisp_free (buffer); | 7086 | buffer->text->intervals = balance_intervals (buffer->text->intervals); |
| 7137 | } | 7087 | unchain_dead_markers (buffer); |
| 7138 | else | 7088 | gcstat.total_buffers++; |
| 7139 | { | 7089 | } |
| 7140 | if (!pdumper_object_p (buffer)) | ||
| 7141 | XUNMARK_VECTOR (buffer); | ||
| 7142 | /* Do not use buffer_(set|get)_intervals here. */ | ||
| 7143 | buffer->text->intervals = balance_intervals (buffer->text->intervals); | ||
| 7144 | unchain_dead_markers (buffer); | ||
| 7145 | gcstat.total_buffers++; | ||
| 7146 | bprev = &buffer->next; | ||
| 7147 | } | ||
| 7148 | } | 7090 | } |
| 7149 | 7091 | ||
| 7150 | /* Sweep: find all structures not marked, and free them. */ | 7092 | /* Sweep: find all structures not marked, and free them. */ |