diff options
Diffstat (limited to 'src/alloc.c')
| -rw-r--r-- | src/alloc.c | 109 |
1 files changed, 38 insertions, 71 deletions
diff --git a/src/alloc.c b/src/alloc.c index 2a539920f22..9dd5e1abc05 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -99,7 +99,7 @@ extern __malloc_size_t __malloc_extra_blocks; | |||
| 99 | If Emacs sets malloc hooks (! SYSTEM_MALLOC) and the emacs_blocked_* | 99 | If Emacs sets malloc hooks (! SYSTEM_MALLOC) and the emacs_blocked_* |
| 100 | functions below are called from malloc, there is a chance that one | 100 | functions below are called from malloc, there is a chance that one |
| 101 | of these threads preempts the Emacs main thread and the hook variables | 101 | of these threads preempts the Emacs main thread and the hook variables |
| 102 | end up in a inconsistent state. So we have a mutex to prevent that (note | 102 | end up in an inconsistent state. So we have a mutex to prevent that (note |
| 103 | that the backend handles concurrent access to malloc within its own threads | 103 | that the backend handles concurrent access to malloc within its own threads |
| 104 | but Emacs code running in the main thread is not included in that control). | 104 | but Emacs code running in the main thread is not included in that control). |
| 105 | 105 | ||
| @@ -109,7 +109,6 @@ extern __malloc_size_t __malloc_extra_blocks; | |||
| 109 | To prevent that, we only call BLOCK/UNBLOCK from the main thread. */ | 109 | To prevent that, we only call BLOCK/UNBLOCK from the main thread. */ |
| 110 | 110 | ||
| 111 | static pthread_mutex_t alloc_mutex; | 111 | static pthread_mutex_t alloc_mutex; |
| 112 | pthread_t main_thread; | ||
| 113 | 112 | ||
| 114 | #define BLOCK_INPUT_ALLOC \ | 113 | #define BLOCK_INPUT_ALLOC \ |
| 115 | do \ | 114 | do \ |
| @@ -201,12 +200,6 @@ extern | |||
| 201 | #endif /* VIRT_ADDR_VARIES */ | 200 | #endif /* VIRT_ADDR_VARIES */ |
| 202 | int malloc_sbrk_unused; | 201 | int malloc_sbrk_unused; |
| 203 | 202 | ||
| 204 | /* Two limits controlling how much undo information to keep. */ | ||
| 205 | |||
| 206 | EMACS_INT undo_limit; | ||
| 207 | EMACS_INT undo_strong_limit; | ||
| 208 | EMACS_INT undo_outer_limit; | ||
| 209 | |||
| 210 | /* Number of live and free conses etc. */ | 203 | /* Number of live and free conses etc. */ |
| 211 | 204 | ||
| 212 | static int total_conses, total_markers, total_symbols, total_vector_size; | 205 | static int total_conses, total_markers, total_symbols, total_vector_size; |
| @@ -1310,8 +1303,6 @@ uninterrupt_malloc () | |||
| 1310 | pthread_mutexattr_init (&attr); | 1303 | pthread_mutexattr_init (&attr); |
| 1311 | pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE); | 1304 | pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE); |
| 1312 | pthread_mutex_init (&alloc_mutex, &attr); | 1305 | pthread_mutex_init (&alloc_mutex, &attr); |
| 1313 | |||
| 1314 | main_thread = pthread_self (); | ||
| 1315 | #endif /* HAVE_GTK_AND_PTHREAD */ | 1306 | #endif /* HAVE_GTK_AND_PTHREAD */ |
| 1316 | 1307 | ||
| 1317 | if (__free_hook != emacs_blocked_free) | 1308 | if (__free_hook != emacs_blocked_free) |
| @@ -4604,13 +4595,48 @@ returns nil, because real GC can't be done. */) | |||
| 4604 | if (abort_on_gc) | 4595 | if (abort_on_gc) |
| 4605 | abort (); | 4596 | abort (); |
| 4606 | 4597 | ||
| 4607 | EMACS_GET_TIME (t1); | ||
| 4608 | |||
| 4609 | /* Can't GC if pure storage overflowed because we can't determine | 4598 | /* Can't GC if pure storage overflowed because we can't determine |
| 4610 | if something is a pure object or not. */ | 4599 | if something is a pure object or not. */ |
| 4611 | if (pure_bytes_used_before_overflow) | 4600 | if (pure_bytes_used_before_overflow) |
| 4612 | return Qnil; | 4601 | return Qnil; |
| 4613 | 4602 | ||
| 4603 | /* Don't keep undo information around forever. | ||
| 4604 | Do this early on, so it is no problem if the user quits. */ | ||
| 4605 | { | ||
| 4606 | register struct buffer *nextb = all_buffers; | ||
| 4607 | |||
| 4608 | while (nextb) | ||
| 4609 | { | ||
| 4610 | /* If a buffer's undo list is Qt, that means that undo is | ||
| 4611 | turned off in that buffer. Calling truncate_undo_list on | ||
| 4612 | Qt tends to return NULL, which effectively turns undo back on. | ||
| 4613 | So don't call truncate_undo_list if undo_list is Qt. */ | ||
| 4614 | if (! EQ (nextb->undo_list, Qt)) | ||
| 4615 | truncate_undo_list (nextb); | ||
| 4616 | |||
| 4617 | /* Shrink buffer gaps, but skip indirect and dead buffers. */ | ||
| 4618 | if (nextb->base_buffer == 0 && !NILP (nextb->name)) | ||
| 4619 | { | ||
| 4620 | /* If a buffer's gap size is more than 10% of the buffer | ||
| 4621 | size, or larger than 2000 bytes, then shrink it | ||
| 4622 | accordingly. Keep a minimum size of 20 bytes. */ | ||
| 4623 | int size = min (2000, max (20, (nextb->text->z_byte / 10))); | ||
| 4624 | |||
| 4625 | if (nextb->text->gap_size > size) | ||
| 4626 | { | ||
| 4627 | struct buffer *save_current = current_buffer; | ||
| 4628 | current_buffer = nextb; | ||
| 4629 | make_gap (-(nextb->text->gap_size - size)); | ||
| 4630 | current_buffer = save_current; | ||
| 4631 | } | ||
| 4632 | } | ||
| 4633 | |||
| 4634 | nextb = nextb->next; | ||
| 4635 | } | ||
| 4636 | } | ||
| 4637 | |||
| 4638 | EMACS_GET_TIME (t1); | ||
| 4639 | |||
| 4614 | /* In case user calls debug_print during GC, | 4640 | /* In case user calls debug_print during GC, |
| 4615 | don't let that cause a recursive GC. */ | 4641 | don't let that cause a recursive GC. */ |
| 4616 | consing_since_gc = 0; | 4642 | consing_since_gc = 0; |
| @@ -4649,42 +4675,6 @@ returns nil, because real GC can't be done. */) | |||
| 4649 | 4675 | ||
| 4650 | shrink_regexp_cache (); | 4676 | shrink_regexp_cache (); |
| 4651 | 4677 | ||
| 4652 | /* Don't keep undo information around forever. */ | ||
| 4653 | { | ||
| 4654 | register struct buffer *nextb = all_buffers; | ||
| 4655 | |||
| 4656 | while (nextb) | ||
| 4657 | { | ||
| 4658 | /* If a buffer's undo list is Qt, that means that undo is | ||
| 4659 | turned off in that buffer. Calling truncate_undo_list on | ||
| 4660 | Qt tends to return NULL, which effectively turns undo back on. | ||
| 4661 | So don't call truncate_undo_list if undo_list is Qt. */ | ||
| 4662 | if (! EQ (nextb->undo_list, Qt)) | ||
| 4663 | nextb->undo_list | ||
| 4664 | = truncate_undo_list (nextb->undo_list, undo_limit, | ||
| 4665 | undo_strong_limit, undo_outer_limit); | ||
| 4666 | |||
| 4667 | /* Shrink buffer gaps, but skip indirect and dead buffers. */ | ||
| 4668 | if (nextb->base_buffer == 0 && !NILP (nextb->name)) | ||
| 4669 | { | ||
| 4670 | /* If a buffer's gap size is more than 10% of the buffer | ||
| 4671 | size, or larger than 2000 bytes, then shrink it | ||
| 4672 | accordingly. Keep a minimum size of 20 bytes. */ | ||
| 4673 | int size = min (2000, max (20, (nextb->text->z_byte / 10))); | ||
| 4674 | |||
| 4675 | if (nextb->text->gap_size > size) | ||
| 4676 | { | ||
| 4677 | struct buffer *save_current = current_buffer; | ||
| 4678 | current_buffer = nextb; | ||
| 4679 | make_gap (-(nextb->text->gap_size - size)); | ||
| 4680 | current_buffer = save_current; | ||
| 4681 | } | ||
| 4682 | } | ||
| 4683 | |||
| 4684 | nextb = nextb->next; | ||
| 4685 | } | ||
| 4686 | } | ||
| 4687 | |||
| 4688 | gc_in_progress = 1; | 4678 | gc_in_progress = 1; |
| 4689 | 4679 | ||
| 4690 | /* clear_marks (); */ | 4680 | /* clear_marks (); */ |
| @@ -5959,29 +5949,6 @@ prevent garbage collection during a part of the program. */); | |||
| 5959 | doc: /* Non-nil means loading Lisp code in order to dump an executable. | 5949 | doc: /* Non-nil means loading Lisp code in order to dump an executable. |
| 5960 | This means that certain objects should be allocated in shared (pure) space. */); | 5950 | This means that certain objects should be allocated in shared (pure) space. */); |
| 5961 | 5951 | ||
| 5962 | DEFVAR_INT ("undo-limit", &undo_limit, | ||
| 5963 | doc: /* Keep no more undo information once it exceeds this size. | ||
| 5964 | This limit is applied when garbage collection happens. | ||
| 5965 | The size is counted as the number of bytes occupied, | ||
| 5966 | which includes both saved text and other data. */); | ||
| 5967 | undo_limit = 20000; | ||
| 5968 | |||
| 5969 | DEFVAR_INT ("undo-strong-limit", &undo_strong_limit, | ||
| 5970 | doc: /* Don't keep more than this much size of undo information. | ||
| 5971 | A previous command which pushes the undo list past this size | ||
| 5972 | is entirely forgotten when GC happens. | ||
| 5973 | The size is counted as the number of bytes occupied, | ||
| 5974 | which includes both saved text and other data. */); | ||
| 5975 | undo_strong_limit = 30000; | ||
| 5976 | |||
| 5977 | DEFVAR_INT ("undo-outer-limit", &undo_outer_limit, | ||
| 5978 | doc: /* Don't keep more than this much size of undo information. | ||
| 5979 | If the current command has produced more than this much undo information, | ||
| 5980 | GC discards it. This is a last-ditch limit to prevent memory overflow. | ||
| 5981 | The size is counted as the number of bytes occupied, | ||
| 5982 | which includes both saved text and other data. */); | ||
| 5983 | undo_outer_limit = 300000; | ||
| 5984 | |||
| 5985 | DEFVAR_BOOL ("garbage-collection-messages", &garbage_collection_messages, | 5952 | DEFVAR_BOOL ("garbage-collection-messages", &garbage_collection_messages, |
| 5986 | doc: /* Non-nil means display messages at start and end of garbage collection. */); | 5953 | doc: /* Non-nil means display messages at start and end of garbage collection. */); |
| 5987 | garbage_collection_messages = 0; | 5954 | garbage_collection_messages = 0; |