From 0ba6379acadf00ee0c4c92cb60ae3724acb7e3c7 Mon Sep 17 00:00:00 2001 From: tomoya ishida Date: Sat, 11 Oct 2025 01:39:54 +0900 Subject: [PATCH 1/6] Update bundled bigdecimal version (#14809) * Update bigdecimal spec * Update bundled bigdecimal to 3.3.1 --- gems/bundled_gems | 2 +- .../library/bigdecimal/BigDecimal_spec.rb | 10 ++++++---- spec/ruby/library/bigdecimal/add_spec.rb | 8 -------- spec/ruby/library/bigdecimal/core_spec.rb | 7 +++++-- spec/ruby/library/bigdecimal/divmod_spec.rb | 19 +++++++++++++------ spec/ruby/library/bigdecimal/mult_spec.rb | 8 -------- .../ruby/library/bigdecimal/remainder_spec.rb | 8 +++++--- spec/ruby/library/bigdecimal/shared/modulo.rb | 14 ++++++++++---- spec/ruby/library/bigdecimal/shared/power.rb | 4 ++-- spec/ruby/library/bigdecimal/sub_spec.rb | 8 -------- 10 files changed, 42 insertions(+), 46 deletions(-) diff --git a/gems/bundled_gems b/gems/bundled_gems index d8fa9642ce1eb8..9f49934794f930 100644 --- a/gems/bundled_gems +++ b/gems/bundled_gems @@ -25,7 +25,7 @@ racc 1.8.1 https://github.com/ruby/racc mutex_m 0.3.0 https://github.com/ruby/mutex_m getoptlong 0.2.1 https://github.com/ruby/getoptlong base64 0.3.0 https://github.com/ruby/base64 -bigdecimal 3.2.2 https://github.com/ruby/bigdecimal +bigdecimal 3.3.1 https://github.com/ruby/bigdecimal observer 0.1.2 https://github.com/ruby/observer abbrev 0.1.2 https://github.com/ruby/abbrev resolv-replace 0.1.1 https://github.com/ruby/resolv-replace diff --git a/spec/ruby/library/bigdecimal/BigDecimal_spec.rb b/spec/ruby/library/bigdecimal/BigDecimal_spec.rb index 45f5ebffc702f6..01772bf9af7d8e 100644 --- a/spec/ruby/library/bigdecimal/BigDecimal_spec.rb +++ b/spec/ruby/library/bigdecimal/BigDecimal_spec.rb @@ -156,8 +156,10 @@ BigDecimal("-12345.6E-1").should == -reference end - it "raises ArgumentError when Float is used without precision" do - -> { BigDecimal(1.0) }.should raise_error(ArgumentError) + version_is BigDecimal::VERSION, "3.3.0" do + it "allows Float without precision" do + BigDecimal(1.2).should == BigDecimal("1.2") + end end it "returns appropriate BigDecimal zero for signed zero" do @@ -259,8 +261,8 @@ def to_s; "cheese"; end end it "produces the expected result" do - @c.should == BigDecimal("-0.666667e-9") - @c.to_s.should == "-0.666667e-9" + @c.round(15).should == BigDecimal("-0.666667e-9") + @c.round(15).to_s.should == "-0.666667e-9" end it "produces the correct class for other arithmetic operators" do diff --git a/spec/ruby/library/bigdecimal/add_spec.rb b/spec/ruby/library/bigdecimal/add_spec.rb index 542713011d6a93..9cdab7d910844d 100644 --- a/spec/ruby/library/bigdecimal/add_spec.rb +++ b/spec/ruby/library/bigdecimal/add_spec.rb @@ -73,14 +73,6 @@ # BigDecimal("0.88").add(0.0, 1).should == BigDecimal("0.9") # end - describe "with Object" do - it "tries to coerce the other operand to self" do - object = mock("Object") - object.should_receive(:coerce).with(@frac_3).and_return([@frac_3, @frac_4]) - @frac_3.add(object, 1).should == BigDecimal("0.1E16") - end - end - describe "with Rational" do it "produces a BigDecimal" do (@three + Rational(500, 2)).should == BigDecimal("0.253e3") diff --git a/spec/ruby/library/bigdecimal/core_spec.rb b/spec/ruby/library/bigdecimal/core_spec.rb index acee4dcf564ea6..5097d708656b73 100644 --- a/spec/ruby/library/bigdecimal/core_spec.rb +++ b/spec/ruby/library/bigdecimal/core_spec.rb @@ -20,9 +20,12 @@ describe "BigDecimal#log" do it "handles high-precision Rational arguments" do - result = BigDecimal('0.22314354220170971436137296411949880462556361100856391620766259404746040597133837784E0') + # log(BigDecimal(r, 50), 50) + result1 = BigDecimal('0.22314354220170971436137296411949880462556361100856e0') + # log(BigDecimal(r, 1000), 50) + result2 = BigDecimal('0.22314354220170971436137296411949880462556361100853e0') r = Rational(1_234_567_890, 987_654_321) - BigMath.log(r, 50).should == result + [result1, result2].should include(BigMath.log(r, 50).mult(1, 50)) end end diff --git a/spec/ruby/library/bigdecimal/divmod_spec.rb b/spec/ruby/library/bigdecimal/divmod_spec.rb index 294f01cba01484..c519783d145a00 100644 --- a/spec/ruby/library/bigdecimal/divmod_spec.rb +++ b/spec/ruby/library/bigdecimal/divmod_spec.rb @@ -154,12 +154,19 @@ class BigDecimal end end - it "returns an array of zero and the dividend if the divisor is Infinity" do - @regular_vals.each do |val| - array = val.divmod(@infinity) - array.length.should == 2 - array[0].should == @zero - array[1].should == val + version_is BigDecimal::VERSION, "3.3.0" do + it "returns an array of zero and the dividend or minus one and Infinity if the divisor is Infinity" do + @regular_vals.each do |val| + array = val.divmod(@infinity) + array.length.should == 2 + if val >= 0 + array[0].should == @zero + array[1].should == val + else + array[0].should == @one_minus + array[1].should == @infinity + end + end end end diff --git a/spec/ruby/library/bigdecimal/mult_spec.rb b/spec/ruby/library/bigdecimal/mult_spec.rb index b7f8044b0b2202..2353df9cb8e9a9 100644 --- a/spec/ruby/library/bigdecimal/mult_spec.rb +++ b/spec/ruby/library/bigdecimal/mult_spec.rb @@ -21,12 +21,4 @@ @e.mult(@one, 1).should be_close(@one, @tolerance) @e3_minus.mult(@one, 1).should be_close(0, @tolerance2) end - - describe "with Object" do - it "tries to coerce the other operand to self" do - object = mock("Object") - object.should_receive(:coerce).with(@e3_minus).and_return([@e3_minus, @e3_plus]) - @e3_minus.mult(object, 1).should == BigDecimal("9") - end - end end diff --git a/spec/ruby/library/bigdecimal/remainder_spec.rb b/spec/ruby/library/bigdecimal/remainder_spec.rb index bac5f37ba968c1..0eb06f7ef1d402 100644 --- a/spec/ruby/library/bigdecimal/remainder_spec.rb +++ b/spec/ruby/library/bigdecimal/remainder_spec.rb @@ -37,9 +37,11 @@ @neg_int.remainder(@pos_frac).should == @neg_int - @pos_frac * (@neg_int / @pos_frac).truncate end - it "returns NaN used with zero" do - @mixed.remainder(@zero).should.nan? - @zero.remainder(@zero).should.nan? + version_is BigDecimal::VERSION, "3.3.0" do + it "raises ZeroDivisionError used with zero" do + -> { @mixed.remainder(@zero) }.should raise_error(ZeroDivisionError) + -> { @zero.remainder(@zero) }.should raise_error(ZeroDivisionError) + end end it "returns zero if used on zero" do diff --git a/spec/ruby/library/bigdecimal/shared/modulo.rb b/spec/ruby/library/bigdecimal/shared/modulo.rb index aa5c5a640b2cc2..eeb030fd23c05c 100644 --- a/spec/ruby/library/bigdecimal/shared/modulo.rb +++ b/spec/ruby/library/bigdecimal/shared/modulo.rb @@ -101,10 +101,16 @@ @infinity_minus.send(@method, @infinity).should.nan? end - it "returns the dividend if the divisor is Infinity" do - @one.send(@method, @infinity).should == @one - @one.send(@method, @infinity_minus).should == @one - @frac_2.send(@method, @infinity_minus).should == @frac_2 + version_is BigDecimal::VERSION, "3.3.0" do + it "returns the dividend if the divisor is Infinity and signs are same" do + @one.send(@method, @infinity).should == @one + (-@frac_2).send(@method, @infinity_minus).should == -@frac_2 + end + + it "returns the divisor if the divisor is Infinity and signs are different" do + (-@one).send(@method, @infinity).should == @infinity + @frac_2.send(@method, @infinity_minus).should == @infinity_minus + end end it "raises TypeError if the argument cannot be coerced to BigDecimal" do diff --git a/spec/ruby/library/bigdecimal/shared/power.rb b/spec/ruby/library/bigdecimal/shared/power.rb index 568a08589b494f..6dafb638e27b22 100644 --- a/spec/ruby/library/bigdecimal/shared/power.rb +++ b/spec/ruby/library/bigdecimal/shared/power.rb @@ -10,8 +10,8 @@ e = BigDecimal("1.00000000000000000000123456789") one = BigDecimal("1") ten = BigDecimal("10") - # The tolerance is dependent upon the size of BASE_FIG - tolerance = BigDecimal("1E-70") + # Accuracy is at least ndigits(== 30) + DOUBLE_FIG(== 16) + tolerance = BigDecimal("1E-46") ten_powers = BigDecimal("1E10000") pi = BigDecimal("3.14159265358979") e3_minus.send(@method, 2).should == e3_minus_power_2 diff --git a/spec/ruby/library/bigdecimal/sub_spec.rb b/spec/ruby/library/bigdecimal/sub_spec.rb index bddfec2186d6a4..3b62a0c794b510 100644 --- a/spec/ruby/library/bigdecimal/sub_spec.rb +++ b/spec/ruby/library/bigdecimal/sub_spec.rb @@ -35,14 +35,6 @@ @frac_1.sub(@frac_1, 1000000).should == @zero end - describe "with Object" do - it "tries to coerce the other operand to self" do - object = mock("Object") - object.should_receive(:coerce).with(@frac_3).and_return([@frac_3, @frac_4]) - @frac_3.sub(object, 1).should == BigDecimal("-0.9E15") - end - end - describe "with Rational" do it "produces a BigDecimal" do (@three - Rational(500, 2)).should == BigDecimal('-0.247e3') From f8c90e45163ce65d20a37789a020b436624c450b Mon Sep 17 00:00:00 2001 From: git Date: Fri, 10 Oct 2025 16:41:29 +0000 Subject: [PATCH 2/6] [DOC] Update bundled gems list at 0ba6379acadf00ee0c4c92cb60ae37 --- NEWS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index 117aae5736bcb0..17cb9ba982d613 100644 --- a/NEWS.md +++ b/NEWS.md @@ -216,7 +216,7 @@ The following bundled gems are updated. * rbs 3.9.5 * debug 1.11.0 * base64 0.3.0 -* bigdecimal 3.2.2 +* bigdecimal 3.3.1 * drb 2.2.3 * syslog 0.3.0 * csv 3.3.5 From 17a5a5e2ef2b6253a68174a846972187dde6d547 Mon Sep 17 00:00:00 2001 From: John Hawthorn Date: Thu, 9 Oct 2025 18:23:46 -0700 Subject: [PATCH 3/6] Take a full VM barrier in gc_rest This isn't (yet?) safe to do because it concurrently modifies GC structures and dfree functions are not necessarily safe to do without stopping all Ractors. If it was safe to do this we should also do it for gc_enter_event_continue. I do think sweeping could be done concurrently with the mutator and in parallel, but that requires more work first. --- gc/default/default.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/gc/default/default.c b/gc/default/default.c index c23adae0627988..af386a9793ae1d 100644 --- a/gc/default/default.c +++ b/gc/default/default.c @@ -6633,8 +6633,6 @@ gc_enter(rb_objspace_t *objspace, enum gc_enter_event event, unsigned int *lock_ switch (event) { case gc_enter_event_rest: - if (!is_marking(objspace)) break; - // fall through case gc_enter_event_start: case gc_enter_event_continue: // stop other ractors From 50cd34c4e837466ce041adf114ea474e6627bb91 Mon Sep 17 00:00:00 2001 From: Aiden Fox Ivey Date: Fri, 10 Oct 2025 13:22:15 -0400 Subject: [PATCH 4/6] ZJIT: Add Insn:: ArrayArefFixnum to accelerate Array#[] (#14717) * ZJIT: Add Insn:: ArrayArefFixnum to accelerate Array#[] * ZJIT: Use result from GuardType in ArrayArefFixnum * ZJIT: Unbox index for aref_fixnum * ZJIT: Change condition and add ArrayArefFixnum test * ZJIT: Fix ArrayArefFixnum display for InsnPrinter * ZJIT: Change insta test --- test/ruby/test_zjit.rb | 8 ++++++ zjit/bindgen/src/main.rs | 1 + zjit/src/codegen.rs | 11 ++++++++ zjit/src/cruby_bindings.inc.rs | 1 + zjit/src/hir.rs | 51 ++++++++++++++++++++++++++++++++++ 5 files changed, 72 insertions(+) diff --git a/test/ruby/test_zjit.rb b/test/ruby/test_zjit.rb index c6dbc01dc2e129..faf717096a4c77 100644 --- a/test/ruby/test_zjit.rb +++ b/test/ruby/test_zjit.rb @@ -1153,6 +1153,14 @@ def test = [1,2,3] } end + def test_array_fixnum_aref + assert_compiles '3', %q{ + def test(x) = [1,2,3][x] + test(2) + test(2) + }, call_threshold: 2, insns: [:opt_aref] + end + def test_new_range_inclusive assert_compiles '1..5', %q{ def test(a, b) = a..b diff --git a/zjit/bindgen/src/main.rs b/zjit/bindgen/src/main.rs index 64b235b838baff..b40986c0f6e154 100644 --- a/zjit/bindgen/src/main.rs +++ b/zjit/bindgen/src/main.rs @@ -125,6 +125,7 @@ fn main() { .allowlist_function("rb_ary_unshift_m") .allowlist_function("rb_ec_ary_new_from_values") .allowlist_function("rb_ary_tmp_new_from_values") + .allowlist_function("rb_ary_entry") .allowlist_function("rb_class_attached_object") .allowlist_function("rb_singleton_class") .allowlist_function("rb_define_class") diff --git a/zjit/src/codegen.rs b/zjit/src/codegen.rs index 4b9331e05b0892..35791bc0d7ae2f 100644 --- a/zjit/src/codegen.rs +++ b/zjit/src/codegen.rs @@ -355,6 +355,7 @@ fn gen_insn(cb: &mut CodeBlock, jit: &mut JITState, asm: &mut Assembler, functio Insn::NewRange { low, high, flag, state } => gen_new_range(jit, asm, opnd!(low), opnd!(high), *flag, &function.frame_state(*state)), Insn::NewRangeFixnum { low, high, flag, state } => gen_new_range_fixnum(asm, opnd!(low), opnd!(high), *flag, &function.frame_state(*state)), Insn::ArrayDup { val, state } => gen_array_dup(asm, opnd!(val), &function.frame_state(*state)), + Insn::ArrayArefFixnum { array, index, .. } => gen_aref_fixnum(asm, opnd!(array), opnd!(index)), Insn::ObjectAlloc { val, state } => gen_object_alloc(jit, asm, opnd!(val), &function.frame_state(*state)), &Insn::ObjectAllocClass { class, state } => gen_object_alloc_class(asm, class, &function.frame_state(state)), Insn::StringCopy { val, chilled, state } => gen_string_copy(asm, opnd!(val), *chilled, &function.frame_state(*state)), @@ -1241,6 +1242,16 @@ fn gen_new_array( new_array } +/// Compile array access (array[index]) +fn gen_aref_fixnum( + asm: &mut Assembler, + array: Opnd, + index: Opnd, +) -> lir::Opnd { + let unboxed_idx = asm.rshift(index, Opnd::UImm(1)); + asm_ccall!(asm, rb_ary_entry, array, unboxed_idx) +} + /// Compile a new hash instruction fn gen_new_hash( jit: &mut JITState, diff --git a/zjit/src/cruby_bindings.inc.rs b/zjit/src/cruby_bindings.inc.rs index ab442841ff267a..ea1bf68acc4173 100644 --- a/zjit/src/cruby_bindings.inc.rs +++ b/zjit/src/cruby_bindings.inc.rs @@ -786,6 +786,7 @@ unsafe extern "C" { pub fn rb_ary_resurrect(ary: VALUE) -> VALUE; pub fn rb_ary_cat(ary: VALUE, train: *const VALUE, len: ::std::os::raw::c_long) -> VALUE; pub fn rb_ary_push(ary: VALUE, elem: VALUE) -> VALUE; + pub fn rb_ary_entry(ary: VALUE, off: ::std::os::raw::c_long) -> VALUE; pub fn rb_ary_clear(ary: VALUE) -> VALUE; pub fn rb_ary_concat(lhs: VALUE, rhs: VALUE) -> VALUE; pub fn rb_hash_new() -> VALUE; diff --git a/zjit/src/hir.rs b/zjit/src/hir.rs index 2fe8eb79700349..1ab603283230e5 100644 --- a/zjit/src/hir.rs +++ b/zjit/src/hir.rs @@ -577,6 +577,7 @@ pub enum Insn { ArrayExtend { left: InsnId, right: InsnId, state: InsnId }, /// Push `val` onto `array`, where `array` is already `Array`. ArrayPush { array: InsnId, val: InsnId, state: InsnId }, + ArrayArefFixnum { array: InsnId, index: InsnId }, HashDup { val: InsnId, state: InsnId }, @@ -888,6 +889,10 @@ impl<'a> std::fmt::Display for InsnPrinter<'a> { } Ok(()) } + Insn::ArrayArefFixnum { array, index, .. } => { + write!(f, "ArrayArefFixnum {array}, {index}")?; + Ok(()) + } Insn::NewHash { elements, .. } => { write!(f, "NewHash")?; let mut prefix = " "; @@ -1579,6 +1584,7 @@ impl Function { &NewHash { ref elements, state } => NewHash { elements: find_vec!(elements), state: find!(state) }, &NewRange { low, high, flag, state } => NewRange { low: find!(low), high: find!(high), flag, state: find!(state) }, &NewRangeFixnum { low, high, flag, state } => NewRangeFixnum { low: find!(low), high: find!(high), flag, state: find!(state) }, + &ArrayArefFixnum { array, index } => ArrayArefFixnum { array: find!(array), index: find!(index) }, &ArrayMax { ref elements, state } => ArrayMax { elements: find_vec!(elements), state: find!(state) }, &SetGlobal { id, val, state } => SetGlobal { id, val: find!(val), state }, &GetIvar { self_val, id, state } => GetIvar { self_val: find!(self_val), id, state }, @@ -1664,6 +1670,7 @@ impl Function { Insn::ToRegexp { .. } => types::RegexpExact, Insn::NewArray { .. } => types::ArrayExact, Insn::ArrayDup { .. } => types::ArrayExact, + Insn::ArrayArefFixnum { .. } => types::BasicObject, Insn::NewHash { .. } => types::HashExact, Insn::HashDup { .. } => types::HashExact, Insn::NewRange { .. } => types::RangeExact, @@ -1969,6 +1976,16 @@ impl Function { } } } + if self.type_of(idx_val).is_subtype(types::Fixnum) { + self.push_insn(block, Insn::PatchPoint { invariant: Invariant::BOPRedefined { klass: ARRAY_REDEFINED_OP_FLAG, bop: BOP_AREF }, state }); + let fixnum_idx = self.push_insn(block, Insn::GuardType { val: idx_val, guard_type: types::Fixnum, state }); + let result = self.push_insn(block, Insn::ArrayArefFixnum { + array: self_val, + index: fixnum_idx, + }); + self.make_equal_to(orig_insn_id, result); + return; + } } self.push_insn_id(block, orig_insn_id); } @@ -2687,6 +2704,10 @@ impl Function { worklist.push_back(val); worklist.push_back(state); } + &Insn::ArrayArefFixnum { array, index } => { + worklist.push_back(array); + worklist.push_back(index); + } &Insn::Send { recv, ref args, state, .. } | &Insn::SendForward { recv, ref args, state, .. } | &Insn::SendWithoutBlock { recv, ref args, state, .. } @@ -12564,4 +12585,34 @@ mod opt_tests { Return v23 "); } + + #[test] + fn test_array_aref_fixnum() { + eval(" + def test + arr = [1, 2, 3] + arr[0] + end + "); + assert_snapshot!(hir_string("test"), @r" + fn test@:3: + bb0(): + EntryPoint interpreter + v1:BasicObject = LoadSelf + v2:NilClass = Const Value(nil) + Jump bb2(v1, v2) + bb1(v5:BasicObject): + EntryPoint JIT(0) + v6:NilClass = Const Value(nil) + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:NilClass): + v13:ArrayExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) + v15:ArrayExact = ArrayDup v13 + v18:Fixnum[0] = Const Value(0) + PatchPoint BOPRedefined(ARRAY_REDEFINED_OP_FLAG, BOP_AREF) + v30:BasicObject = ArrayArefFixnum v15, v18 + CheckInterrupts + Return v30 + "); + } } From 2de13f4d094a92099de92b91cde8d5a7da8c38cc Mon Sep 17 00:00:00 2001 From: Takashi Kokubun Date: Fri, 10 Oct 2025 10:24:14 -0700 Subject: [PATCH 5/6] ZJIT: Remove an unneeded ? https://github.com/ruby/ruby/pull/14717 --- zjit/src/hir.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/zjit/src/hir.rs b/zjit/src/hir.rs index 1ab603283230e5..8837457afaadee 100644 --- a/zjit/src/hir.rs +++ b/zjit/src/hir.rs @@ -890,8 +890,7 @@ impl<'a> std::fmt::Display for InsnPrinter<'a> { Ok(()) } Insn::ArrayArefFixnum { array, index, .. } => { - write!(f, "ArrayArefFixnum {array}, {index}")?; - Ok(()) + write!(f, "ArrayArefFixnum {array}, {index}") } Insn::NewHash { elements, .. } => { write!(f, "NewHash")?; From 0a6cd03b3d91f52c47242d2b45f5ac086a3c1fd8 Mon Sep 17 00:00:00 2001 From: John Hawthorn Date: Thu, 9 Oct 2025 17:09:19 -0700 Subject: [PATCH 6/6] Add ASSERT_vm_locking_with_barrier Previously we just had a comment stating that the code required a barrier. Turns out it's not too difficult to properly assert that. Co-authored-by: Luke Gruber --- concurrent_set.c | 6 ++---- string.c | 3 +-- vm_sync.c | 14 ++++++++++++++ vm_sync.h | 3 +++ 4 files changed, 20 insertions(+), 6 deletions(-) diff --git a/concurrent_set.c b/concurrent_set.c index 19b4b6c373559f..87279384eb8893 100644 --- a/concurrent_set.c +++ b/concurrent_set.c @@ -352,8 +352,7 @@ rb_concurrent_set_find_or_insert(VALUE *set_obj_ptr, VALUE key, void *data) VALUE rb_concurrent_set_delete_by_identity(VALUE set_obj, VALUE key) { - // Assume locking and barrier (which there is no assert for). - ASSERT_vm_locking(); + ASSERT_vm_locking_with_barrier(); struct concurrent_set *set = RTYPEDDATA_GET_DATA(set_obj); @@ -391,8 +390,7 @@ rb_concurrent_set_delete_by_identity(VALUE set_obj, VALUE key) void rb_concurrent_set_foreach_with_replace(VALUE set_obj, int (*callback)(VALUE *key, void *data), void *data) { - // Assume locking and barrier (which there is no assert for). - ASSERT_vm_locking(); + ASSERT_vm_locking_with_barrier(); struct concurrent_set *set = RTYPEDDATA_GET_DATA(set_obj); diff --git a/string.c b/string.c index 331f48313600f4..0ee0ab744856d7 100644 --- a/string.c +++ b/string.c @@ -600,8 +600,7 @@ rb_obj_is_fstring_table(VALUE obj) void rb_gc_free_fstring(VALUE obj) { - // Assume locking and barrier (which there is no assert for) - ASSERT_vm_locking(); + ASSERT_vm_locking_with_barrier(); rb_concurrent_set_delete_by_identity(fstring_table_obj, obj); diff --git a/vm_sync.c b/vm_sync.c index ba311a00e97838..6d93720701bad9 100644 --- a/vm_sync.c +++ b/vm_sync.c @@ -25,6 +25,20 @@ RUBY_ASSERT_vm_locking(void) } } +void +RUBY_ASSERT_vm_locking_with_barrier(void) +{ + if (rb_multi_ractor_p()) { + rb_vm_t *vm = GET_VM(); + VM_ASSERT(vm_locked(vm)); + + if (vm->ractor.cnt > 1) { + /* Written to only when holding both ractor.sync and ractor.sched lock */ + VM_ASSERT(vm->ractor.sched.barrier_waiting); + } + } +} + void RUBY_ASSERT_vm_unlocking(void) { diff --git a/vm_sync.h b/vm_sync.h index 457be2c6b888aa..15dfff4d0b9fe1 100644 --- a/vm_sync.h +++ b/vm_sync.h @@ -142,11 +142,14 @@ rb_vm_lock_leave_cr(struct rb_ractor_struct *cr, unsigned int *levp, const char #if RUBY_DEBUG > 0 void RUBY_ASSERT_vm_locking(void); +void RUBY_ASSERT_vm_locking_with_barrier(void); void RUBY_ASSERT_vm_unlocking(void); #define ASSERT_vm_locking() RUBY_ASSERT_vm_locking() +#define ASSERT_vm_locking_with_barrier() RUBY_ASSERT_vm_locking_with_barrier() #define ASSERT_vm_unlocking() RUBY_ASSERT_vm_unlocking() #else #define ASSERT_vm_locking() +#define ASSERT_vm_locking_with_barrier() #define ASSERT_vm_unlocking() #endif