RCLASS_CONST_TBL() is shared resource so we need to sync with
other ractors.
This commit is contained in:
Koichi Sasada 2020-12-20 03:23:41 +09:00
Родитель 648bbfcc65
Коммит f70b894b88
1 изменённых файлов: 62 добавлений и 29 удалений

Просмотреть файл

@ -2349,7 +2349,13 @@ autoload_const_set(struct autoload_const *ac)
VALUE klass = ac->mod; VALUE klass = ac->mod;
ID id = ac->id; ID id = ac->id;
check_before_mod_set(klass, id, ac->value, "constant"); check_before_mod_set(klass, id, ac->value, "constant");
RB_VM_LOCK_ENTER();
{
const_tbl_update(ac); const_tbl_update(ac);
}
RB_VM_LOCK_LEAVE();
return 0; /* ignored */ return 0; /* ignored */
} }
@ -2782,8 +2788,13 @@ rb_local_constants(VALUE mod)
if (!tbl) return rb_ary_new2(0); if (!tbl) return rb_ary_new2(0);
RB_VM_LOCK_ENTER();
{
ary = rb_ary_new2(rb_id_table_size(tbl)); ary = rb_ary_new2(rb_id_table_size(tbl));
rb_id_table_foreach(tbl, rb_local_constants_i, (void *)ary); rb_id_table_foreach(tbl, rb_local_constants_i, (void *)ary);
}
RB_VM_LOCK_LEAVE();
return ary; return ary;
} }
@ -2795,8 +2806,12 @@ rb_mod_const_at(VALUE mod, void *data)
tbl = st_init_numtable(); tbl = st_init_numtable();
} }
if (RCLASS_CONST_TBL(mod)) { if (RCLASS_CONST_TBL(mod)) {
RB_VM_LOCK_ENTER();
{
rb_id_table_foreach(RCLASS_CONST_TBL(mod), sv_i, tbl); rb_id_table_foreach(RCLASS_CONST_TBL(mod), sv_i, tbl);
} }
RB_VM_LOCK_LEAVE();
}
return tbl; return tbl;
} }
@ -2971,6 +2986,9 @@ static void
set_namespace_path(VALUE named_namespace, VALUE namespace_path) set_namespace_path(VALUE named_namespace, VALUE namespace_path)
{ {
struct rb_id_table *const_table = RCLASS_CONST_TBL(named_namespace); struct rb_id_table *const_table = RCLASS_CONST_TBL(named_namespace);
RB_VM_LOCK_ENTER();
{
if (!RCLASS_IV_TBL(named_namespace)) { if (!RCLASS_IV_TBL(named_namespace)) {
RCLASS_IV_TBL(named_namespace) = st_init_numtable(); RCLASS_IV_TBL(named_namespace) = st_init_numtable();
} }
@ -2978,13 +2996,14 @@ set_namespace_path(VALUE named_namespace, VALUE namespace_path)
if (const_table) { if (const_table) {
rb_id_table_foreach(const_table, set_namespace_path_i, &namespace_path); rb_id_table_foreach(const_table, set_namespace_path_i, &namespace_path);
} }
}
RB_VM_LOCK_LEAVE();
} }
void void
rb_const_set(VALUE klass, ID id, VALUE val) rb_const_set(VALUE klass, ID id, VALUE val)
{ {
rb_const_entry_t *ce; rb_const_entry_t *ce;
struct rb_id_table *tbl = RCLASS_CONST_TBL(klass);
if (NIL_P(klass)) { if (NIL_P(klass)) {
rb_raise(rb_eTypeError, "no class/module to define constant %"PRIsVALUE"", rb_raise(rb_eTypeError, "no class/module to define constant %"PRIsVALUE"",
@ -2996,6 +3015,10 @@ rb_const_set(VALUE klass, ID id, VALUE val)
} }
check_before_mod_set(klass, id, val, "constant"); check_before_mod_set(klass, id, val, "constant");
RB_VM_LOCK_ENTER();
{
struct rb_id_table *tbl = RCLASS_CONST_TBL(klass);
if (!tbl) { if (!tbl) {
RCLASS_CONST_TBL(klass) = tbl = rb_id_table_create(0); RCLASS_CONST_TBL(klass) = tbl = rb_id_table_create(0);
rb_clear_constant_cache(); rb_clear_constant_cache();
@ -3011,6 +3034,9 @@ rb_const_set(VALUE klass, ID id, VALUE val)
}; };
const_tbl_update(&ac); const_tbl_update(&ac);
} }
}
RB_VM_LOCK_LEAVE();
/* /*
* Resolve and cache class name immediately to resolve ambiguity * Resolve and cache class name immediately to resolve ambiguity
* and avoid order-dependency on const_tbl * and avoid order-dependency on const_tbl
@ -3589,10 +3615,17 @@ MJIT_FUNC_EXPORTED rb_const_entry_t *
rb_const_lookup(VALUE klass, ID id) rb_const_lookup(VALUE klass, ID id)
{ {
struct rb_id_table *tbl = RCLASS_CONST_TBL(klass); struct rb_id_table *tbl = RCLASS_CONST_TBL(klass);
VALUE val;
if (tbl && rb_id_table_lookup(tbl, id, &val)) { if (tbl) {
return (rb_const_entry_t *)val; VALUE val;
bool r;
RB_VM_LOCK_ENTER();
{
r = rb_id_table_lookup(tbl, id, &val);
} }
return 0; RB_VM_LOCK_LEAVE();
if (r) return (rb_const_entry_t *)val;
}
return NULL;
} }