diff options
author | Koichi Sasada <[email protected]> | 2020-03-10 02:22:11 +0900 |
---|---|---|
committer | Koichi Sasada <[email protected]> | 2020-09-03 21:11:06 +0900 |
commit | 79df14c04b452411b9d17e26a398e491bca1a811 (patch) | |
tree | 7598cee0f105439efd5bb328a727b0fe27d7c666 /vm_insnhelper.c | |
parent | eeb5325d3bfd71301896360c17e8f51abcb9a7e5 (diff) |
Introduce Ractor mechanism for parallel execution
This commit introduces Ractor mechanism to run Ruby program in
parallel. See doc/ractor.md for more details about Ractor.
See ticket [Feature #17100] to see the implementation details
and discussions.
[Feature #17100]
This commit does not complete the implementation. You can find
many bugs on using Ractor. Also the specification will be changed
so that this feature is experimental. You will see a warning when
you make the first Ractor with `Ractor.new`.
I hope this feature can help programmers from thread-safety issues.
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/3365
Diffstat (limited to 'vm_insnhelper.c')
-rw-r--r-- | vm_insnhelper.c | 55 |
1 files changed, 33 insertions, 22 deletions
diff --git a/vm_insnhelper.c b/vm_insnhelper.c index 9dcd75cc6c..428331a902 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -985,7 +985,13 @@ vm_get_ev_const(rb_execution_context_t *ec, VALUE orig_klass, ID id, bool allow_ if (is_defined) { return 1; } - else { + else { + if (UNLIKELY(!rb_ractor_main_p())) { + if (!rb_ractor_shareable_p(val)) { + rb_raise(rb_eNameError, + "can not access non-sharable objects in constant %"PRIsVALUE"::%s by non-main ractor.", rb_class_path(klass), rb_id2name(id)); + } + } return val; } } @@ -1084,7 +1090,7 @@ vm_getivar(VALUE obj, ID id, IVC ic, const struct rb_callcache *cc, int is_attr) else if (FL_TEST_RAW(obj, FL_EXIVAR)) { struct gen_ivtbl *ivtbl; - if (LIKELY(st_lookup(rb_ivar_generic_ivtbl(), (st_data_t)obj, (st_data_t *)&ivtbl)) && + if (LIKELY(st_lookup(rb_ivar_generic_ivtbl(obj), (st_data_t)obj, (st_data_t *)&ivtbl)) && LIKELY(index < ivtbl->numiv)) { val = ivtbl->ivptr[index]; } @@ -1106,8 +1112,7 @@ vm_getivar(VALUE obj, ID id, IVC ic, const struct rb_callcache *cc, int is_attr) } else if (FL_TEST_RAW(obj, FL_EXIVAR)) { struct gen_ivtbl *ivtbl; - - if (LIKELY(st_lookup(rb_ivar_generic_ivtbl(), (st_data_t)obj, (st_data_t *)&ivtbl))) { + if (LIKELY(st_lookup(rb_ivar_generic_ivtbl(obj), (st_data_t)obj, (st_data_t *)&ivtbl))) { numiv = ivtbl->numiv; ivptr = ivtbl->ivptr; iv_index_tbl = RCLASS_IV_INDEX_TBL(rb_obj_class(obj)); @@ -1634,26 +1639,30 @@ vm_search_cc(VALUE klass, const struct rb_callinfo *ci) MJIT_FUNC_EXPORTED void rb_vm_search_method_slowpath(VALUE cd_owner, struct rb_call_data *cd, VALUE klass) { - const struct rb_callcache *cc = vm_search_cc(klass, cd->ci); + RB_VM_LOCK_ENTER(); + { + const struct rb_callcache *cc = vm_search_cc(klass, cd->ci); - VM_ASSERT(cc); - VM_ASSERT(IMEMO_TYPE_P(cc, imemo_callcache)); + VM_ASSERT(cc); + VM_ASSERT(IMEMO_TYPE_P(cc, imemo_callcache)); - if (! cd_owner) { - cd->cc = cc; - } - else if (cc == &vm_empty_cc) { - cd->cc = cc; - } - else { - VM_ASSERT(vm_cc_markable(cc)); - RB_OBJ_WRITE(cd_owner, &cd->cc, cc); - } + if (! cd_owner) { + cd->cc = cc; + } + else if (cc == &vm_empty_cc) { + cd->cc = cc; + } + else { + VM_ASSERT(vm_cc_markable(cc)); + RB_OBJ_WRITE(cd_owner, &cd->cc, cc); + } - VM_ASSERT(cc == vm_cc_empty() || cc->klass == klass); - VM_ASSERT(cc == vm_cc_empty() || callable_method_entry_p(vm_cc_cme(cc))); - VM_ASSERT(cc == vm_cc_empty() || !METHOD_ENTRY_INVALIDATED(vm_cc_cme(cc))); - VM_ASSERT(cc == vm_cc_empty() || vm_cc_cme(cc)->called_id == vm_ci_mid(cd->ci)); + VM_ASSERT(cc == vm_cc_empty() || cc->klass == klass); + VM_ASSERT(cc == vm_cc_empty() || callable_method_entry_p(vm_cc_cme(cc))); + VM_ASSERT(cc == vm_cc_empty() || !METHOD_ENTRY_INVALIDATED(vm_cc_cme(cc))); + VM_ASSERT(cc == vm_cc_empty() || vm_cc_cme(cc)->called_id == vm_ci_mid(cd->ci)); + } + RB_VM_LOCK_LEAVE(); } #endif @@ -4297,7 +4306,8 @@ vm_opt_newarray_min(rb_num_t num, const VALUE *ptr) static int vm_ic_hit_p(IC ic, const VALUE *reg_ep) { - if (ic->ic_serial == GET_GLOBAL_CONSTANT_STATE()) { + if (ic->ic_serial == GET_GLOBAL_CONSTANT_STATE() && + rb_ractor_main_p()) { return (ic->ic_cref == NULL || // no need to check CREF ic->ic_cref == vm_get_cref(reg_ep)); } @@ -5023,6 +5033,7 @@ Init_vm_stack_canary(void) { /* This has to be called _after_ our PRNG is properly set up. */ int n = ruby_fill_random_bytes(&vm_stack_canary, sizeof vm_stack_canary, false); + vm_stack_canary |= 0x01; // valid VALUE (Fixnum) vm_stack_canary_was_born = true; VM_ASSERT(n == 0); |