diff options
author | Jean Boussier <byroot@ruby-lang.org> | 2023-02-28 10:04:53 +0100 |
---|---|---|
committer | Jean Boussier <jean.boussier@gmail.com> | 2023-03-01 08:56:56 +0100 |
commit | 40e5ee64f08c5a264b95dc2d35d5d3cbcbf858a0 (patch) | |
tree | e993dca97555715074bdbb00fd49aae54b8fca10 /variable.c | |
parent | ee83274f36cdbf1ad12c611273de1042a0f24441 (diff) |
Implement Write Barrier for `autoload_table_type`
It's just a decorated st_table, so we call `RB_OBJ_WRITTEN` after
inserting to it.
We also call `RB_OBJ_WRITTEN` on delete for completeness even though
it's a noop.
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/7402
Diffstat (limited to 'variable.c')
-rw-r--r-- | variable.c | 28 |
1 files changed, 16 insertions, 12 deletions
diff --git a/variable.c b/variable.c index 26a00db7c4..1a417da08e 100644 --- a/variable.c +++ b/variable.c @@ -2099,7 +2099,7 @@ autoload_table_compact(void *ptr) static const rb_data_type_t autoload_table_type = { "autoload_table", {autoload_table_mark, autoload_table_free, autoload_table_memsize, autoload_table_compact,}, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED }; #define check_autoload_table(av) \ @@ -2126,8 +2126,8 @@ autoload_data(VALUE mod, ID id) // Look up the instance variable table for `autoload`, then index into that table with the given constant name `id`. - VALUE tbl_value = rb_ivar_lookup(mod, autoload, 0); - if (!tbl_value || !(tbl = check_autoload_table(tbl_value)) || !st_lookup(tbl, (st_data_t)id, &val)) { + VALUE tbl_value = rb_ivar_lookup(mod, autoload, Qfalse); + if (!RTEST(tbl_value) || !(tbl = check_autoload_table(tbl_value)) || !st_lookup(tbl, (st_data_t)id, &val)) { return 0; } @@ -2323,17 +2323,18 @@ autoload_feature_lookup_or_create(VALUE feature, struct autoload_data **autoload return autoload_data_value; } -static struct st_table * +static VALUE autoload_table_lookup_or_create(VALUE module) { - VALUE autoload_table_value = rb_ivar_lookup(module, autoload, 0); - if (autoload_table_value) { - return check_autoload_table(autoload_table_value); + VALUE autoload_table_value = rb_ivar_lookup(module, autoload, Qfalse); + if (RTEST(autoload_table_value)) { + return autoload_table_value; } else { - autoload_table_value = TypedData_Wrap_Struct(0, &autoload_table_type, 0); + autoload_table_value = TypedData_Wrap_Struct(0, &autoload_table_type, NULL); rb_class_ivar_set(module, autoload, autoload_table_value); - return (DATA_PTR(autoload_table_value) = st_init_numtable()); + RTYPEDDATA_DATA(autoload_table_value) = st_init_numtable(); + return autoload_table_value; } } @@ -2350,7 +2351,8 @@ autoload_synchronized(VALUE _arguments) // Reset any state associated with any previous constant: const_set(arguments->module, arguments->name, Qundef); - struct st_table *autoload_table = autoload_table_lookup_or_create(arguments->module); + VALUE autoload_table_value = autoload_table_lookup_or_create(arguments->module); + struct st_table *autoload_table = check_autoload_table(autoload_table_value); // Ensure the string is uniqued since we use an identity lookup: VALUE feature = rb_fstring(arguments->feature); @@ -2368,6 +2370,7 @@ autoload_synchronized(VALUE _arguments) autoload_const->autoload_data_value = autoload_data_value; ccan_list_add_tail(&autoload_data->constants, &autoload_const->cnode); st_insert(autoload_table, (st_data_t)arguments->name, (st_data_t)autoload_const_value); + RB_OBJ_WRITTEN(autoload_table_value, Qundef, autoload_const_value); } return Qtrue; @@ -2407,11 +2410,12 @@ autoload_delete(VALUE module, ID name) RUBY_ASSERT(RB_TYPE_P(module, T_CLASS) || RB_TYPE_P(module, T_MODULE)); - VALUE table_value = rb_ivar_lookup(module, autoload, 0); - if (table_value) { + VALUE table_value = rb_ivar_lookup(module, autoload, Qfalse); + if (RTEST(table_value)) { struct st_table *table = check_autoload_table(table_value); st_delete(table, &key, &load); + RB_OBJ_WRITTEN(table_value, load, Qundef); /* Qfalse can indicate already deleted */ if (load != Qfalse) { |