From 7cafc61e7df044644f47937694c46835c316e86b Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Mon, 8 Sep 2025 18:09:06 +0900 Subject: [PATCH 1/4] Debug for sporadical failures on RubyCI --- test/rubygems/test_gem_command_manager.rb | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/test/rubygems/test_gem_command_manager.rb b/test/rubygems/test_gem_command_manager.rb index eeda4d94cff1c5..fbf35b8eb9d8c8 100644 --- a/test/rubygems/test_gem_command_manager.rb +++ b/test/rubygems/test_gem_command_manager.rb @@ -89,7 +89,13 @@ def test_find_command_unknown_suggestions actual_message = e.message end - assert_equal message, actual_message + assert_equal message, actual_message, proc {|msg| + msg + { + unknown_command: e.unknown_command, + spell_checker: e.spell_checker, + corrections: e.corrections, + }.pretty_inspect + } end def test_run_interrupt From e5a6e952467eef5444eaf63b77d8c91aa367d4de Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Mon, 8 Sep 2025 19:23:04 +0900 Subject: [PATCH 2/4] Debug: More inspections --- test/rubygems/test_gem_command_manager.rb | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/test/rubygems/test_gem_command_manager.rb b/test/rubygems/test_gem_command_manager.rb index fbf35b8eb9d8c8..bcad4000abbd52 100644 --- a/test/rubygems/test_gem_command_manager.rb +++ b/test/rubygems/test_gem_command_manager.rb @@ -80,6 +80,9 @@ def test_find_command_unknown_suggestions message = "Unknown command pish".dup if defined?(DidYouMean) + assert_operator Gem::UnknownCommandError, :<, DidYouMean::Correctable + assert_operator Gem::UnknownCommandError, :instance_variable_defined?, :@attached + assert_send [Gem::UnknownCommandError, :instance_variable_get, :@attached] message << "\nDid you mean? \"push\"" end @@ -90,10 +93,10 @@ def test_find_command_unknown_suggestions end assert_equal message, actual_message, proc {|msg| - msg + { - unknown_command: e.unknown_command, - spell_checker: e.spell_checker, - corrections: e.corrections, + (msg || "") + { + unknown_command: e.unknown_command, + spell_checker: (e.spell_checker rescue nil), + corrections: (e.corrections rescue nil), }.pretty_inspect } end From 03c86b053197f3cd6bece1925e634c1d74d196d0 Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Mon, 8 Sep 2025 10:30:09 +0200 Subject: [PATCH 3/4] Move `IS_TYPED_DATA` in RBasic.flags Ref: https://github.com/ruby/ruby/pull/14134#issuecomment-3207733725 We can't safely use low-bit pointer tagging anymore because `RTypedData.type` lines up with `RData.dfree` and there is no aligment guarantee on function pointers, as evidenced by `memcached` and `gpgme` gems. We also can't use FL_USER* for this, because extensions may use these for other purposes. Using a general flag for this is a bit unfortunate, as general flags are hard to come by, however I recently freed several of them, and we still have two or three free ones left. --- gc.c | 2 +- include/ruby/internal/core/rtypeddata.h | 12 +++++------- include/ruby/internal/fl_type.h | 4 ++-- yjit/src/cruby_bindings.inc.rs | 2 +- zjit/src/cruby_bindings.inc.rs | 2 +- 5 files changed, 10 insertions(+), 12 deletions(-) diff --git a/gc.c b/gc.c index 72328678c5fc1d..e8709dcf281a64 100644 --- a/gc.c +++ b/gc.c @@ -1062,7 +1062,7 @@ typed_data_alloc(VALUE klass, VALUE typed_flag, void *datap, const rb_data_type_ RBIMPL_NONNULL_ARG(type); if (klass) rb_data_object_check(klass); bool wb_protected = (type->flags & RUBY_FL_WB_PROTECTED) || !type->function.dmark; - return newobj_of(GET_RACTOR(), klass, T_DATA, 0, ((VALUE)type) | IS_TYPED_DATA | typed_flag, (VALUE)datap, wb_protected, size); + return newobj_of(GET_RACTOR(), klass, T_DATA | RUBY_TYPED_FL_IS_TYPED_DATA, 0, ((VALUE)type) | typed_flag, (VALUE)datap, wb_protected, size); } VALUE diff --git a/include/ruby/internal/core/rtypeddata.h b/include/ruby/internal/core/rtypeddata.h index 4d9fd4a6acbde8..8e16c31d998080 100644 --- a/include/ruby/internal/core/rtypeddata.h +++ b/include/ruby/internal/core/rtypeddata.h @@ -115,10 +115,8 @@ #define RUBY_TYPED_PROMOTED1 RUBY_TYPED_PROMOTED1 /** @endcond */ -#define IS_TYPED_DATA ((VALUE)1) -#define TYPED_DATA_EMBEDDED ((VALUE)2) -#define TYPED_DATA_PTR_FLAGS ((VALUE)3) -#define TYPED_DATA_PTR_MASK (~TYPED_DATA_PTR_FLAGS) +#define TYPED_DATA_EMBEDDED ((VALUE)1) +#define TYPED_DATA_PTR_MASK (~(TYPED_DATA_EMBEDDED)) /** * @private @@ -181,9 +179,9 @@ rbimpl_typeddata_flags { RUBY_TYPED_WB_PROTECTED = RUBY_FL_WB_PROTECTED, /* THIS FLAG DEPENDS ON Ruby version */ /** - * This flag no longer in use + * This flag is used to distinguish RTypedData from deprecated RData objects. */ - RUBY_TYPED_UNUSED = RUBY_FL_UNUSED6, + RUBY_TYPED_FL_IS_TYPED_DATA = RUBY_FL_USERPRIV0, /** * This flag determines whether marking and compaction should be carried out @@ -569,7 +567,7 @@ RBIMPL_ATTR_ARTIFICIAL() static inline bool rbimpl_rtypeddata_p(VALUE obj) { - return RTYPEDDATA(obj)->type & IS_TYPED_DATA; + return FL_TEST_RAW(obj, RUBY_TYPED_FL_IS_TYPED_DATA); } RBIMPL_ATTR_PURE_UNLESS_DEBUG() diff --git a/include/ruby/internal/fl_type.h b/include/ruby/internal/fl_type.h index 9e1f3dd15cf84b..da8670a8086abf 100644 --- a/include/ruby/internal/fl_type.h +++ b/include/ruby/internal/fl_type.h @@ -217,11 +217,11 @@ ruby_fl_type { RUBY_FL_PROMOTED = (1<<5), /** - * This flag is no longer in use + * This flag meaning is type dependent, currently only used by T_DATA. * * @internal */ - RUBY_FL_UNUSED6 = (1<<6), + RUBY_FL_USERPRIV0 = (1<<6), /** * This flag has something to do with finalisers. A ruby object can have diff --git a/yjit/src/cruby_bindings.inc.rs b/yjit/src/cruby_bindings.inc.rs index 429330168b0f29..4d1ce5df5eb746 100644 --- a/yjit/src/cruby_bindings.inc.rs +++ b/yjit/src/cruby_bindings.inc.rs @@ -222,7 +222,7 @@ pub const RUBY_FL_USHIFT: ruby_fl_ushift = 12; pub type ruby_fl_ushift = u32; pub const RUBY_FL_WB_PROTECTED: ruby_fl_type = 32; pub const RUBY_FL_PROMOTED: ruby_fl_type = 32; -pub const RUBY_FL_UNUSED6: ruby_fl_type = 64; +pub const RUBY_FL_USERPRIV0: ruby_fl_type = 64; pub const RUBY_FL_FINALIZE: ruby_fl_type = 128; pub const RUBY_FL_TAINT: ruby_fl_type = 0; pub const RUBY_FL_EXIVAR: ruby_fl_type = 0; diff --git a/zjit/src/cruby_bindings.inc.rs b/zjit/src/cruby_bindings.inc.rs index 0ff09a3c094b0e..0523c00ede24a7 100644 --- a/zjit/src/cruby_bindings.inc.rs +++ b/zjit/src/cruby_bindings.inc.rs @@ -103,7 +103,7 @@ pub const RUBY_FL_USHIFT: ruby_fl_ushift = 12; pub type ruby_fl_ushift = u32; pub const RUBY_FL_WB_PROTECTED: ruby_fl_type = 32; pub const RUBY_FL_PROMOTED: ruby_fl_type = 32; -pub const RUBY_FL_UNUSED6: ruby_fl_type = 64; +pub const RUBY_FL_USERPRIV0: ruby_fl_type = 64; pub const RUBY_FL_FINALIZE: ruby_fl_type = 128; pub const RUBY_FL_TAINT: ruby_fl_type = 0; pub const RUBY_FL_EXIVAR: ruby_fl_type = 0; From 7c5ddb793b71d05d3fba954bbe397ab03c6f76dc Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Mon, 8 Sep 2025 21:02:14 +0900 Subject: [PATCH 4/4] Remove debug code * Revert "Debug: More inspections" e5a6e952467eef5444eaf63b77d8c91aa367d4de. * Revert "Debug for sporadical failures on RubyCI" 7cafc61e7df044644f47937694c46835c316e86b. --- test/rubygems/test_gem_command_manager.rb | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/test/rubygems/test_gem_command_manager.rb b/test/rubygems/test_gem_command_manager.rb index bcad4000abbd52..eeda4d94cff1c5 100644 --- a/test/rubygems/test_gem_command_manager.rb +++ b/test/rubygems/test_gem_command_manager.rb @@ -80,9 +80,6 @@ def test_find_command_unknown_suggestions message = "Unknown command pish".dup if defined?(DidYouMean) - assert_operator Gem::UnknownCommandError, :<, DidYouMean::Correctable - assert_operator Gem::UnknownCommandError, :instance_variable_defined?, :@attached - assert_send [Gem::UnknownCommandError, :instance_variable_get, :@attached] message << "\nDid you mean? \"push\"" end @@ -92,13 +89,7 @@ def test_find_command_unknown_suggestions actual_message = e.message end - assert_equal message, actual_message, proc {|msg| - (msg || "") + { - unknown_command: e.unknown_command, - spell_checker: (e.spell_checker rescue nil), - corrections: (e.corrections rescue nil), - }.pretty_inspect - } + assert_equal message, actual_message end def test_run_interrupt