summaryrefslogtreecommitdiff
path: root/gc.c
diff options
context:
space:
mode:
authoreregon <eregon@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-10-27 14:36:22 +0000
committereregon <eregon@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-10-27 14:36:22 +0000
commit1fe5783104b248be54f21d147722ca2ebc7d149a (patch)
tree2b208bab9d547272dd6590eb277b5f46f3efe8d7 /gc.c
parent493d2533002169132162534ee87595c1b91b920d (diff)
* gc.c (gc_profile_result, gc_profile_report): use internal structures
to avoid allocations and progressively print the output for #report. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37343 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'gc.c')
-rw-r--r--gc.c90
1 files changed, 43 insertions, 47 deletions
diff --git a/gc.c b/gc.c
index 0e3413f8f4..0f1b11981b 100644
--- a/gc.c
+++ b/gc.c
@@ -4141,68 +4141,64 @@ gc_profile_record_get(void)
return gc_profile;
}
-/*
- * call-seq:
- * GC::Profiler.result -> String
- *
- * Returns a profile data report such as:
- *
- * GC 1 invokes.
- * Index Invoke Time(sec) Use Size(byte) Total Size(byte) Total Object GC time(ms)
- * 1 0.012 159240 212940 10647 0.00000000000001530000
- */
-
-static VALUE
-gc_profile_result(void)
+static void
+gc_profile_dump_on(VALUE out, VALUE (*append)(VALUE, VALUE))
{
rb_objspace_t *objspace = &rb_objspace;
- VALUE record;
- VALUE result;
- int i, index;
+ size_t count = objspace->profile.count;
- record = gc_profile_record_get();
- if (objspace->profile.run && objspace->profile.count) {
- result = rb_sprintf("GC %d invokes.\n", NUM2INT(gc_count(0)));
- index = 1;
- rb_str_cat2(result, "Index Invoke Time(sec) Use Size(byte) Total Size(byte) Total Object GC Time(ms)\n");
- for (i = 0; i < (int)RARRAY_LEN(record); i++) {
- VALUE r = RARRAY_PTR(record)[i];
+ if (objspace->profile.run && count) {
+ int index = 1;
+ size_t i;
+ gc_profile_record r;
+ append(out, rb_sprintf("GC %zu invokes.\n", objspace->count));
+ append(out, rb_str_new_cstr("Index Invoke Time(sec) Use Size(byte) Total Size(byte) Total Object GC Time(ms)\n"));
+ for (i = 0; i < count; i++) {
+ r = objspace->profile.record[i];
#if !GC_PROFILE_MORE_DETAIL
- if (rb_hash_aref(r, ID2SYM(rb_intern("GC_IS_MARKED")))) {
+ if (r.is_marked) {
#endif
- rb_str_catf(result, "%5d %19.3f %20"PRIuSIZE" %20"PRIuSIZE" %20"PRIuSIZE" %30.20f\n",
- index++, NUM2DBL(rb_hash_aref(r, ID2SYM(rb_intern("GC_INVOKE_TIME")))),
- (size_t)NUM2SIZET(rb_hash_aref(r, ID2SYM(rb_intern("HEAP_USE_SIZE")))),
- (size_t)NUM2SIZET(rb_hash_aref(r, ID2SYM(rb_intern("HEAP_TOTAL_SIZE")))),
- (size_t)NUM2SIZET(rb_hash_aref(r, ID2SYM(rb_intern("HEAP_TOTAL_OBJECTS")))),
- NUM2DBL(rb_hash_aref(r, ID2SYM(rb_intern("GC_TIME"))))*1000);
+ append(out, rb_sprintf("%5d %19.3f %20zu %20zu %20zu %30.20f\n",
+ index++, r.gc_invoke_time, r.heap_use_size,
+ r.heap_total_size, r.heap_total_objects, r.gc_time*1000));
#if !GC_PROFILE_MORE_DETAIL
}
#endif
}
#if GC_PROFILE_MORE_DETAIL
- rb_str_cat2(result, "\n\n");
- rb_str_cat2(result, "More detail.\n");
- rb_str_cat2(result, "Index Allocate Increase Allocate Limit Use Slot Have Finalize Mark Time(ms) Sweep Time(ms)\n");
+ append(out, rb_str_new_cstr("\n\n" \
+ "More detail.\n" \
+ "Index Allocate Increase Allocate Limit Use Slot Have Finalize Mark Time(ms) Sweep Time(ms)\n"));
index = 1;
- for (i = 0; i < (int)RARRAY_LEN(record); i++) {
- VALUE r = RARRAY_PTR(record)[i];
- rb_str_catf(result, "%5d %17"PRIuSIZE" %17"PRIuSIZE" %9"PRIuSIZE" %14s %25.20f %25.20f\n",
- index++, (size_t)NUM2SIZET(rb_hash_aref(r, ID2SYM(rb_intern("ALLOCATE_INCREASE")))),
- (size_t)NUM2SIZET(rb_hash_aref(r, ID2SYM(rb_intern("ALLOCATE_LIMIT")))),
- (size_t)NUM2SIZET(rb_hash_aref(r, ID2SYM(rb_intern("HEAP_USE_SLOTS")))),
- rb_hash_aref(r, ID2SYM(rb_intern("HAVE_FINALIZE")))? "true" : "false",
- NUM2DBL(rb_hash_aref(r, ID2SYM(rb_intern("GC_MARK_TIME"))))*1000,
- NUM2DBL(rb_hash_aref(r, ID2SYM(rb_intern("GC_SWEEP_TIME"))))*1000);
+ for (i = 0; i < count; i++) {
+ r = objspace->profile.record[i];
+ append(out, rb_sprintf("%5d %17zu %17zu %9zu %14s %25.20f %25.20f\n",
+ index++, r.allocate_increase, r.allocate_limit,
+ r.heap_use_slots, (r.have_finalize ? "true" : "false"),
+ r.gc_mark_time*1000, r.gc_sweep_time*1000));
}
#endif
}
- else {
- result = rb_str_new2("");
- }
- return result;
}
+/*
+ * call-seq:
+ * GC::Profiler.result -> String
+ *
+ * Returns a profile data report such as:
+ *
+ * GC 1 invokes.
+ * Index Invoke Time(sec) Use Size(byte) Total Size(byte) Total Object GC time(ms)
+ * 1 0.012 159240 212940 10647 0.00000000000001530000
+ */
+
+static VALUE
+gc_profile_result(void)
+{
+ VALUE str = rb_str_buf_new(0);
+ gc_profile_dump_on(str, rb_str_buf_append);
+ return str;
+}
/*
* call-seq:
@@ -4224,7 +4220,7 @@ gc_profile_report(int argc, VALUE *argv, VALUE self)
else {
rb_scan_args(argc, argv, "01", &out);
}
- rb_io_write(out, gc_profile_result());
+ gc_profile_dump_on(out, rb_io_write);
return Qnil;
}