diff options
| author | Stefan Monnier | 2012-09-26 11:19:10 -0400 |
|---|---|---|
| committer | Stefan Monnier | 2012-09-26 11:19:10 -0400 |
| commit | 3a880af4a79688e90da45311a8d85bae2d59a811 (patch) | |
| tree | 178e2f4ac5889ad1de54fc02c967f7acb377ce64 /src/alloc.c | |
| parent | 9180598cb164cf32daf0e1761a8143e720460987 (diff) | |
| parent | 234148bf943ffce55121aefc8694889eb08b0daa (diff) | |
| download | emacs-3a880af4a79688e90da45311a8d85bae2d59a811.tar.gz emacs-3a880af4a79688e90da45311a8d85bae2d59a811.zip | |
Merge profiler branch
Diffstat (limited to 'src/alloc.c')
| -rw-r--r-- | src/alloc.c | 67 |
1 files changed, 57 insertions, 10 deletions
diff --git a/src/alloc.c b/src/alloc.c index 923e8736a86..46c9a10c725 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. */ |
| @@ -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 = &Qautomatic_gc; | ||
| 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, |
| @@ -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 | ||
| @@ -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"); |