aboutsummaryrefslogtreecommitdiffstats
path: root/variable.c
diff options
context:
space:
mode:
authorKoichi Sasada <ko1@atdot.net>2020-10-14 10:43:13 +0900
committerKoichi Sasada <ko1@atdot.net>2020-10-14 16:36:55 +0900
commitfad97f1f96caf11005a5858a29d32c66203913e8 (patch)
tree156a20da88b4e1efae3c9f749a1ed0dd2181da86 /variable.c
parentae693fff748c68ca2500bbc2c0a8802d50f269dc (diff)
downloadruby-fad97f1f96caf11005a5858a29d32c66203913e8.tar.gz
sync generic_ivtbl
generic_ivtbl is a process global table to maintain instance variables for non T_OBJECT/T_CLASS/... objects. So we need to protect them for multi-Ractor exection. Hint: we can make them Ractor local for unshareable objects, but now it is premature optimization.
Diffstat (limited to 'variable.c')
-rw-r--r--variable.c46
1 files changed, 32 insertions, 14 deletions
diff --git a/variable.c b/variable.c
index 0689112161..bf80df7fae 100644
--- a/variable.c
+++ b/variable.c
@@ -37,6 +37,7 @@
#include "variable.h"
#include "vm_core.h"
#include "ractor_pub.h"
+#include "vm_sync.h"
typedef void rb_gvar_compact_t(void *var);
@@ -896,6 +897,8 @@ IVAR_ACCESSOR_SHOULD_BE_MAIN_RACTOR(ID id)
static inline struct st_table *
generic_ivtbl(VALUE obj, ID id, bool force_check_ractor)
{
+ ASSERT_vm_locking();
+
if ((force_check_ractor || rb_is_instance_id(id)) && // not internal ID
UNLIKELY(rb_ractor_shareable_p(obj) && !rb_ractor_main_p())) {
rb_raise(rb_eRuntimeError, "can not access instance variables of shareable objects from non-main Ractors");
@@ -909,22 +912,28 @@ generic_ivtbl_no_ractor_check(VALUE obj)
return generic_ivtbl(obj, 0, false);
}
-MJIT_FUNC_EXPORTED struct st_table *
-rb_ivar_generic_ivtbl(VALUE obj)
-{
- return generic_ivtbl(obj, 0, true);
-}
-
static int
gen_ivtbl_get(VALUE obj, ID id, struct gen_ivtbl **ivtbl)
{
st_data_t data;
+ int r = 0;
- if (st_lookup(generic_ivtbl(obj, id, false), (st_data_t)obj, &data)) {
- *ivtbl = (struct gen_ivtbl *)data;
- return 1;
+ RB_VM_LOCK_ENTER();
+ {
+ if (st_lookup(generic_ivtbl(obj, id, false), (st_data_t)obj, &data)) {
+ *ivtbl = (struct gen_ivtbl *)data;
+ r = 1;
+ }
}
- return 0;
+ RB_VM_LOCK_LEAVE();
+
+ return r;
+}
+
+MJIT_FUNC_EXPORTED int
+rb_ivar_generic_ivtbl_lookup(VALUE obj, struct gen_ivtbl **ivtbl)
+{
+ return gen_ivtbl_get(obj, 0, ivtbl);
}
static VALUE
@@ -1275,8 +1284,13 @@ generic_ivar_set(VALUE obj, ID id, VALUE val)
ivup.iv_extended = 0;
ivup.u.iv_index_tbl = iv_index_tbl_make(obj);
iv_index_tbl_extend(&ivup, id);
- st_update(generic_ivtbl(obj, id, false), (st_data_t)obj, generic_ivar_update,
- (st_data_t)&ivup);
+
+ RB_VM_LOCK_ENTER();
+ {
+ st_update(generic_ivtbl(obj, id, false), (st_data_t)obj, generic_ivar_update,
+ (st_data_t)&ivup);
+ }
+ RB_VM_LOCK_LEAVE();
ivup.u.ivtbl->ivptr[ivup.index] = val;
@@ -1590,8 +1604,12 @@ rb_copy_generic_ivar(VALUE clone, VALUE obj)
* c.ivtbl may change in gen_ivar_copy due to realloc,
* no need to free
*/
- generic_ivtbl_no_ractor_check(clone);
- st_insert(generic_ivtbl_no_ractor_check(obj), (st_data_t)clone, (st_data_t)c.ivtbl);
+ RB_VM_LOCK_ENTER();
+ {
+ generic_ivtbl_no_ractor_check(clone);
+ st_insert(generic_ivtbl_no_ractor_check(obj), (st_data_t)clone, (st_data_t)c.ivtbl);
+ }
+ RB_VM_LOCK_LEAVE();
}
return;