summaryrefslogtreecommitdiff
path: root/gc.c
diff options
context:
space:
mode:
authorko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-11-29 05:05:19 +0000
committerko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-11-29 05:05:19 +0000
commitc512d6acf98a6d550d1dd03c7642fee82dc46cea (patch)
tree19e5a5e2d8cc83a0757cd4e6881ab4fc5e455287 /gc.c
parent5bb12509a2db64cb92fd52222fc2022c9181d54e (diff)
* gc.c (gc_stat): GC.stat supports new information
* total_allocated_object: total allocated object number. * total_freed_object: total freed object number. Above two numbers are only accumulated and they will overflow (return to 0). Please use them as a hint. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37970 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'gc.c')
-rw-r--r--gc.c89
1 files changed, 37 insertions, 52 deletions
diff --git a/gc.c b/gc.c
index 63869a0542..ff608e2e9c 100644
--- a/gc.c
+++ b/gc.c
@@ -225,7 +225,6 @@ typedef struct rb_objspace {
struct heaps_free_bitmap *free_bitmap;
RVALUE *range[2];
struct heaps_header *freed;
- size_t live_num;
size_t free_num;
size_t free_min;
size_t final_num;
@@ -251,6 +250,8 @@ typedef struct rb_objspace {
} profile;
struct gc_list *global_list;
size_t count;
+ size_t total_allocated_object_num;
+ size_t total_freed_object_num;
int gc_stress;
struct mark_func_data_struct {
@@ -352,8 +353,6 @@ static inline void gc_prof_mark_timer_stop(rb_objspace_t *);
static inline void gc_prof_sweep_timer_start(rb_objspace_t *);
static inline void gc_prof_sweep_timer_stop(rb_objspace_t *);
static inline void gc_prof_set_malloc_info(rb_objspace_t *);
-static inline void gc_prof_inc_live_num(rb_objspace_t *);
-static inline void gc_prof_dec_live_num(rb_objspace_t *);
/*
@@ -531,7 +530,6 @@ assign_heap_slot(rb_objspace_t *objspace)
objspace->heap.sorted[hi]->bits = (uintptr_t *)objspace->heap.free_bitmap;
objspace->heap.free_bitmap = objspace->heap.free_bitmap->next;
memset(heaps->bits, 0, HEAP_BITMAP_LIMIT * sizeof(uintptr_t));
- objspace->heap.free_num += objs;
pend = p + objs;
if (lomem == 0 || lomem > p) lomem = p;
if (himem < pend) himem = pend;
@@ -660,7 +658,7 @@ newobj(VALUE klass, VALUE flags)
RANY(obj)->file = rb_sourcefile();
RANY(obj)->line = rb_sourceline();
#endif
- gc_prof_inc_live_num(objspace);
+ objspace->total_allocated_object_num++;
return obj;
}
@@ -1422,7 +1420,8 @@ finalize_list(rb_objspace_t *objspace, RVALUE *p)
if (!FL_TEST(p, FL_SINGLETON)) { /* not freeing page */
add_slot_local_freelist(objspace, p);
if (!is_lazy_sweeping(objspace)) {
- gc_prof_dec_live_num(objspace);
+ objspace->total_freed_object_num++;
+ objspace->heap.free_num++;
}
}
else {
@@ -1873,10 +1872,16 @@ gc_clear_slot_bits(struct heaps_slot *slot)
memset(slot->bits, 0, HEAP_BITMAP_LIMIT * sizeof(uintptr_t));
}
+static size_t
+objspace_live_num(rb_objspace_t *objspace)
+{
+ return objspace->total_allocated_object_num - objspace->total_freed_object_num;
+}
+
static void
slot_sweep(rb_objspace_t *objspace, struct heaps_slot *sweep_slot)
{
- size_t free_num = 0, final_num = 0;
+ size_t empty_num = 0, freed_num = 0, final_num = 0;
RVALUE *p, *pend;
RVALUE *final = deferred_final_list;
int deferred;
@@ -1903,17 +1908,17 @@ slot_sweep(rb_objspace_t *objspace, struct heaps_slot *sweep_slot)
p->as.free.flags = 0;
p->as.free.next = sweep_slot->freelist;
sweep_slot->freelist = p;
- free_num++;
+ freed_num++;
}
}
else {
- free_num++;
+ empty_num++;
}
}
p++;
}
gc_clear_slot_bits(sweep_slot);
- if (final_num + free_num == sweep_slot->header->limit &&
+ if (final_num + freed_num + empty_num == sweep_slot->header->limit &&
objspace->heap.free_num > objspace->heap.do_heap_free) {
RVALUE *pp;
@@ -1925,13 +1930,14 @@ slot_sweep(rb_objspace_t *objspace, struct heaps_slot *sweep_slot)
unlink_heap_slot(objspace, sweep_slot);
}
else {
- if (free_num > 0) {
+ if (freed_num + empty_num > 0) {
link_free_heap_slot(objspace, sweep_slot);
}
else {
sweep_slot->free_next = NULL;
}
- objspace->heap.free_num += free_num;
+ objspace->total_freed_object_num += freed_num;
+ objspace->heap.free_num += freed_num + empty_num;
}
objspace->heap.final_num += final_num;
@@ -1990,7 +1996,8 @@ after_gc_sweep(rb_objspace_t *objspace)
inc = ATOMIC_SIZE_EXCHANGE(malloc_increase, 0);
if (inc > malloc_limit) {
- malloc_limit += (size_t)((inc - malloc_limit) * (double)objspace->heap.live_num / (heaps_used * HEAP_OBJ_LIMIT));
+ malloc_limit +=
+ (size_t)((inc - malloc_limit) * (double)objspace_live_num(objspace) / (heaps_used * HEAP_OBJ_LIMIT));
if (malloc_limit < initial_malloc_limit) malloc_limit = initial_malloc_limit;
}
@@ -2063,7 +2070,7 @@ gc_prepare_free_objects(rb_objspace_t *objspace)
gc_marks(objspace);
before_gc_sweep(objspace);
- if (objspace->heap.free_min > (heaps_used * HEAP_OBJ_LIMIT - objspace->heap.live_num)) {
+ if (objspace->heap.free_min > (heaps_used * HEAP_OBJ_LIMIT - objspace_live_num(objspace))) {
set_heaps_increment(objspace);
}
@@ -2544,7 +2551,6 @@ gc_mark_ptr(rb_objspace_t *objspace, VALUE ptr)
register uintptr_t *bits = GET_HEAP_BITMAP(ptr);
if (MARKED_IN_BITMAP(bits, ptr)) return 0;
MARK_IN_BITMAP(bits, ptr);
- objspace->heap.live_num++;
return 1;
}
@@ -2905,11 +2911,8 @@ gc_marks(rb_objspace_t *objspace)
objspace->mark_func_data = 0;
gc_prof_mark_timer_start(objspace);
-
- objspace->heap.live_num = 0;
objspace->count++;
-
SET_STACK_END;
th->vm->self ? rb_gc_mark(th->vm->self) : rb_vm_mark(th->vm);
@@ -2956,7 +2959,8 @@ rb_gc_force_recycle(VALUE p)
add_slot_local_freelist(objspace, (RVALUE *)p);
}
else {
- gc_prof_dec_live_num(objspace);
+ objspace->total_freed_object_num++;
+ objspace->heap.free_num++;
slot = add_slot_local_freelist(objspace, (RVALUE *)p);
if (slot->free_next == NULL) {
link_free_heap_slot(objspace, slot);
@@ -3132,15 +3136,16 @@ gc_count(VALUE self)
*
* The hash includes information about internal statistics about GC such as:
*
- * {
- * :count => 18,
- * :heap_used => 77,
- * :heap_length => 77,
- * :heap_increment => 0,
- * :heap_live_num => 23287,
- * :heap_free_num => 8115,
- * :heap_final_num => 0,
- * }
+ * { :count=>0,
+ * :heap_used=>12,
+ * :heap_length=>12,
+ * :heap_increment=>0,
+ * :heap_live_num=>7539,
+ * :heap_free_num=>88,
+ * :heap_final_num=>0,
+ * :total_allocated_object=>7630,
+ * :total_freed_object=>88
+ * }
*
* The contents of the hash are implementation defined and may be changed in
* the future.
@@ -3172,9 +3177,11 @@ gc_stat(int argc, VALUE *argv, VALUE self)
rb_hash_aset(hash, ID2SYM(rb_intern("heap_used")), SIZET2NUM(objspace->heap.used));
rb_hash_aset(hash, ID2SYM(rb_intern("heap_length")), SIZET2NUM(objspace->heap.length));
rb_hash_aset(hash, ID2SYM(rb_intern("heap_increment")), SIZET2NUM(objspace->heap.increment));
- rb_hash_aset(hash, ID2SYM(rb_intern("heap_live_num")), SIZET2NUM(objspace->heap.live_num));
+ rb_hash_aset(hash, ID2SYM(rb_intern("heap_live_num")), SIZET2NUM(objspace_live_num(objspace)));
rb_hash_aset(hash, ID2SYM(rb_intern("heap_free_num")), SIZET2NUM(objspace->heap.free_num));
rb_hash_aset(hash, ID2SYM(rb_intern("heap_final_num")), SIZET2NUM(objspace->heap.final_num));
+ rb_hash_aset(hash, ID2SYM(rb_intern("total_allocated_object")), SIZET2NUM(objspace->total_allocated_object_num));
+ rb_hash_aset(hash, ID2SYM(rb_intern("total_freed_object")), SIZET2NUM(objspace->total_freed_object_num));
return hash;
}
@@ -3952,7 +3959,7 @@ gc_prof_set_malloc_info(rb_objspace_t *objspace)
static inline void
gc_prof_set_heap_info(rb_objspace_t *objspace, gc_profile_record *record)
{
- size_t live = objspace->heap.live_num;
+ size_t live = objspace_live_num(objspace);
size_t total = heaps_used * HEAP_OBJ_LIMIT;
record->heap_total_objects = total;
@@ -3960,16 +3967,6 @@ gc_prof_set_heap_info(rb_objspace_t *objspace, gc_profile_record *record)
record->heap_total_size = total * sizeof(RVALUE);
}
-static inline void
-gc_prof_inc_live_num(rb_objspace_t *objspace)
-{
-}
-
-static inline void
-gc_prof_dec_live_num(rb_objspace_t *objspace)
-{
-}
-
#else
static inline void
@@ -4059,18 +4056,6 @@ gc_prof_set_heap_info(rb_objspace_t *objspace, gc_profile_record *record)
record->heap_total_size = total * sizeof(RVALUE);
}
-static inline void
-gc_prof_inc_live_num(rb_objspace_t *objspace)
-{
- objspace->heap.live_num++;
-}
-
-static inline void
-gc_prof_dec_live_num(rb_objspace_t *objspace)
-{
- objspace->heap.live_num--;
-}
-
#endif /* !GC_PROFILE_MORE_DETAIL */