Skip to content

Commit dadb6bc

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

14 files changed

Lines changed: 167 additions & 48 deletions

File tree

depend

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14795,7 +14795,9 @@ ruby.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
1479514795
ruby.$(OBJEXT): {$(VPATH)}thread_native.h
1479614796
ruby.$(OBJEXT): {$(VPATH)}util.h
1479714797
ruby.$(OBJEXT): {$(VPATH)}vm_core.h
14798+
ruby.$(OBJEXT): {$(VPATH)}vm_debug.h
1479814799
ruby.$(OBJEXT): {$(VPATH)}vm_opts.h
14800+
ruby.$(OBJEXT): {$(VPATH)}vm_sync.h
1479914801
ruby.$(OBJEXT): {$(VPATH)}yjit.h
1480014802
ruby_parser.$(OBJEXT): $(hdrdir)/ruby/ruby.h
1480114803
ruby_parser.$(OBJEXT): $(top_srcdir)/internal/array.h

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: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2765,20 +2765,23 @@ rb_gc_impl_define_finalizer(void *objspace_ptr, VALUE obj, VALUE block)
27652765

27662766
if (st_lookup(finalizer_table, obj, &data)) {
27672767
table = (VALUE)data;
2768+
VALUE dup_table = rb_ary_dup(table);
27682769

2770+
RB_GC_VM_UNLOCK(lev);
27692771
/* avoid duplicate block, table is usually small */
27702772
{
27712773
long len = RARRAY_LEN(table);
27722774
long i;
27732775

27742776
for (i = 0; i < len; i++) {
2775-
VALUE recv = RARRAY_AREF(table, i);
2776-
if (rb_equal(recv, block)) { // TODO: unsafe, can context switch
2777-
RB_GC_VM_UNLOCK(lev);
2777+
VALUE recv = RARRAY_AREF(dup_table, i);
2778+
if (rb_equal(recv, block)) { // can't be called with VM lock held
27782779
return recv;
27792780
}
27802781
}
27812782
}
2783+
lev = RB_GC_VM_LOCK();
2784+
RB_GC_GUARD(dup_table);
27822785

27832786
rb_ary_push(table, block);
27842787
}

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
}

re.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4627,7 +4627,9 @@ static void
46274627
match_setter(VALUE val, ID _x, VALUE *_y)
46284628
{
46294629
if (!NIL_P(val)) {
4630+
RB_VM_UNLOCK();
46304631
Check_Type(val, T_MATCH);
4632+
RB_VM_LOCK();
46314633
}
46324634
rb_backref_set(val);
46334635
}

ruby.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242

4343
#include "dln.h"
4444
#include "eval_intern.h"
45+
#include "vm_sync.h"
4546
#include "internal.h"
4647
#include "internal/cmdlineopt.h"
4748
#include "internal/cont.h"
@@ -3019,10 +3020,13 @@ ruby_setproctitle(VALUE title)
30193020
static void
30203021
set_arg0(VALUE val, ID id, VALUE *_)
30213022
{
3022-
if (origarg.argv == 0)
3023+
RB_VM_UNLOCK();
3024+
if (origarg.argv == 0) {
30233025
rb_raise(rb_eRuntimeError, "$0 not initialized");
3026+
}
30243027

30253028
rb_progname = rb_str_new_frozen(ruby_setproctitle(val));
3029+
RB_VM_LOCK();
30263030
}
30273031

30283032
static inline VALUE

string.c

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11444,6 +11444,7 @@ void
1144411444
rb_str_setter(VALUE val, ID id, VALUE *var)
1144511445
{
1144611446
if (!NIL_P(val) && !RB_TYPE_P(val, T_STRING)) {
11447+
RB_VM_UNLOCK_ALL();
1144711448
rb_raise(rb_eTypeError, "value of %"PRIsVALUE" must be String", rb_id2str(id));
1144811449
}
1144911450
*var = val;
@@ -11452,15 +11453,19 @@ rb_str_setter(VALUE val, ID id, VALUE *var)
1145211453
static void
1145311454
rb_fs_setter(VALUE val, ID id, VALUE *var)
1145411455
{
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);
11456+
RB_VM_UNLOCK();
11457+
{
11458+
val = rb_fs_check(val);
11459+
if (!val) {
11460+
rb_raise(rb_eTypeError,
11461+
"value of %"PRIsVALUE" must be String or Regexp",
11462+
rb_id2str(id));
11463+
}
11464+
if (!NIL_P(val)) {
11465+
rb_warn_deprecated("'$;'", NULL);
11466+
}
1146311467
}
11468+
RB_VM_LOCK();
1146411469
*var = val;
1146511470
}
1146611471

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

0 commit comments

Comments
 (0)