summaryrefslogtreecommitdiff
path: root/struct.c
diff options
context:
space:
mode:
authornagachika <nagachika@ruby-lang.org>2024-07-07 14:47:04 +0900
committernagachika <nagachika@ruby-lang.org>2024-07-07 16:44:06 +0900
commitbd5df1693c89d389471d145fc19b487c708912b1 (patch)
tree02aa26c8eb487a23cf867248464c19c3bbac02a0 /struct.c
parent2a4469ea590e6719eb30e8b7aea7e147e3b82f75 (diff)
merge revision(s) e626da82eae3d437b84d4f9ead0164d436b08e1a, f3af5ae7e6c1c096bbfe46d69de825a02b1696cf: [Backport #20311]
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.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/struct.c b/struct.c
index f68c496728..8b7fea7f95 100644
--- a/struct.c
+++ b/struct.c
@@ -274,7 +274,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));
@@ -495,8 +495,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);
}
@@ -510,7 +515,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);
}
/*