mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* 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:
parent
5bb12509a2
commit
c512d6acf9
2 changed files with 45 additions and 52 deletions
|
@ -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>
|
Thu Nov 29 12:13:54 2012 Ryan Davis <ryand-ruby@zenspider.com>
|
||||||
|
|
||||||
* lib/minitest/*: Imported minitest 4.3.2 (r8026)
|
* lib/minitest/*: Imported minitest 4.3.2 (r8026)
|
||||||
|
|
89
gc.c
89
gc.c
|
@ -225,7 +225,6 @@ typedef struct rb_objspace {
|
||||||
struct heaps_free_bitmap *free_bitmap;
|
struct heaps_free_bitmap *free_bitmap;
|
||||||
RVALUE *range[2];
|
RVALUE *range[2];
|
||||||
struct heaps_header *freed;
|
struct heaps_header *freed;
|
||||||
size_t live_num;
|
|
||||||
size_t free_num;
|
size_t free_num;
|
||||||
size_t free_min;
|
size_t free_min;
|
||||||
size_t final_num;
|
size_t final_num;
|
||||||
|
@ -251,6 +250,8 @@ typedef struct rb_objspace {
|
||||||
} profile;
|
} profile;
|
||||||
struct gc_list *global_list;
|
struct gc_list *global_list;
|
||||||
size_t count;
|
size_t count;
|
||||||
|
size_t total_allocated_object_num;
|
||||||
|
size_t total_freed_object_num;
|
||||||
int gc_stress;
|
int gc_stress;
|
||||||
|
|
||||||
struct mark_func_data_struct {
|
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_start(rb_objspace_t *);
|
||||||
static inline void gc_prof_sweep_timer_stop(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_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.sorted[hi]->bits = (uintptr_t *)objspace->heap.free_bitmap;
|
||||||
objspace->heap.free_bitmap = objspace->heap.free_bitmap->next;
|
objspace->heap.free_bitmap = objspace->heap.free_bitmap->next;
|
||||||
memset(heaps->bits, 0, HEAP_BITMAP_LIMIT * sizeof(uintptr_t));
|
memset(heaps->bits, 0, HEAP_BITMAP_LIMIT * sizeof(uintptr_t));
|
||||||
objspace->heap.free_num += objs;
|
|
||||||
pend = p + objs;
|
pend = p + objs;
|
||||||
if (lomem == 0 || lomem > p) lomem = p;
|
if (lomem == 0 || lomem > p) lomem = p;
|
||||||
if (himem < pend) himem = pend;
|
if (himem < pend) himem = pend;
|
||||||
|
@ -660,7 +658,7 @@ newobj(VALUE klass, VALUE flags)
|
||||||
RANY(obj)->file = rb_sourcefile();
|
RANY(obj)->file = rb_sourcefile();
|
||||||
RANY(obj)->line = rb_sourceline();
|
RANY(obj)->line = rb_sourceline();
|
||||||
#endif
|
#endif
|
||||||
gc_prof_inc_live_num(objspace);
|
objspace->total_allocated_object_num++;
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
@ -1422,7 +1420,8 @@ finalize_list(rb_objspace_t *objspace, RVALUE *p)
|
||||||
if (!FL_TEST(p, FL_SINGLETON)) { /* not freeing page */
|
if (!FL_TEST(p, FL_SINGLETON)) { /* not freeing page */
|
||||||
add_slot_local_freelist(objspace, p);
|
add_slot_local_freelist(objspace, p);
|
||||||
if (!is_lazy_sweeping(objspace)) {
|
if (!is_lazy_sweeping(objspace)) {
|
||||||
gc_prof_dec_live_num(objspace);
|
objspace->total_freed_object_num++;
|
||||||
|
objspace->heap.free_num++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -1873,10 +1872,16 @@ gc_clear_slot_bits(struct heaps_slot *slot)
|
||||||
memset(slot->bits, 0, HEAP_BITMAP_LIMIT * sizeof(uintptr_t));
|
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
|
static void
|
||||||
slot_sweep(rb_objspace_t *objspace, struct heaps_slot *sweep_slot)
|
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 *p, *pend;
|
||||||
RVALUE *final = deferred_final_list;
|
RVALUE *final = deferred_final_list;
|
||||||
int deferred;
|
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.flags = 0;
|
||||||
p->as.free.next = sweep_slot->freelist;
|
p->as.free.next = sweep_slot->freelist;
|
||||||
sweep_slot->freelist = p;
|
sweep_slot->freelist = p;
|
||||||
free_num++;
|
freed_num++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
free_num++;
|
empty_num++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
gc_clear_slot_bits(sweep_slot);
|
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) {
|
objspace->heap.free_num > objspace->heap.do_heap_free) {
|
||||||
RVALUE *pp;
|
RVALUE *pp;
|
||||||
|
|
||||||
|
@ -1925,13 +1930,14 @@ slot_sweep(rb_objspace_t *objspace, struct heaps_slot *sweep_slot)
|
||||||
unlink_heap_slot(objspace, sweep_slot);
|
unlink_heap_slot(objspace, sweep_slot);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (free_num > 0) {
|
if (freed_num + empty_num > 0) {
|
||||||
link_free_heap_slot(objspace, sweep_slot);
|
link_free_heap_slot(objspace, sweep_slot);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sweep_slot->free_next = NULL;
|
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;
|
objspace->heap.final_num += final_num;
|
||||||
|
|
||||||
|
@ -1990,7 +1996,8 @@ after_gc_sweep(rb_objspace_t *objspace)
|
||||||
|
|
||||||
inc = ATOMIC_SIZE_EXCHANGE(malloc_increase, 0);
|
inc = ATOMIC_SIZE_EXCHANGE(malloc_increase, 0);
|
||||||
if (inc > malloc_limit) {
|
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;
|
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);
|
gc_marks(objspace);
|
||||||
|
|
||||||
before_gc_sweep(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);
|
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);
|
register uintptr_t *bits = GET_HEAP_BITMAP(ptr);
|
||||||
if (MARKED_IN_BITMAP(bits, ptr)) return 0;
|
if (MARKED_IN_BITMAP(bits, ptr)) return 0;
|
||||||
MARK_IN_BITMAP(bits, ptr);
|
MARK_IN_BITMAP(bits, ptr);
|
||||||
objspace->heap.live_num++;
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2905,11 +2911,8 @@ gc_marks(rb_objspace_t *objspace)
|
||||||
objspace->mark_func_data = 0;
|
objspace->mark_func_data = 0;
|
||||||
|
|
||||||
gc_prof_mark_timer_start(objspace);
|
gc_prof_mark_timer_start(objspace);
|
||||||
|
|
||||||
objspace->heap.live_num = 0;
|
|
||||||
objspace->count++;
|
objspace->count++;
|
||||||
|
|
||||||
|
|
||||||
SET_STACK_END;
|
SET_STACK_END;
|
||||||
|
|
||||||
th->vm->self ? rb_gc_mark(th->vm->self) : rb_vm_mark(th->vm);
|
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);
|
add_slot_local_freelist(objspace, (RVALUE *)p);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
gc_prof_dec_live_num(objspace);
|
objspace->total_freed_object_num++;
|
||||||
|
objspace->heap.free_num++;
|
||||||
slot = add_slot_local_freelist(objspace, (RVALUE *)p);
|
slot = add_slot_local_freelist(objspace, (RVALUE *)p);
|
||||||
if (slot->free_next == NULL) {
|
if (slot->free_next == NULL) {
|
||||||
link_free_heap_slot(objspace, slot);
|
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:
|
* The hash includes information about internal statistics about GC such as:
|
||||||
*
|
*
|
||||||
* {
|
* { :count=>0,
|
||||||
* :count => 18,
|
* :heap_used=>12,
|
||||||
* :heap_used => 77,
|
* :heap_length=>12,
|
||||||
* :heap_length => 77,
|
* :heap_increment=>0,
|
||||||
* :heap_increment => 0,
|
* :heap_live_num=>7539,
|
||||||
* :heap_live_num => 23287,
|
* :heap_free_num=>88,
|
||||||
* :heap_free_num => 8115,
|
* :heap_final_num=>0,
|
||||||
* :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 contents of the hash are implementation defined and may be changed in
|
||||||
* the future.
|
* 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_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_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_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_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("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;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3952,7 +3959,7 @@ gc_prof_set_malloc_info(rb_objspace_t *objspace)
|
||||||
static inline void
|
static inline void
|
||||||
gc_prof_set_heap_info(rb_objspace_t *objspace, gc_profile_record *record)
|
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;
|
size_t total = heaps_used * HEAP_OBJ_LIMIT;
|
||||||
|
|
||||||
record->heap_total_objects = total;
|
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);
|
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
|
#else
|
||||||
|
|
||||||
static inline void
|
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);
|
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 */
|
#endif /* !GC_PROFILE_MORE_DETAIL */
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue