diff options
| author | NARUSE, Yui <nurse@users.noreply.github.com> | 2024-03-21 14:31:36 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-03-21 05:31:36 +0000 |
| commit | f79b1d1ef1f7aa64d20f0eadbb3b0f8f7084deb3 (patch) | |
| tree | 9e7a3db4bad45e170e273e71de4766a696fca8c6 /struct.c | |
| parent | 57a0afe2090b8d05673d650b1e8bf9ae67449b1f (diff) | |
merge revision(s) e626da82eae3d437b84d4f9ead0164d436b08e1a,f3af5ae7e6c1c096bbfe46d69de825a02b1696cf: [Backport #20311] (#10312)
Don't pin named structs defined in Ruby
[Bug #20311]
`rb_define_class_under` assumes it's called from C and that the
reference might be held in a C global variable, so it adds the
class to the VM root.
In the case of `Struct.new('Name')` it's wasteful and make
the struct immortal.
Make Struct memory leak test faster
[Bug #20311]
It times out on some platform, so we can reduce iterations.
On my machine it completes in 250ms and RSS grows 8X.
Diffstat (limited to 'struct.c')
| -rw-r--r-- | struct.c | 17 |
1 files changed, 12 insertions, 5 deletions
@@ -273,7 +273,7 @@ new_struct(VALUE name, VALUE super) rb_warn("redefining constant %"PRIsVALUE"::%"PRIsVALUE, super, name); rb_mod_remove_const(super, ID2SYM(id)); } - return rb_define_class_id_under(super, id, super); + return rb_define_class_id_under_no_pin(super, id, super); } NORETURN(static void invalid_struct_pos(VALUE s, VALUE idx)); @@ -491,8 +491,13 @@ rb_struct_define(const char *name, ...) ary = struct_make_members_list(ar); va_end(ar); - if (!name) st = anonymous_struct(rb_cStruct); - else st = new_struct(rb_str_new2(name), rb_cStruct); + if (!name) { + st = anonymous_struct(rb_cStruct); + } + else { + st = new_struct(rb_str_new2(name), rb_cStruct); + rb_vm_add_root_module(st); + } return setup_struct(st, ary); } @@ -506,7 +511,7 @@ rb_struct_define_under(VALUE outer, const char *name, ...) ary = struct_make_members_list(ar); va_end(ar); - return setup_struct(rb_define_class_under(outer, name, rb_cStruct), ary); + return setup_struct(rb_define_class_id_under(outer, rb_intern(name), rb_cStruct), ary); } /* @@ -1699,7 +1704,9 @@ rb_data_define(VALUE super, ...) ary = struct_make_members_list(ar); va_end(ar); if (!super) super = rb_cData; - return setup_data(anonymous_struct(super), ary); + VALUE klass = setup_data(anonymous_struct(super), ary); + rb_vm_add_root_module(klass); + return klass; } /* |
