diff options
| author | Kenichi Handa | 2012-09-30 23:39:46 +0900 |
|---|---|---|
| committer | Kenichi Handa | 2012-09-30 23:39:46 +0900 |
| commit | c194970e15b6d6efa07697679a25dfab3aa76442 (patch) | |
| tree | 49aec8be9d2dcc74ad3c81f562e48308d8e27b75 /src/alloc.c | |
| parent | 95402d5faa114a311cabfb8c64cf22a93787a066 (diff) | |
| parent | dd946752ab8810149a66a3eff469eb128709972d (diff) | |
| download | emacs-c194970e15b6d6efa07697679a25dfab3aa76442.tar.gz emacs-c194970e15b6d6efa07697679a25dfab3aa76442.zip | |
merge trunk
Diffstat (limited to 'src/alloc.c')
| -rw-r--r-- | src/alloc.c | 77 |
1 files changed, 62 insertions, 15 deletions
diff --git a/src/alloc.c b/src/alloc.c index 02ba2f5f9e3..df166b4924a 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -205,6 +205,7 @@ static Lisp_Object Qintervals; | |||
| 205 | static Lisp_Object Qbuffers; | 205 | static Lisp_Object Qbuffers; |
| 206 | static Lisp_Object Qstring_bytes, Qvector_slots, Qheap; | 206 | static Lisp_Object Qstring_bytes, Qvector_slots, Qheap; |
| 207 | static Lisp_Object Qgc_cons_threshold; | 207 | static Lisp_Object Qgc_cons_threshold; |
| 208 | Lisp_Object Qautomatic_gc; | ||
| 208 | Lisp_Object Qchar_table_extra_slots; | 209 | Lisp_Object Qchar_table_extra_slots; |
| 209 | 210 | ||
| 210 | /* Hook run after GC has finished. */ | 211 | /* Hook run after GC has finished. */ |
| @@ -633,13 +634,13 @@ static void | |||
| 633 | malloc_block_input (void) | 634 | malloc_block_input (void) |
| 634 | { | 635 | { |
| 635 | if (block_input_in_memory_allocators) | 636 | if (block_input_in_memory_allocators) |
| 636 | BLOCK_INPUT; | 637 | block_input (); |
| 637 | } | 638 | } |
| 638 | static void | 639 | static void |
| 639 | malloc_unblock_input (void) | 640 | malloc_unblock_input (void) |
| 640 | { | 641 | { |
| 641 | if (block_input_in_memory_allocators) | 642 | if (block_input_in_memory_allocators) |
| 642 | UNBLOCK_INPUT; | 643 | unblock_input (); |
| 643 | } | 644 | } |
| 644 | # define MALLOC_BLOCK_INPUT malloc_block_input () | 645 | # define MALLOC_BLOCK_INPUT malloc_block_input () |
| 645 | # define MALLOC_UNBLOCK_INPUT malloc_unblock_input () | 646 | # define MALLOC_UNBLOCK_INPUT malloc_unblock_input () |
| @@ -648,6 +649,13 @@ malloc_unblock_input (void) | |||
| 648 | # define MALLOC_UNBLOCK_INPUT ((void) 0) | 649 | # define MALLOC_UNBLOCK_INPUT ((void) 0) |
| 649 | #endif | 650 | #endif |
| 650 | 651 | ||
| 652 | #define MALLOC_PROBE(size) \ | ||
| 653 | do { \ | ||
| 654 | if (profiler_memory_running) \ | ||
| 655 | malloc_probe (size); \ | ||
| 656 | } while (0) | ||
| 657 | |||
| 658 | |||
| 651 | /* Like malloc but check for no memory and block interrupt input.. */ | 659 | /* Like malloc but check for no memory and block interrupt input.. */ |
| 652 | 660 | ||
| 653 | void * | 661 | void * |
| @@ -661,6 +669,7 @@ xmalloc (size_t size) | |||
| 661 | 669 | ||
| 662 | if (!val && size) | 670 | if (!val && size) |
| 663 | memory_full (size); | 671 | memory_full (size); |
| 672 | MALLOC_PROBE (size); | ||
| 664 | return val; | 673 | return val; |
| 665 | } | 674 | } |
| 666 | 675 | ||
| @@ -678,6 +687,7 @@ xzalloc (size_t size) | |||
| 678 | if (!val && size) | 687 | if (!val && size) |
| 679 | memory_full (size); | 688 | memory_full (size); |
| 680 | memset (val, 0, size); | 689 | memset (val, 0, size); |
| 690 | MALLOC_PROBE (size); | ||
| 681 | return val; | 691 | return val; |
| 682 | } | 692 | } |
| 683 | 693 | ||
| @@ -699,6 +709,7 @@ xrealloc (void *block, size_t size) | |||
| 699 | 709 | ||
| 700 | if (!val && size) | 710 | if (!val && size) |
| 701 | memory_full (size); | 711 | memory_full (size); |
| 712 | MALLOC_PROBE (size); | ||
| 702 | return val; | 713 | return val; |
| 703 | } | 714 | } |
| 704 | 715 | ||
| @@ -888,6 +899,7 @@ lisp_malloc (size_t nbytes, enum mem_type type) | |||
| 888 | MALLOC_UNBLOCK_INPUT; | 899 | MALLOC_UNBLOCK_INPUT; |
| 889 | if (!val && nbytes) | 900 | if (!val && nbytes) |
| 890 | memory_full (nbytes); | 901 | memory_full (nbytes); |
| 902 | MALLOC_PROBE (nbytes); | ||
| 891 | return val; | 903 | return val; |
| 892 | } | 904 | } |
| 893 | 905 | ||
| @@ -1093,6 +1105,8 @@ lisp_align_malloc (size_t nbytes, enum mem_type type) | |||
| 1093 | 1105 | ||
| 1094 | MALLOC_UNBLOCK_INPUT; | 1106 | MALLOC_UNBLOCK_INPUT; |
| 1095 | 1107 | ||
| 1108 | MALLOC_PROBE (nbytes); | ||
| 1109 | |||
| 1096 | eassert (0 == ((uintptr_t) val) % BLOCK_ALIGN); | 1110 | eassert (0 == ((uintptr_t) val) % BLOCK_ALIGN); |
| 1097 | return val; | 1111 | return val; |
| 1098 | } | 1112 | } |
| @@ -5043,6 +5057,23 @@ bounded_number (EMACS_INT number) | |||
| 5043 | return make_number (min (MOST_POSITIVE_FIXNUM, number)); | 5057 | return make_number (min (MOST_POSITIVE_FIXNUM, number)); |
| 5044 | } | 5058 | } |
| 5045 | 5059 | ||
| 5060 | /* Calculate total bytes of live objects. */ | ||
| 5061 | |||
| 5062 | static size_t | ||
| 5063 | total_bytes_of_live_objects (void) | ||
| 5064 | { | ||
| 5065 | size_t tot = 0; | ||
| 5066 | tot += total_conses * sizeof (struct Lisp_Cons); | ||
| 5067 | tot += total_symbols * sizeof (struct Lisp_Symbol); | ||
| 5068 | tot += total_markers * sizeof (union Lisp_Misc); | ||
| 5069 | tot += total_string_bytes; | ||
| 5070 | tot += total_vector_slots * word_size; | ||
| 5071 | tot += total_floats * sizeof (struct Lisp_Float); | ||
| 5072 | tot += total_intervals * sizeof (struct interval); | ||
| 5073 | tot += total_strings * sizeof (struct Lisp_String); | ||
| 5074 | return tot; | ||
| 5075 | } | ||
| 5076 | |||
| 5046 | DEFUN ("garbage-collect", Fgarbage_collect, Sgarbage_collect, 0, 0, "", | 5077 | DEFUN ("garbage-collect", Fgarbage_collect, Sgarbage_collect, 0, 0, "", |
| 5047 | doc: /* Reclaim storage for Lisp objects no longer needed. | 5078 | doc: /* Reclaim storage for Lisp objects no longer needed. |
| 5048 | Garbage collection happens automatically if you cons more than | 5079 | Garbage collection happens automatically if you cons more than |
| @@ -5068,6 +5099,8 @@ See Info node `(elisp)Garbage Collection'. */) | |||
| 5068 | ptrdiff_t count = SPECPDL_INDEX (); | 5099 | ptrdiff_t count = SPECPDL_INDEX (); |
| 5069 | EMACS_TIME start; | 5100 | EMACS_TIME start; |
| 5070 | Lisp_Object retval = Qnil; | 5101 | Lisp_Object retval = Qnil; |
| 5102 | size_t tot_before = 0; | ||
| 5103 | struct backtrace backtrace; | ||
| 5071 | 5104 | ||
| 5072 | if (abort_on_gc) | 5105 | if (abort_on_gc) |
| 5073 | emacs_abort (); | 5106 | emacs_abort (); |
| @@ -5077,6 +5110,14 @@ See Info node `(elisp)Garbage Collection'. */) | |||
| 5077 | if (pure_bytes_used_before_overflow) | 5110 | if (pure_bytes_used_before_overflow) |
| 5078 | return Qnil; | 5111 | return Qnil; |
| 5079 | 5112 | ||
| 5113 | /* Record this function, so it appears on the profiler's backtraces. */ | ||
| 5114 | backtrace.next = backtrace_list; | ||
| 5115 | backtrace.function = Qautomatic_gc; | ||
| 5116 | backtrace.args = &Qnil; | ||
| 5117 | backtrace.nargs = 0; | ||
| 5118 | backtrace.debug_on_exit = 0; | ||
| 5119 | backtrace_list = &backtrace; | ||
| 5120 | |||
| 5080 | check_cons_list (); | 5121 | check_cons_list (); |
| 5081 | 5122 | ||
| 5082 | /* Don't keep undo information around forever. | 5123 | /* Don't keep undo information around forever. |
| @@ -5084,6 +5125,9 @@ See Info node `(elisp)Garbage Collection'. */) | |||
| 5084 | FOR_EACH_BUFFER (nextb) | 5125 | FOR_EACH_BUFFER (nextb) |
| 5085 | compact_buffer (nextb); | 5126 | compact_buffer (nextb); |
| 5086 | 5127 | ||
| 5128 | if (profiler_memory_running) | ||
| 5129 | tot_before = total_bytes_of_live_objects (); | ||
| 5130 | |||
| 5087 | start = current_emacs_time (); | 5131 | start = current_emacs_time (); |
| 5088 | 5132 | ||
| 5089 | /* In case user calls debug_print during GC, | 5133 | /* In case user calls debug_print during GC, |
| @@ -5125,7 +5169,7 @@ See Info node `(elisp)Garbage Collection'. */) | |||
| 5125 | if (garbage_collection_messages) | 5169 | if (garbage_collection_messages) |
| 5126 | message1_nolog ("Garbage collecting..."); | 5170 | message1_nolog ("Garbage collecting..."); |
| 5127 | 5171 | ||
| 5128 | BLOCK_INPUT; | 5172 | block_input (); |
| 5129 | 5173 | ||
| 5130 | shrink_regexp_cache (); | 5174 | shrink_regexp_cache (); |
| 5131 | 5175 | ||
| @@ -5242,7 +5286,7 @@ See Info node `(elisp)Garbage Collection'. */) | |||
| 5242 | dump_zombies (); | 5286 | dump_zombies (); |
| 5243 | #endif | 5287 | #endif |
| 5244 | 5288 | ||
| 5245 | UNBLOCK_INPUT; | 5289 | unblock_input (); |
| 5246 | 5290 | ||
| 5247 | check_cons_list (); | 5291 | check_cons_list (); |
| 5248 | 5292 | ||
| @@ -5255,16 +5299,7 @@ See Info node `(elisp)Garbage Collection'. */) | |||
| 5255 | gc_relative_threshold = 0; | 5299 | gc_relative_threshold = 0; |
| 5256 | if (FLOATP (Vgc_cons_percentage)) | 5300 | if (FLOATP (Vgc_cons_percentage)) |
| 5257 | { /* Set gc_cons_combined_threshold. */ | 5301 | { /* Set gc_cons_combined_threshold. */ |
| 5258 | double tot = 0; | 5302 | double tot = total_bytes_of_live_objects (); |
| 5259 | |||
| 5260 | tot += total_conses * sizeof (struct Lisp_Cons); | ||
| 5261 | tot += total_symbols * sizeof (struct Lisp_Symbol); | ||
| 5262 | tot += total_markers * sizeof (union Lisp_Misc); | ||
| 5263 | tot += total_string_bytes; | ||
| 5264 | tot += total_vector_slots * word_size; | ||
| 5265 | tot += total_floats * sizeof (struct Lisp_Float); | ||
| 5266 | tot += total_intervals * sizeof (struct interval); | ||
| 5267 | tot += total_strings * sizeof (struct Lisp_String); | ||
| 5268 | 5303 | ||
| 5269 | tot *= XFLOAT_DATA (Vgc_cons_percentage); | 5304 | tot *= XFLOAT_DATA (Vgc_cons_percentage); |
| 5270 | if (0 < tot) | 5305 | if (0 < tot) |
| @@ -5367,6 +5402,17 @@ See Info node `(elisp)Garbage Collection'. */) | |||
| 5367 | 5402 | ||
| 5368 | gcs_done++; | 5403 | gcs_done++; |
| 5369 | 5404 | ||
| 5405 | /* Collect profiling data. */ | ||
| 5406 | if (profiler_memory_running) | ||
| 5407 | { | ||
| 5408 | size_t swept = 0; | ||
| 5409 | size_t tot_after = total_bytes_of_live_objects (); | ||
| 5410 | if (tot_before > tot_after) | ||
| 5411 | swept = tot_before - tot_after; | ||
| 5412 | malloc_probe (swept); | ||
| 5413 | } | ||
| 5414 | |||
| 5415 | backtrace_list = backtrace.next; | ||
| 5370 | return retval; | 5416 | return retval; |
| 5371 | } | 5417 | } |
| 5372 | 5418 | ||
| @@ -6395,7 +6441,7 @@ die (const char *msg, const char *file, int line) | |||
| 6395 | { | 6441 | { |
| 6396 | fprintf (stderr, "\r\n%s:%d: Emacs fatal error: %s\r\n", | 6442 | fprintf (stderr, "\r\n%s:%d: Emacs fatal error: %s\r\n", |
| 6397 | file, line, msg); | 6443 | file, line, msg); |
| 6398 | fatal_error_backtrace (SIGABRT, INT_MAX); | 6444 | terminate_due_to_signal (SIGABRT, INT_MAX); |
| 6399 | } | 6445 | } |
| 6400 | #endif | 6446 | #endif |
| 6401 | 6447 | ||
| @@ -6527,6 +6573,7 @@ do hash-consing of the objects allocated to pure space. */); | |||
| 6527 | DEFSYM (Qstring_bytes, "string-bytes"); | 6573 | DEFSYM (Qstring_bytes, "string-bytes"); |
| 6528 | DEFSYM (Qvector_slots, "vector-slots"); | 6574 | DEFSYM (Qvector_slots, "vector-slots"); |
| 6529 | DEFSYM (Qheap, "heap"); | 6575 | DEFSYM (Qheap, "heap"); |
| 6576 | DEFSYM (Qautomatic_gc, "Automatic GC"); | ||
| 6530 | 6577 | ||
| 6531 | DEFSYM (Qgc_cons_threshold, "gc-cons-threshold"); | 6578 | DEFSYM (Qgc_cons_threshold, "gc-cons-threshold"); |
| 6532 | DEFSYM (Qchar_table_extra_slots, "char-table-extra-slots"); | 6579 | DEFSYM (Qchar_table_extra_slots, "char-table-extra-slots"); |