aboutsummaryrefslogtreecommitdiffstats
path: root/src/alloc.c
diff options
context:
space:
mode:
authorDaniel Colascione2012-10-07 14:31:58 -0800
committerDaniel Colascione2012-10-07 14:31:58 -0800
commit36a305a723c63fd345be65c536c52fe9765c14be (patch)
treefb89d9e103552863214c60297a65320917109357 /src/alloc.c
parent2ab329f3b5d52a39f0a45c3d9c129f1c19560142 (diff)
parent795b1482a9e314cda32d62ac2988f573d359366e (diff)
downloademacs-36a305a723c63fd345be65c536c52fe9765c14be.tar.gz
emacs-36a305a723c63fd345be65c536c52fe9765c14be.zip
Merge from trunk
Diffstat (limited to 'src/alloc.c')
-rw-r--r--src/alloc.c130
1 files changed, 90 insertions, 40 deletions
diff --git a/src/alloc.c b/src/alloc.c
index fb7d35b5590..3ed8cc2d990 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -74,6 +74,7 @@ extern void *sbrk ();
74#endif 74#endif
75#ifdef WINDOWSNT 75#ifdef WINDOWSNT
76#include "w32.h" 76#include "w32.h"
77#include "w32heap.h" /* for sbrk */
77#endif 78#endif
78 79
79#ifdef DOUG_LEA_MALLOC 80#ifdef DOUG_LEA_MALLOC
@@ -205,6 +206,7 @@ static Lisp_Object Qintervals;
205static Lisp_Object Qbuffers; 206static Lisp_Object Qbuffers;
206static Lisp_Object Qstring_bytes, Qvector_slots, Qheap; 207static Lisp_Object Qstring_bytes, Qvector_slots, Qheap;
207static Lisp_Object Qgc_cons_threshold; 208static Lisp_Object Qgc_cons_threshold;
209Lisp_Object Qautomatic_gc;
208Lisp_Object Qchar_table_extra_slots; 210Lisp_Object Qchar_table_extra_slots;
209 211
210/* Hook run after GC has finished. */ 212/* Hook run after GC has finished. */
@@ -353,7 +355,7 @@ static void mem_rotate_left (struct mem_node *);
353static void mem_rotate_right (struct mem_node *); 355static void mem_rotate_right (struct mem_node *);
354static void mem_delete (struct mem_node *); 356static void mem_delete (struct mem_node *);
355static void mem_delete_fixup (struct mem_node *); 357static void mem_delete_fixup (struct mem_node *);
356static inline struct mem_node *mem_find (void *); 358static struct mem_node *mem_find (void *);
357#endif 359#endif
358 360
359 361
@@ -633,13 +635,13 @@ static void
633malloc_block_input (void) 635malloc_block_input (void)
634{ 636{
635 if (block_input_in_memory_allocators) 637 if (block_input_in_memory_allocators)
636 BLOCK_INPUT; 638 block_input ();
637} 639}
638static void 640static void
639malloc_unblock_input (void) 641malloc_unblock_input (void)
640{ 642{
641 if (block_input_in_memory_allocators) 643 if (block_input_in_memory_allocators)
642 UNBLOCK_INPUT; 644 unblock_input ();
643} 645}
644# define MALLOC_BLOCK_INPUT malloc_block_input () 646# define MALLOC_BLOCK_INPUT malloc_block_input ()
645# define MALLOC_UNBLOCK_INPUT malloc_unblock_input () 647# define MALLOC_UNBLOCK_INPUT malloc_unblock_input ()
@@ -648,6 +650,13 @@ malloc_unblock_input (void)
648# define MALLOC_UNBLOCK_INPUT ((void) 0) 650# define MALLOC_UNBLOCK_INPUT ((void) 0)
649#endif 651#endif
650 652
653#define MALLOC_PROBE(size) \
654 do { \
655 if (profiler_memory_running) \
656 malloc_probe (size); \
657 } while (0)
658
659
651/* Like malloc but check for no memory and block interrupt input.. */ 660/* Like malloc but check for no memory and block interrupt input.. */
652 661
653void * 662void *
@@ -661,6 +670,7 @@ xmalloc (size_t size)
661 670
662 if (!val && size) 671 if (!val && size)
663 memory_full (size); 672 memory_full (size);
673 MALLOC_PROBE (size);
664 return val; 674 return val;
665} 675}
666 676
@@ -678,6 +688,7 @@ xzalloc (size_t size)
678 if (!val && size) 688 if (!val && size)
679 memory_full (size); 689 memory_full (size);
680 memset (val, 0, size); 690 memset (val, 0, size);
691 MALLOC_PROBE (size);
681 return val; 692 return val;
682} 693}
683 694
@@ -699,6 +710,7 @@ xrealloc (void *block, size_t size)
699 710
700 if (!val && size) 711 if (!val && size)
701 memory_full (size); 712 memory_full (size);
713 MALLOC_PROBE (size);
702 return val; 714 return val;
703} 715}
704 716
@@ -888,6 +900,7 @@ lisp_malloc (size_t nbytes, enum mem_type type)
888 MALLOC_UNBLOCK_INPUT; 900 MALLOC_UNBLOCK_INPUT;
889 if (!val && nbytes) 901 if (!val && nbytes)
890 memory_full (nbytes); 902 memory_full (nbytes);
903 MALLOC_PROBE (nbytes);
891 return val; 904 return val;
892} 905}
893 906
@@ -1093,6 +1106,8 @@ lisp_align_malloc (size_t nbytes, enum mem_type type)
1093 1106
1094 MALLOC_UNBLOCK_INPUT; 1107 MALLOC_UNBLOCK_INPUT;
1095 1108
1109 MALLOC_PROBE (nbytes);
1110
1096 eassert (0 == ((uintptr_t) val) % BLOCK_ALIGN); 1111 eassert (0 == ((uintptr_t) val) % BLOCK_ALIGN);
1097 return val; 1112 return val;
1098} 1113}
@@ -3535,7 +3550,7 @@ mem_init (void)
3535/* Value is a pointer to the mem_node containing START. Value is 3550/* Value is a pointer to the mem_node containing START. Value is
3536 MEM_NIL if there is no node in the tree containing START. */ 3551 MEM_NIL if there is no node in the tree containing START. */
3537 3552
3538static inline struct mem_node * 3553static struct mem_node *
3539mem_find (void *start) 3554mem_find (void *start)
3540{ 3555{
3541 struct mem_node *p; 3556 struct mem_node *p;
@@ -3911,7 +3926,7 @@ mem_delete_fixup (struct mem_node *x)
3911/* Value is non-zero if P is a pointer to a live Lisp string on 3926/* Value is non-zero if P is a pointer to a live Lisp string on
3912 the heap. M is a pointer to the mem_block for P. */ 3927 the heap. M is a pointer to the mem_block for P. */
3913 3928
3914static inline bool 3929static bool
3915live_string_p (struct mem_node *m, void *p) 3930live_string_p (struct mem_node *m, void *p)
3916{ 3931{
3917 if (m->type == MEM_TYPE_STRING) 3932 if (m->type == MEM_TYPE_STRING)
@@ -3934,7 +3949,7 @@ live_string_p (struct mem_node *m, void *p)
3934/* Value is non-zero if P is a pointer to a live Lisp cons on 3949/* Value is non-zero if P is a pointer to a live Lisp cons on
3935 the heap. M is a pointer to the mem_block for P. */ 3950 the heap. M is a pointer to the mem_block for P. */
3936 3951
3937static inline bool 3952static bool
3938live_cons_p (struct mem_node *m, void *p) 3953live_cons_p (struct mem_node *m, void *p)
3939{ 3954{
3940 if (m->type == MEM_TYPE_CONS) 3955 if (m->type == MEM_TYPE_CONS)
@@ -3960,7 +3975,7 @@ live_cons_p (struct mem_node *m, void *p)
3960/* Value is non-zero if P is a pointer to a live Lisp symbol on 3975/* Value is non-zero if P is a pointer to a live Lisp symbol on
3961 the heap. M is a pointer to the mem_block for P. */ 3976 the heap. M is a pointer to the mem_block for P. */
3962 3977
3963static inline bool 3978static bool
3964live_symbol_p (struct mem_node *m, void *p) 3979live_symbol_p (struct mem_node *m, void *p)
3965{ 3980{
3966 if (m->type == MEM_TYPE_SYMBOL) 3981 if (m->type == MEM_TYPE_SYMBOL)
@@ -3986,7 +4001,7 @@ live_symbol_p (struct mem_node *m, void *p)
3986/* Value is non-zero if P is a pointer to a live Lisp float on 4001/* Value is non-zero if P is a pointer to a live Lisp float on
3987 the heap. M is a pointer to the mem_block for P. */ 4002 the heap. M is a pointer to the mem_block for P. */
3988 4003
3989static inline bool 4004static bool
3990live_float_p (struct mem_node *m, void *p) 4005live_float_p (struct mem_node *m, void *p)
3991{ 4006{
3992 if (m->type == MEM_TYPE_FLOAT) 4007 if (m->type == MEM_TYPE_FLOAT)
@@ -4010,7 +4025,7 @@ live_float_p (struct mem_node *m, void *p)
4010/* Value is non-zero if P is a pointer to a live Lisp Misc on 4025/* Value is non-zero if P is a pointer to a live Lisp Misc on
4011 the heap. M is a pointer to the mem_block for P. */ 4026 the heap. M is a pointer to the mem_block for P. */
4012 4027
4013static inline bool 4028static bool
4014live_misc_p (struct mem_node *m, void *p) 4029live_misc_p (struct mem_node *m, void *p)
4015{ 4030{
4016 if (m->type == MEM_TYPE_MISC) 4031 if (m->type == MEM_TYPE_MISC)
@@ -4036,7 +4051,7 @@ live_misc_p (struct mem_node *m, void *p)
4036/* Value is non-zero if P is a pointer to a live vector-like object. 4051/* Value is non-zero if P is a pointer to a live vector-like object.
4037 M is a pointer to the mem_block for P. */ 4052 M is a pointer to the mem_block for P. */
4038 4053
4039static inline bool 4054static bool
4040live_vector_p (struct mem_node *m, void *p) 4055live_vector_p (struct mem_node *m, void *p)
4041{ 4056{
4042 if (m->type == MEM_TYPE_VECTOR_BLOCK) 4057 if (m->type == MEM_TYPE_VECTOR_BLOCK)
@@ -4072,7 +4087,7 @@ live_vector_p (struct mem_node *m, void *p)
4072/* Value is non-zero if P is a pointer to a live buffer. M is a 4087/* Value is non-zero if P is a pointer to a live buffer. M is a
4073 pointer to the mem_block for P. */ 4088 pointer to the mem_block for P. */
4074 4089
4075static inline bool 4090static bool
4076live_buffer_p (struct mem_node *m, void *p) 4091live_buffer_p (struct mem_node *m, void *p)
4077{ 4092{
4078 /* P must point to the start of the block, and the buffer 4093 /* P must point to the start of the block, and the buffer
@@ -4138,7 +4153,7 @@ DEFUN ("gc-status", Fgc_status, Sgc_status, 0, 0, "",
4138 4153
4139/* Mark OBJ if we can prove it's a Lisp_Object. */ 4154/* Mark OBJ if we can prove it's a Lisp_Object. */
4140 4155
4141static inline void 4156static void
4142mark_maybe_object (Lisp_Object obj) 4157mark_maybe_object (Lisp_Object obj)
4143{ 4158{
4144 void *po; 4159 void *po;
@@ -4207,7 +4222,7 @@ mark_maybe_object (Lisp_Object obj)
4207/* If P points to Lisp data, mark that as live if it isn't already 4222/* If P points to Lisp data, mark that as live if it isn't already
4208 marked. */ 4223 marked. */
4209 4224
4210static inline void 4225static void
4211mark_maybe_pointer (void *p) 4226mark_maybe_pointer (void *p)
4212{ 4227{
4213 struct mem_node *m; 4228 struct mem_node *m;
@@ -5037,12 +5052,29 @@ inhibit_garbage_collection (void)
5037/* Used to avoid possible overflows when 5052/* Used to avoid possible overflows when
5038 converting from C to Lisp integers. */ 5053 converting from C to Lisp integers. */
5039 5054
5040static inline Lisp_Object 5055static Lisp_Object
5041bounded_number (EMACS_INT number) 5056bounded_number (EMACS_INT number)
5042{ 5057{
5043 return make_number (min (MOST_POSITIVE_FIXNUM, number)); 5058 return make_number (min (MOST_POSITIVE_FIXNUM, number));
5044} 5059}
5045 5060
5061/* Calculate total bytes of live objects. */
5062
5063static size_t
5064total_bytes_of_live_objects (void)
5065{
5066 size_t tot = 0;
5067 tot += total_conses * sizeof (struct Lisp_Cons);
5068 tot += total_symbols * sizeof (struct Lisp_Symbol);
5069 tot += total_markers * sizeof (union Lisp_Misc);
5070 tot += total_string_bytes;
5071 tot += total_vector_slots * word_size;
5072 tot += total_floats * sizeof (struct Lisp_Float);
5073 tot += total_intervals * sizeof (struct interval);
5074 tot += total_strings * sizeof (struct Lisp_String);
5075 return tot;
5076}
5077
5046DEFUN ("garbage-collect", Fgarbage_collect, Sgarbage_collect, 0, 0, "", 5078DEFUN ("garbage-collect", Fgarbage_collect, Sgarbage_collect, 0, 0, "",
5047 doc: /* Reclaim storage for Lisp objects no longer needed. 5079 doc: /* Reclaim storage for Lisp objects no longer needed.
5048Garbage collection happens automatically if you cons more than 5080Garbage collection happens automatically if you cons more than
@@ -5068,6 +5100,8 @@ See Info node `(elisp)Garbage Collection'. */)
5068 ptrdiff_t count = SPECPDL_INDEX (); 5100 ptrdiff_t count = SPECPDL_INDEX ();
5069 EMACS_TIME start; 5101 EMACS_TIME start;
5070 Lisp_Object retval = Qnil; 5102 Lisp_Object retval = Qnil;
5103 size_t tot_before = 0;
5104 struct backtrace backtrace;
5071 5105
5072 if (abort_on_gc) 5106 if (abort_on_gc)
5073 emacs_abort (); 5107 emacs_abort ();
@@ -5077,6 +5111,14 @@ See Info node `(elisp)Garbage Collection'. */)
5077 if (pure_bytes_used_before_overflow) 5111 if (pure_bytes_used_before_overflow)
5078 return Qnil; 5112 return Qnil;
5079 5113
5114 /* Record this function, so it appears on the profiler's backtraces. */
5115 backtrace.next = backtrace_list;
5116 backtrace.function = Qautomatic_gc;
5117 backtrace.args = &Qnil;
5118 backtrace.nargs = 0;
5119 backtrace.debug_on_exit = 0;
5120 backtrace_list = &backtrace;
5121
5080 check_cons_list (); 5122 check_cons_list ();
5081 5123
5082 /* Don't keep undo information around forever. 5124 /* Don't keep undo information around forever.
@@ -5084,6 +5126,9 @@ See Info node `(elisp)Garbage Collection'. */)
5084 FOR_EACH_BUFFER (nextb) 5126 FOR_EACH_BUFFER (nextb)
5085 compact_buffer (nextb); 5127 compact_buffer (nextb);
5086 5128
5129 if (profiler_memory_running)
5130 tot_before = total_bytes_of_live_objects ();
5131
5087 start = current_emacs_time (); 5132 start = current_emacs_time ();
5088 5133
5089 /* In case user calls debug_print during GC, 5134 /* In case user calls debug_print during GC,
@@ -5125,7 +5170,7 @@ See Info node `(elisp)Garbage Collection'. */)
5125 if (garbage_collection_messages) 5170 if (garbage_collection_messages)
5126 message1_nolog ("Garbage collecting..."); 5171 message1_nolog ("Garbage collecting...");
5127 5172
5128 BLOCK_INPUT; 5173 block_input ();
5129 5174
5130 shrink_regexp_cache (); 5175 shrink_regexp_cache ();
5131 5176
@@ -5242,7 +5287,7 @@ See Info node `(elisp)Garbage Collection'. */)
5242 dump_zombies (); 5287 dump_zombies ();
5243#endif 5288#endif
5244 5289
5245 UNBLOCK_INPUT; 5290 unblock_input ();
5246 5291
5247 check_cons_list (); 5292 check_cons_list ();
5248 5293
@@ -5255,16 +5300,7 @@ See Info node `(elisp)Garbage Collection'. */)
5255 gc_relative_threshold = 0; 5300 gc_relative_threshold = 0;
5256 if (FLOATP (Vgc_cons_percentage)) 5301 if (FLOATP (Vgc_cons_percentage))
5257 { /* Set gc_cons_combined_threshold. */ 5302 { /* Set gc_cons_combined_threshold. */
5258 double tot = 0; 5303 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 5304
5269 tot *= XFLOAT_DATA (Vgc_cons_percentage); 5305 tot *= XFLOAT_DATA (Vgc_cons_percentage);
5270 if (0 < tot) 5306 if (0 < tot)
@@ -5367,6 +5403,17 @@ See Info node `(elisp)Garbage Collection'. */)
5367 5403
5368 gcs_done++; 5404 gcs_done++;
5369 5405
5406 /* Collect profiling data. */
5407 if (profiler_memory_running)
5408 {
5409 size_t swept = 0;
5410 size_t tot_after = total_bytes_of_live_objects ();
5411 if (tot_before > tot_after)
5412 swept = tot_before - tot_after;
5413 malloc_probe (swept);
5414 }
5415
5416 backtrace_list = backtrace.next;
5370 return retval; 5417 return retval;
5371} 5418}
5372 5419
@@ -5521,7 +5568,7 @@ mark_buffer (struct buffer *buffer)
5521} 5568}
5522 5569
5523/* Remove killed buffers or items whose car is a killed buffer from 5570/* Remove killed buffers or items whose car is a killed buffer from
5524 LIST, and mark other items. Return changed LIST, which is marked. */ 5571 LIST, and mark other items. Return changed LIST, which is marked. */
5525 5572
5526static Lisp_Object 5573static Lisp_Object
5527mark_discard_killed_buffers (Lisp_Object list) 5574mark_discard_killed_buffers (Lisp_Object list)
@@ -5543,6 +5590,7 @@ mark_discard_killed_buffers (Lisp_Object list)
5543 prev = &XCDR_AS_LVALUE (tail); 5590 prev = &XCDR_AS_LVALUE (tail);
5544 } 5591 }
5545 } 5592 }
5593 mark_object (tail);
5546 return list; 5594 return list;
5547} 5595}
5548 5596
@@ -5691,18 +5739,8 @@ mark_object (Lisp_Object arg)
5691 struct window *w = (struct window *) ptr; 5739 struct window *w = (struct window *) ptr;
5692 bool leaf = NILP (w->hchild) && NILP (w->vchild); 5740 bool leaf = NILP (w->hchild) && NILP (w->vchild);
5693 5741
5694 /* For live windows, Lisp code filters out killed buffers
5695 from both buffer lists. For dead windows, we do it here
5696 in attempt to help GC to reclaim killed buffers faster. */
5697 if (leaf && NILP (w->buffer))
5698 {
5699 wset_prev_buffers
5700 (w, mark_discard_killed_buffers (w->prev_buffers));
5701 wset_next_buffers
5702 (w, mark_discard_killed_buffers (w->next_buffers));
5703 }
5704
5705 mark_vectorlike (ptr); 5742 mark_vectorlike (ptr);
5743
5706 /* Mark glyphs for leaf windows. Marking window 5744 /* Mark glyphs for leaf windows. Marking window
5707 matrices is sufficient because frame matrices 5745 matrices is sufficient because frame matrices
5708 use the same glyph memory. */ 5746 use the same glyph memory. */
@@ -5711,6 +5749,15 @@ mark_object (Lisp_Object arg)
5711 mark_glyph_matrix (w->current_matrix); 5749 mark_glyph_matrix (w->current_matrix);
5712 mark_glyph_matrix (w->desired_matrix); 5750 mark_glyph_matrix (w->desired_matrix);
5713 } 5751 }
5752
5753 /* Filter out killed buffers from both buffer lists
5754 in attempt to help GC to reclaim killed buffers faster.
5755 We can do it elsewhere for live windows, but this is the
5756 best place to do it for dead windows. */
5757 wset_prev_buffers
5758 (w, mark_discard_killed_buffers (w->prev_buffers));
5759 wset_next_buffers
5760 (w, mark_discard_killed_buffers (w->next_buffers));
5714 } 5761 }
5715 break; 5762 break;
5716 5763
@@ -6395,7 +6442,7 @@ die (const char *msg, const char *file, int line)
6395{ 6442{
6396 fprintf (stderr, "\r\n%s:%d: Emacs fatal error: %s\r\n", 6443 fprintf (stderr, "\r\n%s:%d: Emacs fatal error: %s\r\n",
6397 file, line, msg); 6444 file, line, msg);
6398 fatal_error_backtrace (SIGABRT, INT_MAX); 6445 terminate_due_to_signal (SIGABRT, INT_MAX);
6399} 6446}
6400#endif 6447#endif
6401 6448
@@ -6527,6 +6574,7 @@ do hash-consing of the objects allocated to pure space. */);
6527 DEFSYM (Qstring_bytes, "string-bytes"); 6574 DEFSYM (Qstring_bytes, "string-bytes");
6528 DEFSYM (Qvector_slots, "vector-slots"); 6575 DEFSYM (Qvector_slots, "vector-slots");
6529 DEFSYM (Qheap, "heap"); 6576 DEFSYM (Qheap, "heap");
6577 DEFSYM (Qautomatic_gc, "Automatic GC");
6530 6578
6531 DEFSYM (Qgc_cons_threshold, "gc-cons-threshold"); 6579 DEFSYM (Qgc_cons_threshold, "gc-cons-threshold");
6532 DEFSYM (Qchar_table_extra_slots, "char-table-extra-slots"); 6580 DEFSYM (Qchar_table_extra_slots, "char-table-extra-slots");
@@ -6560,7 +6608,8 @@ The time is in seconds as a floating point value. */);
6560/* When compiled with GCC, GDB might say "No enum type named 6608/* When compiled with GCC, GDB might say "No enum type named
6561 pvec_type" if we don't have at least one symbol with that type, and 6609 pvec_type" if we don't have at least one symbol with that type, and
6562 then xbacktrace could fail. Similarly for the other enums and 6610 then xbacktrace could fail. Similarly for the other enums and
6563 their values. */ 6611 their values. Some non-GCC compilers don't like these constructs. */
6612#ifdef __GNUC__
6564union 6613union
6565{ 6614{
6566 enum CHARTAB_SIZE_BITS CHARTAB_SIZE_BITS; 6615 enum CHARTAB_SIZE_BITS CHARTAB_SIZE_BITS;
@@ -6580,3 +6629,4 @@ union
6580 enum lsb_bits lsb_bits; 6629 enum lsb_bits lsb_bits;
6581#endif 6630#endif
6582} const EXTERNALLY_VISIBLE gdb_make_enums_visible = {0}; 6631} const EXTERNALLY_VISIBLE gdb_make_enums_visible = {0};
6632#endif /* __GNUC__ */