mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
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
This commit is contained in:
parent
97d292cb55
commit
7170baa878
5 changed files with 85 additions and 0 deletions
12
ChangeLog
12
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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
47
gc.c
47
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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue