From ed22e15acb83562825a6b4cd95a8ae15c0d3b6d2 Mon Sep 17 00:00:00 2001 From: BurdetteLamar Date: Wed, 23 Jul 2025 15:40:50 -0500 Subject: [PATCH 1/6] [DOC] Tweak for String#encode! --- transcode.c | 1 + 1 file changed, 1 insertion(+) diff --git a/transcode.c b/transcode.c index 8e36fa13eb88cd..d8cd90e56d5cf7 100644 --- a/transcode.c +++ b/transcode.c @@ -2889,6 +2889,7 @@ str_encode_associate(VALUE str, int encidx) * * Like #encode, but applies encoding changes to +self+; returns +self+. * + * Related: see {Modifying}[rdoc-ref:String@Modifying]. */ static VALUE From 7e2b6291b81320a5ad6458b9bbe66595e9b06d8b Mon Sep 17 00:00:00 2001 From: Alan Wu Date: Sat, 5 Jul 2025 00:54:44 +0900 Subject: [PATCH 2/6] ZJIT: DRY up underscore rexport anti-pattern Keeping the same name makes re-exporting more concise. --- zjit/src/backend/arm64/mod.rs | 12 ++++++------ zjit/src/backend/lir.rs | 15 ++++++--------- zjit/src/backend/x86_64/mod.rs | 12 ++++++------ 3 files changed, 18 insertions(+), 21 deletions(-) diff --git a/zjit/src/backend/arm64/mod.rs b/zjit/src/backend/arm64/mod.rs index dc5c7e6058f144..88ccad8e091ed1 100644 --- a/zjit/src/backend/arm64/mod.rs +++ b/zjit/src/backend/arm64/mod.rs @@ -11,12 +11,12 @@ use crate::cast::*; pub type Reg = A64Reg; // Callee-saved registers -pub const _CFP: Opnd = Opnd::Reg(X19_REG); -pub const _EC: Opnd = Opnd::Reg(X20_REG); -pub const _SP: Opnd = Opnd::Reg(X21_REG); +pub const CFP: Opnd = Opnd::Reg(X19_REG); +pub const EC: Opnd = Opnd::Reg(X20_REG); +pub const SP: Opnd = Opnd::Reg(X21_REG); // C argument registers on this platform -pub const _C_ARG_OPNDS: [Opnd; 6] = [ +pub const C_ARG_OPNDS: [Opnd; 6] = [ Opnd::Reg(X0_REG), Opnd::Reg(X1_REG), Opnd::Reg(X2_REG), @@ -27,8 +27,8 @@ pub const _C_ARG_OPNDS: [Opnd; 6] = [ // C return value register on this platform pub const C_RET_REG: Reg = X0_REG; -pub const _C_RET_OPND: Opnd = Opnd::Reg(X0_REG); -pub const _NATIVE_STACK_PTR: Opnd = Opnd::Reg(XZR_REG); +pub const C_RET_OPND: Opnd = Opnd::Reg(X0_REG); +pub const NATIVE_STACK_PTR: Opnd = Opnd::Reg(XZR_REG); // These constants define the way we work with Arm64's stack pointer. The stack // pointer always needs to be aligned to a 16-byte boundary. diff --git a/zjit/src/backend/lir.rs b/zjit/src/backend/lir.rs index 47ba5ddf704859..7bac210bee6689 100644 --- a/zjit/src/backend/lir.rs +++ b/zjit/src/backend/lir.rs @@ -6,18 +6,15 @@ use crate::cruby::{Qundef, RUBY_OFFSET_CFP_PC, RUBY_OFFSET_CFP_SP, SIZEOF_VALUE_ use crate::hir::SideExitReason; use crate::options::{debug, get_option}; use crate::cruby::VALUE; -use crate::backend::current::*; use crate::virtualmem::CodePtr; use crate::asm::{CodeBlock, Label}; -pub const EC: Opnd = _EC; -pub const CFP: Opnd = _CFP; -pub const SP: Opnd = _SP; - -pub const C_ARG_OPNDS: [Opnd; 6] = _C_ARG_OPNDS; -pub const C_RET_OPND: Opnd = _C_RET_OPND; -pub const NATIVE_STACK_PTR: Opnd = _NATIVE_STACK_PTR; -pub use crate::backend::current::{Reg, C_RET_REG}; +pub use crate::backend::current::{ + Reg, + EC, CFP, SP, + NATIVE_STACK_PTR, + C_ARG_OPNDS, C_RET_REG, C_RET_OPND, +}; // Memory operand base #[derive(Clone, Copy, PartialEq, Eq, Debug)] diff --git a/zjit/src/backend/x86_64/mod.rs b/zjit/src/backend/x86_64/mod.rs index 816f38db37f133..942705fb95bb75 100644 --- a/zjit/src/backend/x86_64/mod.rs +++ b/zjit/src/backend/x86_64/mod.rs @@ -11,12 +11,12 @@ use crate::cast::*; pub type Reg = X86Reg; // Callee-saved registers -pub const _CFP: Opnd = Opnd::Reg(R13_REG); -pub const _EC: Opnd = Opnd::Reg(R12_REG); -pub const _SP: Opnd = Opnd::Reg(RBX_REG); +pub const CFP: Opnd = Opnd::Reg(R13_REG); +pub const EC: Opnd = Opnd::Reg(R12_REG); +pub const SP: Opnd = Opnd::Reg(RBX_REG); // C argument registers on this platform -pub const _C_ARG_OPNDS: [Opnd; 6] = [ +pub const C_ARG_OPNDS: [Opnd; 6] = [ Opnd::Reg(RDI_REG), Opnd::Reg(RSI_REG), Opnd::Reg(RDX_REG), @@ -27,8 +27,8 @@ pub const _C_ARG_OPNDS: [Opnd; 6] = [ // C return value register on this platform pub const C_RET_REG: Reg = RAX_REG; -pub const _C_RET_OPND: Opnd = Opnd::Reg(RAX_REG); -pub const _NATIVE_STACK_PTR: Opnd = Opnd::Reg(RSP_REG); +pub const C_RET_OPND: Opnd = Opnd::Reg(RAX_REG); +pub const NATIVE_STACK_PTR: Opnd = Opnd::Reg(RSP_REG); impl CodeBlock { // The number of bytes that are generated by jmp_ptr From 271e52d55399ffaf41c59b7b477ff68d8a7e3e3b Mon Sep 17 00:00:00 2001 From: Alan Wu Date: Thu, 24 Jul 2025 15:48:40 -0400 Subject: [PATCH 3/6] ZJIT: Re-enable some A64 assembler tests Tweak for Condition to build when `cfg!(target = "x86_64")`. --- zjit/src/asm/arm64/arg/mod.rs | 1 - zjit/src/asm/arm64/mod.rs | 5 ++--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/zjit/src/asm/arm64/arg/mod.rs b/zjit/src/asm/arm64/arg/mod.rs index 9aff99a81778af..7eb37834f9aada 100644 --- a/zjit/src/asm/arm64/arg/mod.rs +++ b/zjit/src/asm/arm64/arg/mod.rs @@ -10,7 +10,6 @@ mod sys_reg; mod truncate; pub use bitmask_imm::BitmaskImmediate; -#[cfg(target_arch = "aarch64")] pub use condition::Condition; pub use inst_offset::InstructionOffset; pub use sf::Sf; diff --git a/zjit/src/asm/arm64/mod.rs b/zjit/src/asm/arm64/mod.rs index ef477821aa38a5..d1fa3b0d9f9c9b 100644 --- a/zjit/src/asm/arm64/mod.rs +++ b/zjit/src/asm/arm64/mod.rs @@ -217,6 +217,7 @@ pub const fn bcond_offset_fits_bits(offset: i64) -> bool { /// B.cond - branch to target if condition is true pub fn bcond(cb: &mut CodeBlock, cond: u8, offset: InstructionOffset) { + _ = Condition; assert!(bcond_offset_fits_bits(offset.into()), "The offset must be 19 bits or less."); let bytes: [u8; 4] = BranchCond::bcond(cond, offset).into(); @@ -1138,14 +1139,13 @@ fn cbz_cbnz(num_bits: u8, op: bool, offset: InstructionOffset, rt: u8) -> [u8; 4 rt as u32).to_le_bytes() } -/* #[cfg(test)] mod tests { use super::*; /// Check that the bytes for an instruction sequence match a hex string fn check_bytes(bytes: &str, run: R) where R: FnOnce(&mut super::CodeBlock) { - let mut cb = super::CodeBlock::new_dummy(128); + let mut cb = super::CodeBlock::new_dummy(); run(&mut cb); assert_eq!(format!("{:x}", cb), bytes); } @@ -1676,4 +1676,3 @@ mod tests { check_bytes("1f3c0072", |cb| tst(cb, W0, A64Opnd::new_uimm(0xffff))); } } -*/ From 7465e169dae537937c1ed244e22aaa565b13a3eb Mon Sep 17 00:00:00 2001 From: Stan Lo Date: Thu, 24 Jul 2025 22:38:18 +0100 Subject: [PATCH 4/6] ZJIT: Remove redundant test exclusions --- test/.excludes-zjit/OpenSSL/OSSL.rb | 1 - test/.excludes-zjit/OpenSSL/TestASN1.rb | 1 - test/.excludes-zjit/OpenSSL/TestBN.rb | 1 - test/.excludes-zjit/OpenSSL/TestBuffering.rb | 1 - test/.excludes-zjit/OpenSSL/TestCase.rb | 1 - test/.excludes-zjit/OpenSSL/TestCipher.rb | 1 - test/.excludes-zjit/OpenSSL/TestConfig.rb | 1 - test/.excludes-zjit/OpenSSL/TestDigest.rb | 1 - test/.excludes-zjit/OpenSSL/TestEC.rb | 1 - test/.excludes-zjit/OpenSSL/TestEOF1.rb | 1 - test/.excludes-zjit/OpenSSL/TestEOF1LowlevelSocket.rb | 1 - test/.excludes-zjit/OpenSSL/TestEOF2.rb | 1 - test/.excludes-zjit/OpenSSL/TestEOF2LowlevelSocket.rb | 1 - test/.excludes-zjit/OpenSSL/TestEngine.rb | 1 - test/.excludes-zjit/OpenSSL/TestFIPS.rb | 1 - test/.excludes-zjit/OpenSSL/TestHMAC.rb | 1 - test/.excludes-zjit/OpenSSL/TestKDF.rb | 1 - test/.excludes-zjit/OpenSSL/TestNSSPI.rb | 1 - test/.excludes-zjit/OpenSSL/TestOCSP.rb | 1 - test/.excludes-zjit/OpenSSL/TestPKCS12.rb | 1 - test/.excludes-zjit/OpenSSL/TestPKCS7.rb | 1 - test/.excludes-zjit/OpenSSL/TestPKey.rb | 1 - test/.excludes-zjit/OpenSSL/TestPKeyDH.rb | 1 - test/.excludes-zjit/OpenSSL/TestPKeyDSA.rb | 1 - test/.excludes-zjit/OpenSSL/TestPKeyRSA.rb | 1 - test/.excludes-zjit/OpenSSL/TestPair.rb | 1 - test/.excludes-zjit/OpenSSL/TestPairLowlevelSocket.rb | 1 - test/.excludes-zjit/OpenSSL/TestProvider.rb | 1 - test/.excludes-zjit/OpenSSL/TestRandom.rb | 1 - test/.excludes-zjit/OpenSSL/TestSSL.rb | 1 - test/.excludes-zjit/OpenSSL/TestSSLSession.rb | 1 - test/.excludes-zjit/OpenSSL/TestTimestamp.rb | 1 - test/.excludes-zjit/OpenSSL/TestX509Attribute.rb | 1 - test/.excludes-zjit/OpenSSL/TestX509CRL.rb | 1 - test/.excludes-zjit/OpenSSL/TestX509Certificate.rb | 1 - test/.excludes-zjit/OpenSSL/TestX509Extension.rb | 1 - test/.excludes-zjit/OpenSSL/TestX509Name.rb | 1 - test/.excludes-zjit/OpenSSL/TestX509Request.rb | 1 - test/.excludes-zjit/OpenSSL/TestX509Store.rb | 1 - test/.excludes-zjit/Prism/DumpTest.rb | 1 - test/.excludes-zjit/Prism/SnippetsTest.rb | 1 - test/.excludes-zjit/TestFixnum.rb | 1 + test/.excludes-zjit/TestRefinement.rb | 1 - 43 files changed, 1 insertion(+), 42 deletions(-) delete mode 100644 test/.excludes-zjit/OpenSSL/OSSL.rb delete mode 100644 test/.excludes-zjit/OpenSSL/TestASN1.rb delete mode 100644 test/.excludes-zjit/OpenSSL/TestBN.rb delete mode 100644 test/.excludes-zjit/OpenSSL/TestBuffering.rb delete mode 100644 test/.excludes-zjit/OpenSSL/TestCase.rb delete mode 100644 test/.excludes-zjit/OpenSSL/TestCipher.rb delete mode 100644 test/.excludes-zjit/OpenSSL/TestConfig.rb delete mode 100644 test/.excludes-zjit/OpenSSL/TestDigest.rb delete mode 100644 test/.excludes-zjit/OpenSSL/TestEC.rb delete mode 100644 test/.excludes-zjit/OpenSSL/TestEOF1.rb delete mode 100644 test/.excludes-zjit/OpenSSL/TestEOF1LowlevelSocket.rb delete mode 100644 test/.excludes-zjit/OpenSSL/TestEOF2.rb delete mode 100644 test/.excludes-zjit/OpenSSL/TestEOF2LowlevelSocket.rb delete mode 100644 test/.excludes-zjit/OpenSSL/TestEngine.rb delete mode 100644 test/.excludes-zjit/OpenSSL/TestFIPS.rb delete mode 100644 test/.excludes-zjit/OpenSSL/TestHMAC.rb delete mode 100644 test/.excludes-zjit/OpenSSL/TestKDF.rb delete mode 100644 test/.excludes-zjit/OpenSSL/TestNSSPI.rb delete mode 100644 test/.excludes-zjit/OpenSSL/TestOCSP.rb delete mode 100644 test/.excludes-zjit/OpenSSL/TestPKCS12.rb delete mode 100644 test/.excludes-zjit/OpenSSL/TestPKCS7.rb delete mode 100644 test/.excludes-zjit/OpenSSL/TestPKey.rb delete mode 100644 test/.excludes-zjit/OpenSSL/TestPKeyDH.rb delete mode 100644 test/.excludes-zjit/OpenSSL/TestPKeyDSA.rb delete mode 100644 test/.excludes-zjit/OpenSSL/TestPKeyRSA.rb delete mode 100644 test/.excludes-zjit/OpenSSL/TestPair.rb delete mode 100644 test/.excludes-zjit/OpenSSL/TestPairLowlevelSocket.rb delete mode 100644 test/.excludes-zjit/OpenSSL/TestProvider.rb delete mode 100644 test/.excludes-zjit/OpenSSL/TestRandom.rb delete mode 100644 test/.excludes-zjit/OpenSSL/TestSSL.rb delete mode 100644 test/.excludes-zjit/OpenSSL/TestSSLSession.rb delete mode 100644 test/.excludes-zjit/OpenSSL/TestTimestamp.rb delete mode 100644 test/.excludes-zjit/OpenSSL/TestX509Attribute.rb delete mode 100644 test/.excludes-zjit/OpenSSL/TestX509CRL.rb delete mode 100644 test/.excludes-zjit/OpenSSL/TestX509Certificate.rb delete mode 100644 test/.excludes-zjit/OpenSSL/TestX509Extension.rb delete mode 100644 test/.excludes-zjit/OpenSSL/TestX509Name.rb delete mode 100644 test/.excludes-zjit/OpenSSL/TestX509Request.rb delete mode 100644 test/.excludes-zjit/OpenSSL/TestX509Store.rb delete mode 100644 test/.excludes-zjit/Prism/DumpTest.rb delete mode 100644 test/.excludes-zjit/Prism/SnippetsTest.rb delete mode 100644 test/.excludes-zjit/TestRefinement.rb diff --git a/test/.excludes-zjit/OpenSSL/OSSL.rb b/test/.excludes-zjit/OpenSSL/OSSL.rb deleted file mode 100644 index 87f30945a278d9..00000000000000 --- a/test/.excludes-zjit/OpenSSL/OSSL.rb +++ /dev/null @@ -1 +0,0 @@ -exclude(/test_/, 'Tests fail with ZJIT') diff --git a/test/.excludes-zjit/OpenSSL/TestASN1.rb b/test/.excludes-zjit/OpenSSL/TestASN1.rb deleted file mode 100644 index 87f30945a278d9..00000000000000 --- a/test/.excludes-zjit/OpenSSL/TestASN1.rb +++ /dev/null @@ -1 +0,0 @@ -exclude(/test_/, 'Tests fail with ZJIT') diff --git a/test/.excludes-zjit/OpenSSL/TestBN.rb b/test/.excludes-zjit/OpenSSL/TestBN.rb deleted file mode 100644 index 87f30945a278d9..00000000000000 --- a/test/.excludes-zjit/OpenSSL/TestBN.rb +++ /dev/null @@ -1 +0,0 @@ -exclude(/test_/, 'Tests fail with ZJIT') diff --git a/test/.excludes-zjit/OpenSSL/TestBuffering.rb b/test/.excludes-zjit/OpenSSL/TestBuffering.rb deleted file mode 100644 index 87f30945a278d9..00000000000000 --- a/test/.excludes-zjit/OpenSSL/TestBuffering.rb +++ /dev/null @@ -1 +0,0 @@ -exclude(/test_/, 'Tests fail with ZJIT') diff --git a/test/.excludes-zjit/OpenSSL/TestCase.rb b/test/.excludes-zjit/OpenSSL/TestCase.rb deleted file mode 100644 index 87f30945a278d9..00000000000000 --- a/test/.excludes-zjit/OpenSSL/TestCase.rb +++ /dev/null @@ -1 +0,0 @@ -exclude(/test_/, 'Tests fail with ZJIT') diff --git a/test/.excludes-zjit/OpenSSL/TestCipher.rb b/test/.excludes-zjit/OpenSSL/TestCipher.rb deleted file mode 100644 index 87f30945a278d9..00000000000000 --- a/test/.excludes-zjit/OpenSSL/TestCipher.rb +++ /dev/null @@ -1 +0,0 @@ -exclude(/test_/, 'Tests fail with ZJIT') diff --git a/test/.excludes-zjit/OpenSSL/TestConfig.rb b/test/.excludes-zjit/OpenSSL/TestConfig.rb deleted file mode 100644 index 87f30945a278d9..00000000000000 --- a/test/.excludes-zjit/OpenSSL/TestConfig.rb +++ /dev/null @@ -1 +0,0 @@ -exclude(/test_/, 'Tests fail with ZJIT') diff --git a/test/.excludes-zjit/OpenSSL/TestDigest.rb b/test/.excludes-zjit/OpenSSL/TestDigest.rb deleted file mode 100644 index 87f30945a278d9..00000000000000 --- a/test/.excludes-zjit/OpenSSL/TestDigest.rb +++ /dev/null @@ -1 +0,0 @@ -exclude(/test_/, 'Tests fail with ZJIT') diff --git a/test/.excludes-zjit/OpenSSL/TestEC.rb b/test/.excludes-zjit/OpenSSL/TestEC.rb deleted file mode 100644 index 87f30945a278d9..00000000000000 --- a/test/.excludes-zjit/OpenSSL/TestEC.rb +++ /dev/null @@ -1 +0,0 @@ -exclude(/test_/, 'Tests fail with ZJIT') diff --git a/test/.excludes-zjit/OpenSSL/TestEOF1.rb b/test/.excludes-zjit/OpenSSL/TestEOF1.rb deleted file mode 100644 index 87f30945a278d9..00000000000000 --- a/test/.excludes-zjit/OpenSSL/TestEOF1.rb +++ /dev/null @@ -1 +0,0 @@ -exclude(/test_/, 'Tests fail with ZJIT') diff --git a/test/.excludes-zjit/OpenSSL/TestEOF1LowlevelSocket.rb b/test/.excludes-zjit/OpenSSL/TestEOF1LowlevelSocket.rb deleted file mode 100644 index 87f30945a278d9..00000000000000 --- a/test/.excludes-zjit/OpenSSL/TestEOF1LowlevelSocket.rb +++ /dev/null @@ -1 +0,0 @@ -exclude(/test_/, 'Tests fail with ZJIT') diff --git a/test/.excludes-zjit/OpenSSL/TestEOF2.rb b/test/.excludes-zjit/OpenSSL/TestEOF2.rb deleted file mode 100644 index 87f30945a278d9..00000000000000 --- a/test/.excludes-zjit/OpenSSL/TestEOF2.rb +++ /dev/null @@ -1 +0,0 @@ -exclude(/test_/, 'Tests fail with ZJIT') diff --git a/test/.excludes-zjit/OpenSSL/TestEOF2LowlevelSocket.rb b/test/.excludes-zjit/OpenSSL/TestEOF2LowlevelSocket.rb deleted file mode 100644 index 87f30945a278d9..00000000000000 --- a/test/.excludes-zjit/OpenSSL/TestEOF2LowlevelSocket.rb +++ /dev/null @@ -1 +0,0 @@ -exclude(/test_/, 'Tests fail with ZJIT') diff --git a/test/.excludes-zjit/OpenSSL/TestEngine.rb b/test/.excludes-zjit/OpenSSL/TestEngine.rb deleted file mode 100644 index 87f30945a278d9..00000000000000 --- a/test/.excludes-zjit/OpenSSL/TestEngine.rb +++ /dev/null @@ -1 +0,0 @@ -exclude(/test_/, 'Tests fail with ZJIT') diff --git a/test/.excludes-zjit/OpenSSL/TestFIPS.rb b/test/.excludes-zjit/OpenSSL/TestFIPS.rb deleted file mode 100644 index 87f30945a278d9..00000000000000 --- a/test/.excludes-zjit/OpenSSL/TestFIPS.rb +++ /dev/null @@ -1 +0,0 @@ -exclude(/test_/, 'Tests fail with ZJIT') diff --git a/test/.excludes-zjit/OpenSSL/TestHMAC.rb b/test/.excludes-zjit/OpenSSL/TestHMAC.rb deleted file mode 100644 index 87f30945a278d9..00000000000000 --- a/test/.excludes-zjit/OpenSSL/TestHMAC.rb +++ /dev/null @@ -1 +0,0 @@ -exclude(/test_/, 'Tests fail with ZJIT') diff --git a/test/.excludes-zjit/OpenSSL/TestKDF.rb b/test/.excludes-zjit/OpenSSL/TestKDF.rb deleted file mode 100644 index 87f30945a278d9..00000000000000 --- a/test/.excludes-zjit/OpenSSL/TestKDF.rb +++ /dev/null @@ -1 +0,0 @@ -exclude(/test_/, 'Tests fail with ZJIT') diff --git a/test/.excludes-zjit/OpenSSL/TestNSSPI.rb b/test/.excludes-zjit/OpenSSL/TestNSSPI.rb deleted file mode 100644 index 87f30945a278d9..00000000000000 --- a/test/.excludes-zjit/OpenSSL/TestNSSPI.rb +++ /dev/null @@ -1 +0,0 @@ -exclude(/test_/, 'Tests fail with ZJIT') diff --git a/test/.excludes-zjit/OpenSSL/TestOCSP.rb b/test/.excludes-zjit/OpenSSL/TestOCSP.rb deleted file mode 100644 index 87f30945a278d9..00000000000000 --- a/test/.excludes-zjit/OpenSSL/TestOCSP.rb +++ /dev/null @@ -1 +0,0 @@ -exclude(/test_/, 'Tests fail with ZJIT') diff --git a/test/.excludes-zjit/OpenSSL/TestPKCS12.rb b/test/.excludes-zjit/OpenSSL/TestPKCS12.rb deleted file mode 100644 index 87f30945a278d9..00000000000000 --- a/test/.excludes-zjit/OpenSSL/TestPKCS12.rb +++ /dev/null @@ -1 +0,0 @@ -exclude(/test_/, 'Tests fail with ZJIT') diff --git a/test/.excludes-zjit/OpenSSL/TestPKCS7.rb b/test/.excludes-zjit/OpenSSL/TestPKCS7.rb deleted file mode 100644 index 87f30945a278d9..00000000000000 --- a/test/.excludes-zjit/OpenSSL/TestPKCS7.rb +++ /dev/null @@ -1 +0,0 @@ -exclude(/test_/, 'Tests fail with ZJIT') diff --git a/test/.excludes-zjit/OpenSSL/TestPKey.rb b/test/.excludes-zjit/OpenSSL/TestPKey.rb deleted file mode 100644 index 87f30945a278d9..00000000000000 --- a/test/.excludes-zjit/OpenSSL/TestPKey.rb +++ /dev/null @@ -1 +0,0 @@ -exclude(/test_/, 'Tests fail with ZJIT') diff --git a/test/.excludes-zjit/OpenSSL/TestPKeyDH.rb b/test/.excludes-zjit/OpenSSL/TestPKeyDH.rb deleted file mode 100644 index 87f30945a278d9..00000000000000 --- a/test/.excludes-zjit/OpenSSL/TestPKeyDH.rb +++ /dev/null @@ -1 +0,0 @@ -exclude(/test_/, 'Tests fail with ZJIT') diff --git a/test/.excludes-zjit/OpenSSL/TestPKeyDSA.rb b/test/.excludes-zjit/OpenSSL/TestPKeyDSA.rb deleted file mode 100644 index 87f30945a278d9..00000000000000 --- a/test/.excludes-zjit/OpenSSL/TestPKeyDSA.rb +++ /dev/null @@ -1 +0,0 @@ -exclude(/test_/, 'Tests fail with ZJIT') diff --git a/test/.excludes-zjit/OpenSSL/TestPKeyRSA.rb b/test/.excludes-zjit/OpenSSL/TestPKeyRSA.rb deleted file mode 100644 index 87f30945a278d9..00000000000000 --- a/test/.excludes-zjit/OpenSSL/TestPKeyRSA.rb +++ /dev/null @@ -1 +0,0 @@ -exclude(/test_/, 'Tests fail with ZJIT') diff --git a/test/.excludes-zjit/OpenSSL/TestPair.rb b/test/.excludes-zjit/OpenSSL/TestPair.rb deleted file mode 100644 index 87f30945a278d9..00000000000000 --- a/test/.excludes-zjit/OpenSSL/TestPair.rb +++ /dev/null @@ -1 +0,0 @@ -exclude(/test_/, 'Tests fail with ZJIT') diff --git a/test/.excludes-zjit/OpenSSL/TestPairLowlevelSocket.rb b/test/.excludes-zjit/OpenSSL/TestPairLowlevelSocket.rb deleted file mode 100644 index 87f30945a278d9..00000000000000 --- a/test/.excludes-zjit/OpenSSL/TestPairLowlevelSocket.rb +++ /dev/null @@ -1 +0,0 @@ -exclude(/test_/, 'Tests fail with ZJIT') diff --git a/test/.excludes-zjit/OpenSSL/TestProvider.rb b/test/.excludes-zjit/OpenSSL/TestProvider.rb deleted file mode 100644 index 87f30945a278d9..00000000000000 --- a/test/.excludes-zjit/OpenSSL/TestProvider.rb +++ /dev/null @@ -1 +0,0 @@ -exclude(/test_/, 'Tests fail with ZJIT') diff --git a/test/.excludes-zjit/OpenSSL/TestRandom.rb b/test/.excludes-zjit/OpenSSL/TestRandom.rb deleted file mode 100644 index 87f30945a278d9..00000000000000 --- a/test/.excludes-zjit/OpenSSL/TestRandom.rb +++ /dev/null @@ -1 +0,0 @@ -exclude(/test_/, 'Tests fail with ZJIT') diff --git a/test/.excludes-zjit/OpenSSL/TestSSL.rb b/test/.excludes-zjit/OpenSSL/TestSSL.rb deleted file mode 100644 index 87f30945a278d9..00000000000000 --- a/test/.excludes-zjit/OpenSSL/TestSSL.rb +++ /dev/null @@ -1 +0,0 @@ -exclude(/test_/, 'Tests fail with ZJIT') diff --git a/test/.excludes-zjit/OpenSSL/TestSSLSession.rb b/test/.excludes-zjit/OpenSSL/TestSSLSession.rb deleted file mode 100644 index 87f30945a278d9..00000000000000 --- a/test/.excludes-zjit/OpenSSL/TestSSLSession.rb +++ /dev/null @@ -1 +0,0 @@ -exclude(/test_/, 'Tests fail with ZJIT') diff --git a/test/.excludes-zjit/OpenSSL/TestTimestamp.rb b/test/.excludes-zjit/OpenSSL/TestTimestamp.rb deleted file mode 100644 index 87f30945a278d9..00000000000000 --- a/test/.excludes-zjit/OpenSSL/TestTimestamp.rb +++ /dev/null @@ -1 +0,0 @@ -exclude(/test_/, 'Tests fail with ZJIT') diff --git a/test/.excludes-zjit/OpenSSL/TestX509Attribute.rb b/test/.excludes-zjit/OpenSSL/TestX509Attribute.rb deleted file mode 100644 index 87f30945a278d9..00000000000000 --- a/test/.excludes-zjit/OpenSSL/TestX509Attribute.rb +++ /dev/null @@ -1 +0,0 @@ -exclude(/test_/, 'Tests fail with ZJIT') diff --git a/test/.excludes-zjit/OpenSSL/TestX509CRL.rb b/test/.excludes-zjit/OpenSSL/TestX509CRL.rb deleted file mode 100644 index 87f30945a278d9..00000000000000 --- a/test/.excludes-zjit/OpenSSL/TestX509CRL.rb +++ /dev/null @@ -1 +0,0 @@ -exclude(/test_/, 'Tests fail with ZJIT') diff --git a/test/.excludes-zjit/OpenSSL/TestX509Certificate.rb b/test/.excludes-zjit/OpenSSL/TestX509Certificate.rb deleted file mode 100644 index 87f30945a278d9..00000000000000 --- a/test/.excludes-zjit/OpenSSL/TestX509Certificate.rb +++ /dev/null @@ -1 +0,0 @@ -exclude(/test_/, 'Tests fail with ZJIT') diff --git a/test/.excludes-zjit/OpenSSL/TestX509Extension.rb b/test/.excludes-zjit/OpenSSL/TestX509Extension.rb deleted file mode 100644 index 87f30945a278d9..00000000000000 --- a/test/.excludes-zjit/OpenSSL/TestX509Extension.rb +++ /dev/null @@ -1 +0,0 @@ -exclude(/test_/, 'Tests fail with ZJIT') diff --git a/test/.excludes-zjit/OpenSSL/TestX509Name.rb b/test/.excludes-zjit/OpenSSL/TestX509Name.rb deleted file mode 100644 index 87f30945a278d9..00000000000000 --- a/test/.excludes-zjit/OpenSSL/TestX509Name.rb +++ /dev/null @@ -1 +0,0 @@ -exclude(/test_/, 'Tests fail with ZJIT') diff --git a/test/.excludes-zjit/OpenSSL/TestX509Request.rb b/test/.excludes-zjit/OpenSSL/TestX509Request.rb deleted file mode 100644 index 87f30945a278d9..00000000000000 --- a/test/.excludes-zjit/OpenSSL/TestX509Request.rb +++ /dev/null @@ -1 +0,0 @@ -exclude(/test_/, 'Tests fail with ZJIT') diff --git a/test/.excludes-zjit/OpenSSL/TestX509Store.rb b/test/.excludes-zjit/OpenSSL/TestX509Store.rb deleted file mode 100644 index 87f30945a278d9..00000000000000 --- a/test/.excludes-zjit/OpenSSL/TestX509Store.rb +++ /dev/null @@ -1 +0,0 @@ -exclude(/test_/, 'Tests fail with ZJIT') diff --git a/test/.excludes-zjit/Prism/DumpTest.rb b/test/.excludes-zjit/Prism/DumpTest.rb deleted file mode 100644 index 232903bfea982f..00000000000000 --- a/test/.excludes-zjit/Prism/DumpTest.rb +++ /dev/null @@ -1 +0,0 @@ -exclude(/test_/, 'Tests crash with ZJIT') diff --git a/test/.excludes-zjit/Prism/SnippetsTest.rb b/test/.excludes-zjit/Prism/SnippetsTest.rb deleted file mode 100644 index 232903bfea982f..00000000000000 --- a/test/.excludes-zjit/Prism/SnippetsTest.rb +++ /dev/null @@ -1 +0,0 @@ -exclude(/test_/, 'Tests crash with ZJIT') diff --git a/test/.excludes-zjit/TestFixnum.rb b/test/.excludes-zjit/TestFixnum.rb index b2ca8c67f77f16..6aa0a1f95b5575 100644 --- a/test/.excludes-zjit/TestFixnum.rb +++ b/test/.excludes-zjit/TestFixnum.rb @@ -1 +1,2 @@ +# Issue: https://github.com/Shopify/ruby/issues/646 exclude(/test_/, 'Tests make ZJIT panic') diff --git a/test/.excludes-zjit/TestRefinement.rb b/test/.excludes-zjit/TestRefinement.rb deleted file mode 100644 index 39e504c9a26944..00000000000000 --- a/test/.excludes-zjit/TestRefinement.rb +++ /dev/null @@ -1 +0,0 @@ -exclude(:test_override_builtin_method_with_method_added, 'Test fails with ZJIT') From 3ad2019259015080ab7fdadaa6f4ae818229bcd1 Mon Sep 17 00:00:00 2001 From: John Hawthorn Date: Wed, 23 Jul 2025 14:24:59 -0700 Subject: [PATCH 5/6] Extract vm_locked_by_ractor_p This introduces a new method to encapsulate checking whether the current Ractor owns the vm->ractor.sync lock. This allows us to disable TSan on it since that operation should be safe, and still get validation of other uses. --- misc/tsan_suppressions.txt | 7 ------- vm_core.h | 11 ++++++++++- vm_sync.c | 2 +- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/misc/tsan_suppressions.txt b/misc/tsan_suppressions.txt index a34e040913d9dd..692c1be3886787 100644 --- a/misc/tsan_suppressions.txt +++ b/misc/tsan_suppressions.txt @@ -30,13 +30,6 @@ race:check_reserved_signal_ race_top:rb_check_deadlock -# lock_owner -race_top:thread_sched_setup_running_threads -race_top:vm_lock_enter -race_top:rb_ec_vm_lock_rec -race_top:vm_lock_enter -race_top:vm_locked - # vm->ractor.sched.grq_cnt++ race_top:ractor_sched_enq race_top:ractor_sched_deq diff --git a/vm_core.h b/vm_core.h index 8da7a0811992c0..569aebaba4a9bb 100644 --- a/vm_core.h +++ b/vm_core.h @@ -2065,12 +2065,21 @@ void rb_ec_vm_lock_rec_release(const rb_execution_context_t *ec, unsigned int recorded_lock_rec, unsigned int current_lock_rec); +/* This technically is a data race, as it's checked without the lock, however we + * check against a value only our own thread will write. */ +NO_SANITIZE("thread", static inline bool +vm_locked_by_ractor_p(rb_vm_t *vm, rb_ractor_t *cr)) +{ + VM_ASSERT(cr == GET_RACTOR()); + return vm->ractor.sync.lock_owner == cr; +} + static inline unsigned int rb_ec_vm_lock_rec(const rb_execution_context_t *ec) { rb_vm_t *vm = rb_ec_vm_ptr(ec); - if (vm->ractor.sync.lock_owner != rb_ec_ractor_ptr(ec)) { + if (!vm_locked_by_ractor_p(vm, rb_ec_ractor_ptr(ec))) { return 0; } else { diff --git a/vm_sync.c b/vm_sync.c index 772a3239db1386..ba311a00e97838 100644 --- a/vm_sync.c +++ b/vm_sync.c @@ -12,7 +12,7 @@ void rb_ractor_sched_barrier_end(rb_vm_t *vm, rb_ractor_t *cr); static bool vm_locked(rb_vm_t *vm) { - return vm->ractor.sync.lock_owner == GET_RACTOR(); + return vm_locked_by_ractor_p(vm, GET_RACTOR()); } #if RUBY_DEBUG > 0 From 7f25b8f5fb95e547353c3cbf426bb39ec9150fe2 Mon Sep 17 00:00:00 2001 From: John Hawthorn Date: Fri, 18 Jul 2025 16:06:17 -0700 Subject: [PATCH 6/6] Disable TSAN for rb_gc_mark_machine_context Previously this was listed as a suppression, but we actually want this permanently unsanitized. This should be faster and more reliable since TASN won't have to match against symbolicated backtraces. --- configure.ac | 1 + internal/sanitizers.h | 10 ++++++++++ misc/tsan_suppressions.txt | 4 ---- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index 07a6d823142853..8dc7fa4aef22e8 100644 --- a/configure.ac +++ b/configure.ac @@ -1372,6 +1372,7 @@ AC_CHECK_HEADERS(process.h) AC_CHECK_HEADERS(pwd.h) AC_CHECK_HEADERS(sanitizer/asan_interface.h) AC_CHECK_HEADERS(sanitizer/msan_interface.h) +AC_CHECK_HEADERS(sanitizer/tsan_interface.h) AC_CHECK_HEADERS(setjmpex.h) AC_CHECK_HEADERS(stdalign.h) AC_CHECK_HEADERS(stdio.h) diff --git a/internal/sanitizers.h b/internal/sanitizers.h index 8e6e87ddc8d749..feafb4e6169a33 100644 --- a/internal/sanitizers.h +++ b/internal/sanitizers.h @@ -29,6 +29,13 @@ # endif #endif +#ifdef HAVE_SANITIZER_TSAN_INTERFACE_H +# if __has_feature(thread_sanitizer) || defined(__SANITIZE_THREAD__) +# define RUBY_TSAN_ENABLED +# include +# endif +#endif + #include "ruby/internal/stdbool.h" /* for bool */ #include "ruby/ruby.h" /* for VALUE */ @@ -42,6 +49,9 @@ #elif defined(RUBY_MSAN_ENABLED) # define ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS(x) \ __attribute__((__no_sanitize__("memory"), __noinline__)) x +#elif defined(RUBY_TSAN_ENABLED) +# define ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS(x) \ + __attribute__((__no_sanitize__("thread"), __noinline__)) x #elif defined(NO_SANITIZE_ADDRESS) # define ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS(x) \ NO_SANITIZE_ADDRESS(NOINLINE(x)) diff --git a/misc/tsan_suppressions.txt b/misc/tsan_suppressions.txt index 692c1be3886787..5492500e7f90ec 100644 --- a/misc/tsan_suppressions.txt +++ b/misc/tsan_suppressions.txt @@ -104,10 +104,6 @@ race_top:encoded_iseq_trace_instrument race:rb_iseq_trace_set_all race:rb_tracepoint_enable -# We walk the machine stack looking for markable objects, a thread with the GVL -# released could by mutating the stack with non-Ruby-objects -race:rb_gc_mark_machine_context - # GC enable/disable flag modifications race with object allocation flag reads race_top:rb_gc_impl_gc_disable race_top:rb_gc_impl_gc_enable