diff --git a/gc.c b/gc.c index d9f495b..1a95745 100644 --- a/gc.c +++ b/gc.c @@ -1820,6 +1820,7 @@ newobj_init(VALUE klass, VALUE flags, VALUE v1, VALUE v2, VALUE v3, int wb_prote #endif objspace->total_allocated_objects++; + GET_THREAD()->allocated_objects++; gc_report(5, objspace, "newobj: %s\n", obj_info(obj)); diff --git a/test/ruby/test_thread.rb b/test/ruby/test_thread.rb index f13a962..70f784e 100644 --- a/test/ruby/test_thread.rb +++ b/test/ruby/test_thread.rb @@ -1104,4 +1104,15 @@ def test_thread_setname_in_initialize c = Class.new(Thread) {def initialize() self.name = "foo"; super; end} assert_equal("foo", c.new {Thread.current.name}.value) end + + def test_thread_allocated_objects + t = Thread.new do + 1000.times do + Object.new + end + end + + t.join + assert_equal 1001, t.allocated_objects + end end diff --git a/thread.c b/thread.c index ac31da5..421c6b1 100644 --- a/thread.c +++ b/thread.c @@ -2616,6 +2616,14 @@ rb_thread_group(VALUE thread) return group; } +VALUE +rb_thread_allocated_objects(VALUE thread) +{ + rb_thread_t *th; + GetThreadPtr(thread, th); + return LONG2NUM(th->allocated_objects); +} + static const char * thread_status_name(rb_thread_t *th) { @@ -4653,6 +4661,7 @@ Init_Thread(void) rb_define_method(rb_cThread, "abort_on_exception=", rb_thread_abort_exc_set, 1); rb_define_method(rb_cThread, "safe_level", rb_thread_safe_level, 0); rb_define_method(rb_cThread, "group", rb_thread_group, 0); + rb_define_method(rb_cThread, "allocated_objects", rb_thread_allocated_objects, 0); rb_define_method(rb_cThread, "backtrace", rb_thread_backtrace_m, -1); rb_define_method(rb_cThread, "backtrace_locations", rb_thread_backtrace_locations_m, -1); diff --git a/vm_core.h b/vm_core.h index 5c1e718..4b45ad3 100644 --- a/vm_core.h +++ b/vm_core.h @@ -682,6 +682,7 @@ typedef struct rb_thread_struct { int safe_level; int raised_flag; VALUE last_status; /* $? */ + uint64_t allocated_objects; /* passing state */ int state;