Skip to content

Commit 004eef1

Browse files
committed
Add ASSERT_vm_unlocking() to vm_call0_body
This uncovered many more test failures.
1 parent 1e3e0c7 commit 004eef1

11 files changed

Lines changed: 150 additions & 45 deletions

File tree

encoding.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,7 @@ static int
345345
enc_table_expand(struct enc_table *enc_table, int newsize)
346346
{
347347
if (newsize > ENCODING_LIST_CAPA) {
348+
RB_VM_UNLOCK();
348349
rb_raise(rb_eEncodingError, "too many encoding (> %d)", ENCODING_LIST_CAPA);
349350
}
350351
return newsize;
@@ -491,9 +492,11 @@ static void
491492
enc_check_addable(struct enc_table *enc_table, const char *name)
492493
{
493494
if (enc_registered(enc_table, name) >= 0) {
495+
RB_VM_UNLOCK();
494496
rb_raise(rb_eArgError, "encoding %s is already registered", name);
495497
}
496498
else if (!valid_encoding_name_p(name)) {
499+
RB_VM_UNLOCK();
497500
rb_raise(rb_eArgError, "invalid encoding name: %s", name);
498501
}
499502
}
@@ -541,7 +544,10 @@ enc_replicate(struct enc_table *enc_table, const char *name, rb_encoding *encodi
541544

542545
enc_check_addable(enc_table, name);
543546
idx = enc_register(enc_table, name, encoding);
544-
if (idx < 0) rb_raise(rb_eArgError, "invalid encoding name: %s", name);
547+
if (idx < 0) {
548+
RB_VM_UNLOCK();
549+
rb_raise(rb_eArgError, "invalid encoding name: %s", name);
550+
}
545551
set_base_encoding(enc_table, idx, encoding);
546552
return idx;
547553
}
@@ -559,6 +565,7 @@ enc_replicate_with_index(struct enc_table *enc_table, const char *name, rb_encod
559565
set_base_encoding(enc_table, idx, origenc);
560566
}
561567
else {
568+
RB_VM_UNLOCK();
562569
rb_raise(rb_eArgError, "failed to replicate encoding");
563570
}
564571
return idx;
@@ -885,7 +892,7 @@ int
885892
rb_enc_find_index(const char *name)
886893
{
887894
int i;
888-
#if RUBY_DEBUG > 0
895+
#if RUBY_DEBUG
889896
if (rb_multi_ractor_p() || !rb_enc_registered(name)) {
890897
ASSERT_vm_unlocking(); // it needs to be unlocked so it can call `load_encoding` if necessary
891898
}

eval.c

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2078,7 +2078,14 @@ errat_getter(ID id, VALUE *_)
20782078
{
20792079
VALUE err = get_errinfo();
20802080
if (!NIL_P(err)) {
2081-
return rb_get_backtrace(err);
2081+
VALUE bt;
2082+
RB_VM_UNLOCK();
2083+
{
2084+
bt = rb_get_backtrace(err);
2085+
}
2086+
RB_VM_LOCK();
2087+
2088+
return bt;
20822089
}
20832090
else {
20842091
return Qnil;
@@ -2089,10 +2096,14 @@ static void
20892096
errat_setter(VALUE val, ID id, VALUE *var)
20902097
{
20912098
VALUE err = get_errinfo();
2092-
if (NIL_P(err)) {
2093-
rb_raise(rb_eArgError, "$! not set");
2099+
RB_VM_UNLOCK();
2100+
{
2101+
if (NIL_P(err)) {
2102+
rb_raise(rb_eArgError, "$! not set");
2103+
}
2104+
set_backtrace(err, val);
20942105
}
2095-
set_backtrace(err, val);
2106+
RB_VM_LOCK();
20962107
}
20972108

20982109
/*

gc/default/default.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2773,7 +2773,7 @@ rb_gc_impl_define_finalizer(void *objspace_ptr, VALUE obj, VALUE block)
27732773

27742774
for (i = 0; i < len; i++) {
27752775
VALUE recv = RARRAY_AREF(table, i);
2776-
if (rb_equal(recv, block)) { // TODO: unsafe, can context switch
2776+
if (recv == block) {
27772777
RB_GC_VM_UNLOCK(lev);
27782778
return recv;
27792779
}

io.c

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8675,7 +8675,11 @@ deprecated_str_setter(VALUE val, ID id, VALUE *var)
86758675
{
86768676
rb_str_setter(val, id, &val);
86778677
if (!NIL_P(val)) {
8678-
rb_warn_deprecated("'%s'", NULL, rb_id2name(id));
8678+
RB_VM_UNLOCK();
8679+
{
8680+
rb_warn_deprecated("'%s'", NULL, rb_id2name(id));
8681+
}
8682+
RB_VM_LOCK();
86798683
}
86808684
*var = val;
86818685
}
@@ -8684,17 +8688,21 @@ static void
86848688
deprecated_rs_setter(VALUE val, ID id, VALUE *var)
86858689
{
86868690
if (!NIL_P(val)) {
8687-
if (!RB_TYPE_P(val, T_STRING)) {
8688-
rb_raise(rb_eTypeError, "value of %"PRIsVALUE" must be String", rb_id2str(id));
8689-
}
8690-
if (rb_str_equal(val, rb_default_rs)) {
8691-
val = rb_default_rs;
8692-
}
8693-
else {
8694-
val = rb_str_frozen_bare_string(val);
8691+
RB_VM_UNLOCK();
8692+
{
8693+
if (!RB_TYPE_P(val, T_STRING)) {
8694+
rb_raise(rb_eTypeError, "value of %"PRIsVALUE" must be String", rb_id2str(id));
8695+
}
8696+
if (rb_str_equal(val, rb_default_rs)) {
8697+
val = rb_default_rs;
8698+
}
8699+
else {
8700+
val = rb_str_frozen_bare_string(val);
8701+
}
8702+
rb_enc_str_coderange(val);
8703+
rb_warn_deprecated("'%s'", NULL, rb_id2name(id));
86958704
}
8696-
rb_enc_str_coderange(val);
8697-
rb_warn_deprecated("'%s'", NULL, rb_id2name(id));
8705+
RB_VM_LOCK();
86988706
}
86998707
*var = val;
87008708
}
@@ -9246,7 +9254,11 @@ stdin_getter(ID id, VALUE *ptr)
92469254
static void
92479255
stdout_setter(VALUE val, ID id, VALUE *ptr)
92489256
{
9249-
must_respond_to(id_write, val, id);
9257+
RB_VM_UNLOCK();
9258+
{
9259+
must_respond_to(id_write, val, id);
9260+
}
9261+
RB_VM_LOCK();
92509262
rb_ractor_stdout_set(val);
92519263
}
92529264

@@ -9259,7 +9271,11 @@ stdout_getter(ID id, VALUE *ptr)
92599271
static void
92609272
stderr_setter(VALUE val, ID id, VALUE *ptr)
92619273
{
9262-
must_respond_to(id_write, val, id);
9274+
RB_VM_UNLOCK();
9275+
{
9276+
must_respond_to(id_write, val, id);
9277+
}
9278+
RB_VM_LOCK();
92639279
rb_ractor_stderr_set(val);
92649280
}
92659281

ractor.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1374,10 +1374,15 @@ make_shareable_check_shareable(VALUE obj)
13741374
}
13751375
else if (!allow_frozen_shareable_p(obj)) {
13761376
if (rb_obj_is_proc(obj)) {
1377-
rb_proc_ractor_make_shareable(obj);
1377+
int lev = RB_VM_UNLOCK_ALL();
1378+
{
1379+
rb_proc_ractor_make_shareable(obj);
1380+
}
1381+
RB_VM_RELOCK_ALL(lev);
13781382
return traverse_cont;
13791383
}
13801384
else {
1385+
(void)RB_VM_UNLOCK_ALL();
13811386
rb_raise(rb_eRactorError, "can not make shareable object for %+"PRIsVALUE, obj);
13821387
}
13831388
}

string.c

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11452,15 +11452,19 @@ rb_str_setter(VALUE val, ID id, VALUE *var)
1145211452
static void
1145311453
rb_fs_setter(VALUE val, ID id, VALUE *var)
1145411454
{
11455-
val = rb_fs_check(val);
11456-
if (!val) {
11457-
rb_raise(rb_eTypeError,
11458-
"value of %"PRIsVALUE" must be String or Regexp",
11459-
rb_id2str(id));
11460-
}
11461-
if (!NIL_P(val)) {
11462-
rb_warn_deprecated("'$;'", NULL);
11455+
RB_VM_UNLOCK();
11456+
{
11457+
val = rb_fs_check(val);
11458+
if (!val) {
11459+
rb_raise(rb_eTypeError,
11460+
"value of %"PRIsVALUE" must be String or Regexp",
11461+
rb_id2str(id));
11462+
}
11463+
if (!NIL_P(val)) {
11464+
rb_warn_deprecated("'$;'", NULL);
11465+
}
1146311466
}
11467+
RB_VM_LOCK();
1146411468
*var = val;
1146511469
}
1146611470

transcode.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1856,13 +1856,9 @@ rb_econv_asciicompat_encoding(const char *ascii_incompat_name)
18561856
RB_VM_LOCK_ENTER_LEV(&lev);
18571857
}
18581858
else {
1859-
#if RUBY_DEBUG > 0
18601859
RB_VM_LOCK_LEAVE_LEV(&lev);
1861-
#endif
18621860
st_foreach(table2, asciicompat_encoding_i, (st_data_t)&data);
1863-
#if RUBY_DEBUG > 0
18641861
RB_VM_LOCK_ENTER_LEV(&lev);
1865-
#endif
18661862
}
18671863
}
18681864

variable.c

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -653,7 +653,11 @@ rb_global_entry(ID id)
653653
VALUE
654654
rb_gvar_undef_getter(ID id, VALUE *_)
655655
{
656-
rb_warning("global variable '%"PRIsVALUE"' not initialized", QUOTE_ID(id));
656+
RB_VM_UNLOCK();
657+
{
658+
rb_warning("global variable '%"PRIsVALUE"' not initialized", QUOTE_ID(id));
659+
}
660+
RB_VM_LOCK();
657661

658662
return Qnil;
659663
}
@@ -732,6 +736,7 @@ rb_gvar_var_marker(VALUE *var)
732736
void
733737
rb_gvar_readonly_setter(VALUE v, ID id, VALUE *_)
734738
{
739+
RB_VM_UNLOCK();
735740
rb_name_error(id, "%"PRIsVALUE" is a read-only variable", QUOTE_ID(id));
736741
}
737742

@@ -3857,7 +3862,6 @@ static void
38573862
const_added(VALUE klass, ID const_name)
38583863
{
38593864
if (GET_VM()->running) {
3860-
ASSERT_vm_unlocking();
38613865
VALUE name = ID2SYM(const_name);
38623866
rb_funcallv(klass, idConst_added, 1, &name);
38633867
}
@@ -3992,14 +3996,28 @@ const_tbl_update(struct autoload_const *ac, int autoload_force)
39923996
else {
39933997
VALUE name = QUOTE_ID(id);
39943998
visibility = ce->flag;
3995-
if (klass == rb_cObject)
3996-
rb_warn("already initialized constant %"PRIsVALUE"", name);
3997-
else
3998-
rb_warn("already initialized constant %"PRIsVALUE"::%"PRIsVALUE"",
3999-
rb_class_name(klass), name);
3999+
if (klass == rb_cObject) {
4000+
RB_VM_UNLOCK();
4001+
{
4002+
rb_warn("already initialized constant %"PRIsVALUE"", name);
4003+
}
4004+
RB_VM_LOCK();
4005+
}
4006+
else {
4007+
RB_VM_UNLOCK();
4008+
{
4009+
rb_warn("already initialized constant %"PRIsVALUE"::%"PRIsVALUE"",
4010+
rb_class_name(klass), name);
4011+
}
4012+
RB_VM_LOCK();
4013+
}
40004014
if (!NIL_P(ce->file) && ce->line) {
4001-
rb_compile_warn(RSTRING_PTR(ce->file), ce->line,
4002-
"previous definition of %"PRIsVALUE" was here", name);
4015+
RB_VM_UNLOCK();
4016+
{
4017+
rb_compile_warn(RSTRING_PTR(ce->file), ce->line,
4018+
"previous definition of %"PRIsVALUE" was here", name);
4019+
}
4020+
RB_VM_LOCK();
40034021
}
40044022
}
40054023
rb_clear_constant_cache_for_id(id);

vm.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1307,6 +1307,8 @@ collect_outer_variable_names(ID id, VALUE val, void *ptr)
13071307
static const rb_env_t *
13081308
env_copy(const VALUE *src_ep, VALUE read_only_variables)
13091309
{
1310+
ASSERT_vm_unlocking();
1311+
13101312
const rb_env_t *src_env = (rb_env_t *)VM_ENV_ENVVAL(src_ep);
13111313
VM_ASSERT(src_env->ep == src_ep);
13121314

@@ -1675,7 +1677,6 @@ invoke_block_from_c_bh(rb_execution_context_t *ec, VALUE block_handler,
16751677
int kw_splat, VALUE passed_block_handler, const rb_cref_t *cref,
16761678
int is_lambda, int force_blockarg)
16771679
{
1678-
ASSERT_vm_unlocking();
16791680
again:
16801681
switch (vm_block_handler_type(block_handler)) {
16811682
case block_handler_type_iseq:
@@ -1718,7 +1719,6 @@ check_block_handler(rb_execution_context_t *ec)
17181719
static VALUE
17191720
vm_yield_with_cref(rb_execution_context_t *ec, int argc, const VALUE *argv, int kw_splat, const rb_cref_t *cref, int is_lambda)
17201721
{
1721-
ASSERT_vm_unlocking();
17221722
return invoke_block_from_c_bh(ec, check_block_handler(ec),
17231723
argc, argv, kw_splat, VM_BLOCK_HANDLER_NONE,
17241724
cref, is_lambda, FALSE);

vm_eval.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,8 @@ vm_call0_body(rb_execution_context_t *ec, struct rb_calling_info *calling, const
199199
const struct rb_callcache *cc = calling->cc;
200200
VALUE ret;
201201

202+
ASSERT_vm_unlocking();
203+
202204
retry:
203205

204206
switch (vm_cc_cme(cc)->def->type) {

0 commit comments

Comments
 (0)