aboutsummaryrefslogtreecommitdiffstats
path: root/variable.c
diff options
context:
space:
mode:
authorJean Boussier <byroot@ruby-lang.org>2023-02-27 15:46:44 +0100
committerJean Boussier <jean.boussier@gmail.com>2023-02-28 09:27:55 +0100
commitcf18f0b868de01666cbef6a117ac1642f4e0aa08 (patch)
tree5f6691d0d10679d829a7f6df55daea369c0b3435 /variable.c
parentcd1991281e2cfde5b5415612d4cc1c878748513a (diff)
downloadruby-cf18f0b868de01666cbef6a117ac1642f4e0aa08.tar.gz
Implement Write Barrier for `autoload_data`
It's not uncommon for libraries to add thing sinto autoload that won't necessarily be loaded. This can cause hundreds or thousands of entries to be left over in the autoload table, so it's best not to mark them on every minor.
Diffstat (limited to 'variable.c')
-rw-r--r--variable.c13
1 files changed, 7 insertions, 6 deletions
diff --git a/variable.c b/variable.c
index 1d2c6362c2..692d158a8c 100644
--- a/variable.c
+++ b/variable.c
@@ -2212,7 +2212,7 @@ autoload_data_memsize(const void *ptr)
static const rb_data_type_t autoload_data_type = {
"autoload_data",
{autoload_data_mark, autoload_data_free, autoload_data_memsize, autoload_data_compact},
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
};
static void
@@ -2263,11 +2263,12 @@ get_autoload_data(VALUE autoload_const_value, struct autoload_const **autoload_c
{
struct autoload_const *autoload_const = rb_check_typeddata(autoload_const_value, &autoload_const_type);
- struct autoload_data *autoload_data = rb_check_typeddata(autoload_const->autoload_data_value, &autoload_data_type);
+ VALUE autoload_data_value = autoload_const->autoload_data_value;
+ struct autoload_data *autoload_data = rb_check_typeddata(autoload_data_value, &autoload_data_type);
/* do not reach across stack for ->state after forking: */
if (autoload_data && autoload_data->fork_gen != GET_VM()->fork_gen) {
- autoload_data->mutex = Qnil;
+ RB_OBJ_WRITE(autoload_data_value, &autoload_data->mutex, Qnil);
autoload_data->fork_gen = 0;
}
@@ -2306,8 +2307,8 @@ autoload_feature_lookup_or_create(VALUE feature, struct autoload_data **autoload
if (NIL_P(autoload_data_value)) {
autoload_data_value = TypedData_Make_Struct(0, struct autoload_data, &autoload_data_type, autoload_data);
- autoload_data->feature = feature;
- autoload_data->mutex = Qnil;
+ RB_OBJ_WRITE(autoload_data_value, &autoload_data->feature, feature);
+ RB_OBJ_WRITE(autoload_data_value, &autoload_data->mutex, Qnil);
ccan_list_head_init(&autoload_data->constants);
if (autoload_data_pointer) *autoload_data_pointer = autoload_data;
@@ -2608,7 +2609,7 @@ autoload_load_needed(VALUE _arguments)
}
if (NIL_P(autoload_data->mutex)) {
- autoload_data->mutex = rb_mutex_new();
+ RB_OBJ_WRITE(autoload_const->autoload_data_value, &autoload_data->mutex, rb_mutex_new());
autoload_data->fork_gen = GET_VM()->fork_gen;
}
else if (rb_mutex_owned_p(autoload_data->mutex)) {