From 5e45f2a0bce9a94b1b5f9eda615344e74a39e597 Mon Sep 17 00:00:00 2001 From: Peter Zhu Date: Tue, 18 Feb 2025 13:45:27 -0500 Subject: [PATCH] Add age to rb_gc_object_metadata This will allow ObjectSpace.dump to output the age of the object. --- gc/default/default.c | 4 +++- test/objspace/test_objspace.rb | 16 +++++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/gc/default/default.c b/gc/default/default.c index 03427f51a1..0147640af7 100644 --- a/gc/default/default.c +++ b/gc/default/default.c @@ -6197,11 +6197,12 @@ rb_gc_impl_object_metadata(void *objspace_ptr, VALUE obj) { rb_objspace_t *objspace = objspace_ptr; size_t n = 0; - static ID ID_wb_protected, ID_old, ID_uncollectible, ID_marking, ID_marked, ID_pinned; + static ID ID_wb_protected, ID_age, ID_old, ID_uncollectible, ID_marking, ID_marked, ID_pinned; if (!ID_marked) { #define I(s) ID_##s = rb_intern(#s); I(wb_protected); + I(age); I(old); I(uncollectible); I(marking); @@ -6218,6 +6219,7 @@ rb_gc_impl_object_metadata(void *objspace_ptr, VALUE obj) } while (0) if (!RVALUE_WB_UNPROTECTED(objspace, obj)) SET_ENTRY(wb_protected, Qtrue); + SET_ENTRY(age, INT2FIX(RVALUE_AGE_GET(obj))); if (RVALUE_OLD_P(objspace, obj)) SET_ENTRY(old, Qtrue); if (RVALUE_UNCOLLECTIBLE(objspace, obj)) SET_ENTRY(uncollectible, Qtrue); if (RVALUE_MARKING(objspace, obj)) SET_ENTRY(marking, Qtrue); diff --git a/test/objspace/test_objspace.rb b/test/objspace/test_objspace.rb index 939092e1c1..2f78df8faa 100644 --- a/test/objspace/test_objspace.rb +++ b/test/objspace/test_objspace.rb @@ -332,11 +332,25 @@ class TestObjSpace < Test::Unit::TestCase # Ensure that the fstring is promoted to old generation 4.times { GC.start } info = ObjectSpace.dump("foo".freeze) - assert_match(/"wb_protected":true, "old":true/, info) + assert_include(info, '"wb_protected":true') + assert_include(info, '"age":3') + assert_include(info, '"old":true') assert_match(/"fstring":true/, info) JSON.parse(info) if defined?(JSON) end + def test_dump_flag_age + EnvUtil.without_gc do + o = Object.new + + assert_include(ObjectSpace.dump(o), '"age":0') + + GC.start + + assert_include(ObjectSpace.dump(o), '"age":1') + end + end + if defined?(RubyVM::Shape) class TooComplex; end