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.
This commit is contained in:
Jean Boussier 2023-02-27 15:46:44 +01:00 committed by Jean Boussier
parent cd1991281e
commit cf18f0b868
Notes: git 2023-02-28 08:28:21 +00:00

View File

@ -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)) {