[#56982] [ruby-trunk - Bug #8854][Open] Update URL for bug reports — "stomar (Marcus Stollsteimer)" <redmine@...>
7 messages
2013/09/03
[#57038] [ruby-trunk - Feature #3620] Add Queue, SIzedQueue and ConditionVariable implementations in C in addition to ruby ones — "Glass_saga (Masaki Matsushita)" <glass.saga@...>
4 messages
2013/09/05
[#57040] Re: [ruby-trunk - Feature #3620] Add Queue, SIzedQueue and ConditionVariable implementations in C in addition to ruby ones
— SASADA Koichi <ko1@...>
2013/09/05
(2013/09/05 20:52), Glass_saga (Masaki Matsushita) wrote:
[#57058] [ruby-trunk - Bug #8875][Open] Select is not usable with SSLSocket — "headius (Charles Nutter)" <headius@...>
11 messages
2013/09/07
[#57092] [ruby-trunk - Bug #8883][Open] Rational canonicalization unexpectedly converts to Fixnum — "melquiades (Paul Cantrell)" <cantrell@...>
16 messages
2013/09/09
[#57111] [ruby-trunk - Feature #8887][Open] min(n), max(n), min_by(n), max_by(n) — "akr (Akira Tanaka)" <akr@...>
13 messages
2013/09/10
[#57117] [ruby-trunk - Feature #8890][Open] [PATCH] Eliminate less-than-zero checks for unsigned variables — "tonyo (Anton Ovchinnikov)" <revolver112@...>
5 messages
2013/09/10
[#57134] [CommonRuby - Feature #8896][Open] #tap with missing block — "prijutme4ty (Ilya Vorontsov)" <prijutme4ty@...>
5 messages
2013/09/11
[#57138] [ruby-trunk - Feature #8897][Open] client side TCP fast open — "Glass_saga (Masaki Matsushita)" <glass.saga@...>
5 messages
2013/09/11
[#57195] [ruby-trunk - Feature #8897][Assigned] client side TCP fast open
— "Glass_saga (Masaki Matsushita)" <glass.saga@...>
2013/09/14
[#57186] [ruby-trunk - Feature #8909][Open] Expand "f" frozen suffix to literal arrays and hashes — "headius (Charles Nutter)" <headius@...>
37 messages
2013/09/14
[#57224] [ruby-trunk - Feature #8909] Expand "f" frozen suffix to literal arrays and hashes
— "headius (Charles Nutter)" <headius@...>
2013/09/15
[#57262] [ruby-trunk - Feature #8921][Open] Allow select, reject, etc to accept a regex — "kyledecot (Kyle Decot)" <kyle.decot@...>
13 messages
2013/09/18
[#57264] [ruby-trunk - Feature #8921] Allow select, reject, etc to accept a regex
— "kyledecot (Kyle Decot)" <kyle.decot@...>
2013/09/18
[#57265] Re: [ruby-trunk - Feature #8921] Allow select, reject, etc to accept a regex
— Fuad Saud <fuadksd@...>
2013/09/18
Shouldn't select/reject use threequals?
[#57292] [ruby-trunk - Feature #8931][Open] Update URL in REPORTBUG_MSG — "zzak (Zachary Scott)" <e@...>
4 messages
2013/09/20
[#57315] [ruby-trunk - Feature #8938][Open] it keyword — "Sing9898 (Sing Lou)" <3b06e8d4@...>
5 messages
2013/09/23
[#57367] [ruby-trunk - Feature #8951][Open] Please add a hash-to-hash alternative of the map method to Hash — "behrangsa (Behrang Saeedzadeh)" <behrangsa@...>
8 messages
2013/09/25
[#57385] [ruby-trunk - Bug #8953][Open] `str =~ /pattern/` does not call =~ method if (1) str is a String, (2) /pattern/ is a Regexp literal — "gfx (Goro Fuji)" <gfuji@...>
12 messages
2013/09/26
[#57394] [ruby-trunk - Bug #8955][Open] LocalJumpError - no block given (yield) after implementation of class hierarchy method cache invalidation — "mfla (Morten Fla)" <mmflaa@...>
4 messages
2013/09/26
[#57462] [ruby-trunk - misc #8962][Open] [DOC] add step to enable Generational GC merits in README.EXT* — "tad (Tadashi Saito)" <redmine@...>
6 messages
2013/09/28
[ruby-core:57486] [ruby-trunk - Bug #8122] [patch] gc: GC.stat improvements and related cleanup
From:
"ko1 (Koichi Sasada)" <redmine@...>
Date:
2013-09-30 11:26:44 UTC
List:
ruby-core #57486
Issue #8122 has been updated by ko1 (Koichi Sasada).
Target version set to current: 2.1.0
----------------------------------------
Bug #8122: [patch] gc: GC.stat improvements and related cleanup
https://bugs.ruby-lang.org/issues/8122#change-42099
Author: tmm1 (Aman Gupta)
Status: Open
Priority: Normal
Assignee: ko1 (Koichi Sasada)
Category: core
Target version: current: 2.1.0
ruby -v: ruby 2.1.0dev (2013-03-19 trunk 39816) [x86_64-darwin12.2.1]
Backport:
I propose 4 related patches below. The end result is more information from GC.stat about mark and sweep activity.
1) Rename heap.free_num to heap.swept_num
This is a purely cosmetic change, to make the purpose of the variable more clear and avoid problems due to misuse later (like we saw in r39811)
I considered some other names: heap.freelisted_num, heap.reused_num
2) Add heap.sweep_num
We already calculate heap.marked_num during mark. This is inverse of marked_num calculated at the end of mark cycle.
Using this you can monitor progress of sweep cycle: (100% * heap.swept_num / heap.sweep_num)
I considered also: heap.sweeping_num
3) Remove rest_sweep() from GC.stat
Currently sweep is a side-effect of GC.stat. It makes GC.stat difficult to use for statistics, because it is not constant time operation.
Also, after rest_sweep(), heap.swept_num == heap.sweep_num, so GC.stat cannot be used to track progress of sweep cycle.
4) Expose new mark/sweep counters via GC.stat
Author: Aman Gupta <aman@tmm1.net>
Date: Mon Mar 18 18:11:27 2013 -0700
rename heap.free_num to heap.swept_num
diff --git a/gc.c b/gc.c
index 635e3ec..f654e19 100644
--- a/gc.c
+++ b/gc.c
@@ -229,7 +229,7 @@ typedef struct rb_objspace {
RVALUE *range[2];
struct heaps_header *freed;
size_t marked_num;
- size_t free_num;
+ size_t swept_num;
size_t free_min;
size_t final_num;
size_t do_heap_free;
@@ -1434,7 +1434,7 @@ finalize_list(rb_objspace_t *objspace, RVALUE *p)
objspace->total_freed_object_num++;
if (!FL_TEST(p, FL_SINGLETON)) { /* not freeing page */
add_slot_local_freelist(objspace, p);
- objspace->heap.free_num++;
+ objspace->heap.swept_num++;
}
else {
struct heaps_slot *slot = (struct heaps_slot *)(VALUE)RDATA(p)->dmark;
@@ -1921,7 +1921,7 @@ slot_sweep(rb_objspace_t *objspace, struct heaps_slot *sweep_slot)
}
gc_clear_slot_bits(sweep_slot);
if (final_num + freed_num + empty_num == sweep_slot->header->limit &&
- objspace->heap.free_num > objspace->heap.do_heap_free) {
+ objspace->heap.swept_num > objspace->heap.do_heap_free) {
RVALUE *pp;
for (pp = deferred_final_list; pp != final; pp = pp->as.free.next) {
@@ -1938,7 +1938,7 @@ slot_sweep(rb_objspace_t *objspace, struct heaps_slot *sweep_slot)
else {
sweep_slot->free_next = NULL;
}
- objspace->heap.free_num += freed_num + empty_num;
+ objspace->heap.swept_num += freed_num + empty_num;
}
objspace->total_freed_object_num += freed_num;
objspace->heap.final_num += final_num;
@@ -1977,7 +1977,7 @@ before_gc_sweep(rb_objspace_t *objspace)
objspace->heap.do_heap_free = initial_free_min;
}
objspace->heap.sweep_slots = heaps;
- objspace->heap.free_num = 0;
+ objspace->heap.swept_num = 0;
objspace->heap.free_slots = NULL;
/* sweep unlinked method entries */
@@ -1992,7 +1992,7 @@ after_gc_sweep(rb_objspace_t *objspace)
size_t inc;
gc_prof_set_malloc_info(objspace);
- if (objspace->heap.free_num < objspace->heap.free_min) {
+ if (objspace->heap.swept_num < objspace->heap.free_min) {
set_heaps_increment(objspace);
heaps_increment(objspace);
}
@@ -2972,7 +2972,7 @@ rb_gc_force_recycle(VALUE p)
add_slot_local_freelist(objspace, (RVALUE *)p);
}
else {
- objspace->heap.free_num++;
+ objspace->heap.swept_num++;
slot = add_slot_local_freelist(objspace, (RVALUE *)p);
if (slot->free_next == NULL) {
link_free_heap_slot(objspace, slot);
@@ -3205,7 +3205,7 @@ gc_stat(int argc, VALUE *argv, VALUE self)
rb_hash_aset(hash, sym_heap_length, SIZET2NUM(objspace->heap.length));
rb_hash_aset(hash, sym_heap_increment, SIZET2NUM(objspace->heap.increment));
rb_hash_aset(hash, sym_heap_live_num, SIZET2NUM(objspace_live_num(objspace)));
- rb_hash_aset(hash, sym_heap_free_num, SIZET2NUM(objspace->heap.free_num));
+ rb_hash_aset(hash, sym_heap_free_num, SIZET2NUM(objspace->heap.swept_num));
rb_hash_aset(hash, sym_heap_final_num, SIZET2NUM(objspace->heap.final_num));
rb_hash_aset(hash, sym_total_allocated_object, SIZET2NUM(objspace->total_allocated_object_num));
rb_hash_aset(hash, sym_total_freed_object, SIZET2NUM(objspace->total_freed_object_num));
Author: Aman Gupta <aman@tmm1.net>
Date: Mon Mar 18 18:32:58 2013 -0700
add sweep_num
diff --git a/gc.c b/gc.c
index b911d04..c49f1dd 100644
--- a/gc.c
+++ b/gc.c
@@ -229,6 +229,7 @@ typedef struct rb_objspace {
RVALUE *range[2];
struct heaps_header *freed;
size_t marked_num;
+ size_t sweep_num;
size_t swept_num;
size_t free_min;
size_t final_num;
@@ -2957,6 +2958,7 @@ gc_marks(rb_objspace_t *objspace)
gc_prof_mark_timer_stop(objspace);
objspace->mark_func_data = prev_mark_func_data;
+ objspace->heap.sweep_num = (heaps_used * HEAP_OBJ_LIMIT) - objspace->heap.marked_num;
}
/* GC */
Author: Aman Gupta <aman@tmm1.net>
Date: Mon Mar 18 18:14:10 2013 -0700
remove rest_sweep side-effect from GC.stat
diff --git a/gc.c b/gc.c
index f654e19..b911d04 100644
--- a/gc.c
+++ b/gc.c
@@ -3197,8 +3197,6 @@ gc_stat(int argc, VALUE *argv, VALUE self)
hash = rb_hash_new();
}
- rest_sweep(objspace);
-
rb_hash_aset(hash, sym_count, SIZET2NUM(objspace->count));
/* implementation dependent counters */
rb_hash_aset(hash, sym_heap_used, SIZET2NUM(objspace->heap.used));
Author: Aman Gupta <aman@tmm1.net>
Date: Mon Mar 18 18:59:50 2013 -0700
add more stats to GC.stat
diff --git a/gc.c b/gc.c
index c49f1dd..8f458db 100644
--- a/gc.c
+++ b/gc.c
@@ -3174,18 +3174,28 @@ gc_stat(int argc, VALUE *argv, VALUE self)
{
rb_objspace_t *objspace = &rb_objspace;
VALUE hash;
+ size_t total_num, live_num;
static VALUE sym_count;
static VALUE sym_heap_used, sym_heap_length, sym_heap_increment;
- static VALUE sym_heap_live_num, sym_heap_free_num, sym_heap_final_num;
+ static VALUE sym_heap_obj_limit, sym_heap_total_num;
+ static VALUE sym_heap_live_num, sym_heap_empty_num, sym_heap_final_num;
+ static VALUE sym_heap_marked_num, sym_heap_sweep_num, sym_heap_swept_num;
+ static VALUE sym_is_lazy_sweeping;
static VALUE sym_total_allocated_object, sym_total_freed_object;
if (sym_count == 0) {
sym_count = ID2SYM(rb_intern_const("count"));
sym_heap_used = ID2SYM(rb_intern_const("heap_used"));
sym_heap_length = ID2SYM(rb_intern_const("heap_length"));
sym_heap_increment = ID2SYM(rb_intern_const("heap_increment"));
+ sym_heap_obj_limit = ID2SYM(rb_intern_const("heap_obj_limit"));
+ sym_heap_total_num = ID2SYM(rb_intern_const("heap_total_num"));
sym_heap_live_num = ID2SYM(rb_intern_const("heap_live_num"));
- sym_heap_free_num = ID2SYM(rb_intern_const("heap_free_num"));
+ sym_heap_empty_num = ID2SYM(rb_intern_const("heap_empty_num"));
sym_heap_final_num = ID2SYM(rb_intern_const("heap_final_num"));
+ sym_heap_marked_num = ID2SYM(rb_intern_const("heap_marked_num"));
+ sym_heap_sweep_num = ID2SYM(rb_intern_const("heap_sweep_num"));
+ sym_heap_swept_num = ID2SYM(rb_intern_const("heap_swept_num"));
+ sym_is_lazy_sweeping = ID2SYM(rb_intern_const("is_lazy_sweeping"));
sym_total_allocated_object = ID2SYM(rb_intern_const("total_allocated_object"));
sym_total_freed_object = ID2SYM(rb_intern_const("total_freed_object"));
}
@@ -3201,12 +3211,21 @@ gc_stat(int argc, VALUE *argv, VALUE self)
rb_hash_aset(hash, sym_count, SIZET2NUM(objspace->count));
/* implementation dependent counters */
+ total_num = heaps_used * HEAP_OBJ_LIMIT;
+ live_num = objspace_live_num(objspace);
+
rb_hash_aset(hash, sym_heap_used, SIZET2NUM(objspace->heap.used));
rb_hash_aset(hash, sym_heap_length, SIZET2NUM(objspace->heap.length));
rb_hash_aset(hash, sym_heap_increment, SIZET2NUM(objspace->heap.increment));
- rb_hash_aset(hash, sym_heap_live_num, SIZET2NUM(objspace_live_num(objspace)));
- rb_hash_aset(hash, sym_heap_free_num, SIZET2NUM(objspace->heap.swept_num));
+ rb_hash_aset(hash, sym_heap_obj_limit, SIZET2NUM(HEAP_OBJ_LIMIT));
+ rb_hash_aset(hash, sym_heap_total_num, SIZET2NUM(total_num));
+ rb_hash_aset(hash, sym_heap_live_num, SIZET2NUM(live_num));
+ rb_hash_aset(hash, sym_heap_empty_num, SIZET2NUM(total_num - live_num));
rb_hash_aset(hash, sym_heap_final_num, SIZET2NUM(objspace->heap.final_num));
+ rb_hash_aset(hash, sym_is_lazy_sweeping, is_lazy_sweeping(objspace) ? Qtrue : Qfalse);
+ rb_hash_aset(hash, sym_heap_marked_num, SIZET2NUM(objspace->heap.marked_num));
+ rb_hash_aset(hash, sym_heap_swept_num, SIZET2NUM(objspace->heap.swept_num));
+ rb_hash_aset(hash, sym_heap_sweep_num, SIZET2NUM(objspace->heap.sweep_num));
rb_hash_aset(hash, sym_total_allocated_object, SIZET2NUM(objspace->total_allocated_object_num));
rb_hash_aset(hash, sym_total_freed_object, SIZET2NUM(objspace->total_freed_object_num));
--
http://bugs.ruby-lang.org/