summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortmm1 <tmm1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-12-10 02:26:09 +0000
committertmm1 <tmm1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-12-10 02:26:09 +0000
commit7170baa878ac0223f26fcf8c8bf25492415e6eaa (patch)
tree284ae309fe2ac5c1aace26feb6ab4836b5382e62
parent97d292cb5580f15de13b2e8f54b6e4e366e8f0cb (diff)
objspace_dump.c: include object's gc flags in dump
* ext/objspace/objspace_dump.c (dump_object): include fstring flag on strings. include gc flags (old, remembered, wb_protected) on all objects. * ext/objspace/objspace_dump.c (Init_objspace_dump): initialize lazy IDs before first use. * gc.c (rb_obj_gc_flags): new function to retrieve object flags * internal.h (RB_OBJ_GC_FLAGS_MAX): maximum flags allowed for one obj * test/objspace/test_objspace.rb (test_dump_flags): test for above * test/objspace/test_objspace.rb (test_trace_object_allocations): resolve name before dump (for rb_class_path_cached) git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@44105 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog12
-rw-r--r--ext/objspace/objspace_dump.c17
-rw-r--r--gc.c47
-rw-r--r--internal.h2
-rw-r--r--test/objspace/test_objspace.rb7
5 files changed, 85 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index 4e20aa5cd9..0995e0c1b7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+Tue Dec 10 11:20:56 2013 Aman Gupta <ruby@tmm1.net>
+
+ * ext/objspace/objspace_dump.c (dump_object): include fstring flag on
+ strings. include gc flags (old, remembered, wb_protected) on all objects.
+ * ext/objspace/objspace_dump.c (Init_objspace_dump): initialize lazy
+ IDs before first use.
+ * gc.c (rb_obj_gc_flags): new function to retrieve object flags
+ * internal.h (RB_OBJ_GC_FLAGS_MAX): maximum flags allowed for one obj
+ * test/objspace/test_objspace.rb (test_dump_flags): test for above
+ * test/objspace/test_objspace.rb (test_trace_object_allocations):
+ resolve name before dump (for rb_class_path_cached)
+
Tue Dec 10 07:48:29 2013 Aman Gupta <ruby@tmm1.net>
* vm_method.c (rb_clear_method_cache_by_class): fire
diff --git a/ext/objspace/objspace_dump.c b/ext/objspace/objspace_dump.c
index a9906b8538..9a694d33aa 100644
--- a/ext/objspace/objspace_dump.c
+++ b/ext/objspace/objspace_dump.c
@@ -20,6 +20,7 @@
#include "node.h"
#include "vm_core.h"
#include "objspace.h"
+#include "internal.h"
static VALUE sym_output, sym_stdout, sym_string, sym_file;
@@ -148,6 +149,8 @@ dump_object(VALUE obj, struct dump_config *dc)
size_t memsize;
struct allocation_info *ainfo;
rb_io_t *fptr;
+ ID flags[RB_OBJ_GC_FLAGS_MAX];
+ size_t n, i;
dc->cur_obj = obj;
dc->cur_obj_references = 0;
@@ -175,6 +178,8 @@ dump_object(VALUE obj, struct dump_config *dc)
dump_append(dc, ", \"associated\":true");
if (is_broken_string(obj))
dump_append(dc, ", \"broken\":true");
+ if (FL_TEST(obj, RSTRING_FSTR))
+ dump_append(dc, ", \"fstring\":true");
if (STR_SHARED_P(obj))
dump_append(dc, ", \"shared\":true");
else {
@@ -249,6 +254,15 @@ dump_object(VALUE obj, struct dump_config *dc)
if ((memsize = rb_obj_memsize_of(obj)) > 0)
dump_append(dc, ", \"memsize\":%"PRIuSIZE, memsize);
+ if ((n = rb_obj_gc_flags(obj, flags, sizeof(flags))) > 0) {
+ dump_append(dc, ", \"flags\":{");
+ for (i=0; i<n; i++) {
+ dump_append(dc, "\"%s\":true", rb_id2name(flags[i]));
+ if (i != n-1) dump_append(dc, ", ");
+ }
+ dump_append(dc, "}");
+ }
+
dump_append(dc, "}\n");
}
@@ -411,4 +425,7 @@ Init_objspace_dump(VALUE rb_mObjSpace)
sym_stdout = ID2SYM(rb_intern("stdout"));
sym_string = ID2SYM(rb_intern("string"));
sym_file = ID2SYM(rb_intern("file"));
+
+ /* force create static IDs */
+ rb_obj_gc_flags(rb_mObjSpace, 0, 0);
}
diff --git a/gc.c b/gc.c
index 2083cc1027..3d6ca43e37 100644
--- a/gc.c
+++ b/gc.c
@@ -4749,6 +4749,53 @@ rb_obj_rgengc_promoted_p(VALUE obj)
return OBJ_PROMOTED(obj) ? Qtrue : Qfalse;
}
+size_t
+rb_obj_gc_flags(VALUE obj, ID* flags, size_t max)
+{
+ size_t n = 0;
+ static ID ID_marked;
+#if USE_RGENGC
+ static ID ID_wb_protected, ID_old, ID_remembered;
+#if RGENGC_THREEGEN
+ static ID ID_young, ID_infant;
+#endif
+#endif
+
+ if (!ID_marked) {
+#define I(s) ID_##s = rb_intern(#s);
+ I(marked);
+#if USE_RGENGC
+ I(wb_protected);
+ I(old);
+ I(remembered);
+#if RGENGC_THREEGEN
+ I(young);
+ I(infant);
+#endif
+#endif
+#undef I
+ }
+
+#if USE_RGENGC
+ if (OBJ_WB_PROTECTED(obj) && n<max)
+ flags[n++] = ID_wb_protected;
+ if (RVALUE_OLD_P(obj) && n<max)
+ flags[n++] = ID_old;
+#if RGENGC_THREEGEN
+ if (RVALUE_YOUNG_P(obj) && n<max)
+ flags[n++] = ID_young;
+ if (RVALUE_INFANT_P(obj) && n<max)
+ flags[n++] = ID_infant;
+#endif
+ if (MARKED_IN_BITMAP(GET_HEAP_REMEMBERSET_BITS(obj), obj) && n<max)
+ flags[n++] = ID_remembered;
+#endif
+ if (MARKED_IN_BITMAP(GET_HEAP_MARK_BITS(obj), obj) && n<max)
+ flags[n++] = ID_marked;
+
+ return n;
+}
+
/* GC */
void
diff --git a/internal.h b/internal.h
index 064f1a034a..9b8000d136 100644
--- a/internal.h
+++ b/internal.h
@@ -871,6 +871,8 @@ st_table *rb_st_copy(VALUE obj, struct st_table *orig_tbl);
/* gc.c */
size_t rb_obj_memsize_of(VALUE);
+#define RB_OBJ_GC_FLAGS_MAX 5
+size_t rb_obj_gc_flags(VALUE, ID[], size_t);
RUBY_SYMBOL_EXPORT_END
diff --git a/test/objspace/test_objspace.rb b/test/objspace/test_objspace.rb
index 38fd9bd46f..42dc55de9f 100644
--- a/test/objspace/test_objspace.rb
+++ b/test/objspace/test_objspace.rb
@@ -130,6 +130,7 @@ class TestObjSpace < Test::Unit::TestCase
end
def test_trace_object_allocations
+ Class.name
o0 = Object.new
ObjectSpace.trace_object_allocations{
o1 = Object.new; line1 = __LINE__; c1 = GC.count
@@ -193,6 +194,12 @@ class TestObjSpace < Test::Unit::TestCase
assert_equal(nil, ObjectSpace.allocation_sourcefile(obj3))
end
+ def test_dump_flags
+ info = ObjectSpace.dump("foo".freeze)
+ assert_match /"wb_protected":true, "old":true, "marked":true/, info
+ assert_match /"fstring":true/, info
+ end
+
def test_dump_to_default
line = nil
info = nil