From f70b894b8829c064e39646c9b5f6d304d13bb16d Mon Sep 17 00:00:00 2001 From: Koichi Sasada Date: Sun, 20 Dec 2020 03:23:41 +0900 Subject: [PATCH] sync RCLASS_CONST_TBL() RCLASS_CONST_TBL() is shared resource so we need to sync with other ractors. --- variable.c | 91 +++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 62 insertions(+), 29 deletions(-) diff --git a/variable.c b/variable.c index 3b1462b9de..b780446f19 100644 --- a/variable.c +++ b/variable.c @@ -2349,7 +2349,13 @@ autoload_const_set(struct autoload_const *ac) VALUE klass = ac->mod; ID id = ac->id; check_before_mod_set(klass, id, ac->value, "constant"); - const_tbl_update(ac); + + RB_VM_LOCK_ENTER(); + { + const_tbl_update(ac); + } + RB_VM_LOCK_LEAVE(); + return 0; /* ignored */ } @@ -2782,8 +2788,13 @@ rb_local_constants(VALUE mod) if (!tbl) return rb_ary_new2(0); - ary = rb_ary_new2(rb_id_table_size(tbl)); - rb_id_table_foreach(tbl, rb_local_constants_i, (void *)ary); + RB_VM_LOCK_ENTER(); + { + ary = rb_ary_new2(rb_id_table_size(tbl)); + rb_id_table_foreach(tbl, rb_local_constants_i, (void *)ary); + } + RB_VM_LOCK_LEAVE(); + return ary; } @@ -2795,7 +2806,11 @@ rb_mod_const_at(VALUE mod, void *data) tbl = st_init_numtable(); } if (RCLASS_CONST_TBL(mod)) { - rb_id_table_foreach(RCLASS_CONST_TBL(mod), sv_i, tbl); + RB_VM_LOCK_ENTER(); + { + rb_id_table_foreach(RCLASS_CONST_TBL(mod), sv_i, tbl); + } + RB_VM_LOCK_LEAVE(); } return tbl; } @@ -2971,20 +2986,24 @@ static void set_namespace_path(VALUE named_namespace, VALUE namespace_path) { struct rb_id_table *const_table = RCLASS_CONST_TBL(named_namespace); - if (!RCLASS_IV_TBL(named_namespace)) { - RCLASS_IV_TBL(named_namespace) = st_init_numtable(); - } - rb_class_ivar_set(named_namespace, classpath, namespace_path); - if (const_table) { - rb_id_table_foreach(const_table, set_namespace_path_i, &namespace_path); + + RB_VM_LOCK_ENTER(); + { + if (!RCLASS_IV_TBL(named_namespace)) { + RCLASS_IV_TBL(named_namespace) = st_init_numtable(); + } + rb_class_ivar_set(named_namespace, classpath, namespace_path); + if (const_table) { + rb_id_table_foreach(const_table, set_namespace_path_i, &namespace_path); + } } + RB_VM_LOCK_LEAVE(); } void rb_const_set(VALUE klass, ID id, VALUE val) { rb_const_entry_t *ce; - struct rb_id_table *tbl = RCLASS_CONST_TBL(klass); if (NIL_P(klass)) { rb_raise(rb_eTypeError, "no class/module to define constant %"PRIsVALUE"", @@ -2996,21 +3015,28 @@ rb_const_set(VALUE klass, ID id, VALUE val) } check_before_mod_set(klass, id, val, "constant"); - if (!tbl) { - RCLASS_CONST_TBL(klass) = tbl = rb_id_table_create(0); - rb_clear_constant_cache(); - ce = ZALLOC(rb_const_entry_t); - rb_id_table_insert(tbl, id, (VALUE)ce); - setup_const_entry(ce, klass, val, CONST_PUBLIC); - } - else { - struct autoload_const ac = { - .mod = klass, .id = id, - .value = val, .flag = CONST_PUBLIC, - /* fill the rest with 0 */ - }; - const_tbl_update(&ac); + + RB_VM_LOCK_ENTER(); + { + struct rb_id_table *tbl = RCLASS_CONST_TBL(klass); + if (!tbl) { + RCLASS_CONST_TBL(klass) = tbl = rb_id_table_create(0); + rb_clear_constant_cache(); + ce = ZALLOC(rb_const_entry_t); + rb_id_table_insert(tbl, id, (VALUE)ce); + setup_const_entry(ce, klass, val, CONST_PUBLIC); + } + else { + struct autoload_const ac = { + .mod = klass, .id = id, + .value = val, .flag = CONST_PUBLIC, + /* fill the rest with 0 */ + }; + const_tbl_update(&ac); + } } + RB_VM_LOCK_LEAVE(); + /* * Resolve and cache class name immediately to resolve ambiguity * 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) { struct rb_id_table *tbl = RCLASS_CONST_TBL(klass); - VALUE val; - if (tbl && rb_id_table_lookup(tbl, id, &val)) { - return (rb_const_entry_t *)val; + if (tbl) { + VALUE val; + bool r; + RB_VM_LOCK_ENTER(); + { + r = rb_id_table_lookup(tbl, id, &val); + } + RB_VM_LOCK_LEAVE(); + + if (r) return (rb_const_entry_t *)val; } - return 0; + return NULL; }