summaryrefslogtreecommitdiff
path: root/gc.c
diff options
context:
space:
mode:
authorJohn Hawthorn <john@hawthorn.email>2020-08-25 23:42:15 -0700
committerAaron Patterson <aaron.patterson@gmail.com>2020-09-02 14:54:29 -0700
commit0b81a484f3453082d28a48968a063fd907daa5b5 (patch)
tree8de85d3e490af9f92e623ab3fca6a29b151f9475 /gc.c
parenteada6350332155972f19bad52bd8621f607520a2 (diff)
Initialize new T_OBJECT as ROBJECT_EMBED
Previously, when an object is first initialized, ROBJECT_EMBED isn't set. This means that for brand new objects, ROBJECT_NUMIV(obj) is 0 and ROBJECT_IV_INDEX_TBL(obj) is NULL. Previously, this combination meant that the inline cache would never be initialized when setting an ivar on an object for the first time since iv_index_tbl was NULL, and if it were it would never be used because ROBJECT_NUMIV was 0. Both cases always fell through to the generic rb_ivar_set which would then set the ROBJECT_EMBED flag and initialize the ivar array. This commit changes rb_class_allocate_instance to set the ROBJECT_EMBED flag on the object initially and to initialize all members of the embedded array to Qundef. This allows the inline cache to be set correctly on first use and to be used on future uses. This moves rb_class_allocate_instance to gc.c, so that it has access to newobj_of. This seems appropriate given that there are other allocating methods in this file (ex. rb_data_object_wrap, rb_imemo_new).
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/3486
Diffstat (limited to 'gc.c')
-rw-r--r--gc.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/gc.c b/gc.c
index 05d75e16e2..9b453cb6ed 100644
--- a/gc.c
+++ b/gc.c
@@ -2374,6 +2374,13 @@ rb_imemo_new_debug(enum imemo_type type, VALUE v1, VALUE v2, VALUE v3, VALUE v0,
#endif
VALUE
+rb_class_allocate_instance(VALUE klass)
+{
+ VALUE flags = T_OBJECT | ROBJECT_EMBED;
+ return newobj_of(klass, flags, Qundef, Qundef, Qundef, RGENGC_WB_PROTECTED_OBJECT);
+}
+
+VALUE
rb_data_object_wrap(VALUE klass, void *datap, RUBY_DATA_FUNC dmark, RUBY_DATA_FUNC dfree)
{
RUBY_ASSERT_ALWAYS(dfree != (RUBY_DATA_FUNC)1);