* 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
This commit is contained in:
ko1 2012-11-29 05:05:19 +00:00
Родитель 5bb12509a2
Коммит c512d6acf9
2 изменённых файлов: 45 добавлений и 52 удалений

Просмотреть файл

@ -1,3 +1,11 @@
Thu Nov 29 14:02:15 2012 Koichi Sasada <ko1@atdot.net>
* 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.
Thu Nov 29 12:13:54 2012 Ryan Davis <ryand-ruby@zenspider.com>
* lib/minitest/*: Imported minitest 4.3.2 (r8026)

89
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 */