diff --git a/error.c b/error.c index ed66e6c8488d0f..e1a01b985aae16 100644 --- a/error.c +++ b/error.c @@ -4163,7 +4163,7 @@ rb_error_frozen_object(VALUE frozen_obj) rb_yjit_lazy_push_frame(GET_EC()->cfp->pc); VALUE mesg = rb_sprintf("can't modify frozen %"PRIsVALUE": ", - CLASS_OF(frozen_obj)); + rb_obj_class(frozen_obj)); VALUE exc = rb_exc_new_str(rb_eFrozenError, mesg); rb_ivar_set(exc, id_recv, frozen_obj); diff --git a/eval.c b/eval.c index 4fbb0e799735d4..ee5bc43f9cc4c1 100644 --- a/eval.c +++ b/eval.c @@ -428,40 +428,10 @@ rb_class_modify_check(VALUE klass) rb_class_set_initialized(klass); } if (OBJ_FROZEN(klass)) { - const char *desc; - if (RCLASS_SINGLETON_P(klass)) { - desc = "object"; klass = RCLASS_ATTACHED_OBJECT(klass); - if (!SPECIAL_CONST_P(klass)) { - switch (BUILTIN_TYPE(klass)) { - case T_MODULE: - case T_ICLASS: - desc = "Module"; - break; - case T_CLASS: - desc = "Class"; - break; - default: - break; - } - } - } - else { - switch (BUILTIN_TYPE(klass)) { - case T_MODULE: - case T_ICLASS: - desc = "module"; - break; - case T_CLASS: - desc = "class"; - break; - default: - Check_Type(klass, T_CLASS); - UNREACHABLE; - } } - rb_frozen_error_raise(klass, "can't modify frozen %s: %"PRIsVALUE, desc, klass); + rb_error_frozen_object(klass); } } diff --git a/spec/ruby/core/exception/frozen_error_spec.rb b/spec/ruby/core/exception/frozen_error_spec.rb index 51eb79cacef6ae..af2e92566192eb 100644 --- a/spec/ruby/core/exception/frozen_error_spec.rb +++ b/spec/ruby/core/exception/frozen_error_spec.rb @@ -26,9 +26,11 @@ def o.x; end object = Object.new object.freeze + msg_class = ruby_version_is("4.0") ? "Object" : "object" + -> { def object.x; end - }.should raise_error(FrozenError, "can't modify frozen object: #{object}") + }.should raise_error(FrozenError, "can't modify frozen #{msg_class}: #{object}") object = [].freeze -> { object << nil }.should raise_error(FrozenError, "can't modify frozen Array: []") diff --git a/spec/ruby/language/def_spec.rb b/spec/ruby/language/def_spec.rb index 296d4787d01c45..0cf1790791a0fb 100644 --- a/spec/ruby/language/def_spec.rb +++ b/spec/ruby/language/def_spec.rb @@ -97,7 +97,8 @@ def foo(a); end def foo; end end }.should raise_error(FrozenError) { |e| - e.message.should == "can't modify frozen module: #{e.receiver}" + msg_class = ruby_version_is("4.0") ? "Module" : "module" + e.message.should == "can't modify frozen #{msg_class}: #{e.receiver}" } -> { @@ -106,7 +107,8 @@ def foo; end def foo; end end }.should raise_error(FrozenError){ |e| - e.message.should == "can't modify frozen class: #{e.receiver}" + msg_class = ruby_version_is("4.0") ? "Class" : "class" + e.message.should == "can't modify frozen #{msg_class}: #{e.receiver}" } end end @@ -283,7 +285,8 @@ def obj.==(other) it "raises FrozenError with the correct class name" do obj = Object.new obj.freeze - -> { def obj.foo; end }.should raise_error(FrozenError, "can't modify frozen object: #{obj}") + msg_class = ruby_version_is("4.0") ? "Object" : "object" + -> { def obj.foo; end }.should raise_error(FrozenError, "can't modify frozen #{msg_class}: #{obj}") obj = Object.new c = obj.singleton_class diff --git a/test/ruby/test_allocation.rb b/test/ruby/test_allocation.rb index 6ade391c951848..90d7c04f9b0a2b 100644 --- a/test/ruby/test_allocation.rb +++ b/test/ruby/test_allocation.rb @@ -527,6 +527,59 @@ def self.splat_and_keyword_splat(*b, **kw#{block}); end RUBY end + def test_anonymous_splat_parameter + only_block = block.empty? ? block : block[2..] + check_allocations(<<~RUBY) + def self.anon_splat(*#{block}); end + + check_allocations(1, 1, "anon_splat(1, a: 2#{block})") + check_allocations(1, 1, "anon_splat(1, *empty_array, a: 2#{block})") + check_allocations(1, 1, "anon_splat(1, a:2, **empty_hash#{block})") + check_allocations(1, 1, "anon_splat(1, **empty_hash, a: 2#{block})") + + check_allocations(1, 0, "anon_splat(1, **nil#{block})") + check_allocations(1, 0, "anon_splat(1, **empty_hash#{block})") + check_allocations(1, 1, "anon_splat(1, **hash1#{block})") + check_allocations(1, 1, "anon_splat(1, *empty_array, **hash1#{block})") + check_allocations(1, 1, "anon_splat(1, **hash1, **empty_hash#{block})") + check_allocations(1, 1, "anon_splat(1, **empty_hash, **hash1#{block})") + + check_allocations(1, 0, "anon_splat(1, *empty_array#{block})") + check_allocations(1, 0, "anon_splat(1, *empty_array, *empty_array, **empty_hash#{block})") + + check_allocations(1, 1, "anon_splat(*array1, a: 2#{block})") + + check_allocations(0, 0, "anon_splat(*nil, **nill#{block})") + check_allocations(0, 0, "anon_splat(*array1, **nill#{block})") + check_allocations(0, 0, "anon_splat(*array1, **empty_hash#{block})") + check_allocations(1, 1, "anon_splat(*array1, **hash1#{block})") + check_allocations(1, 1, "anon_splat(*array1, *empty_array, **hash1#{block})") + + check_allocations(1, 0, "anon_splat(*array1, *empty_array#{block})") + check_allocations(1, 0, "anon_splat(*array1, *empty_array, **empty_hash#{block})") + + check_allocations(1, 1, "anon_splat(*array1, *empty_array, a: 2, **empty_hash#{block})") + check_allocations(1, 1, "anon_splat(*array1, *empty_array, **hash1, **empty_hash#{block})") + + check_allocations(0, 0, "anon_splat(#{only_block})") + check_allocations(1, 1, "anon_splat(a: 2#{block})") + check_allocations(0, 0, "anon_splat(**empty_hash#{block})") + + check_allocations(1, 1, "anon_splat(1, *empty_array, a: 2, **empty_hash#{block})") + check_allocations(1, 1, "anon_splat(1, *empty_array, **hash1, **empty_hash#{block})") + check_allocations(1, 1, "anon_splat(*array1, **empty_hash, a: 2#{block})") + check_allocations(1, 1, "anon_splat(*array1, **hash1, **empty_hash#{block})") + + unless defined?(RubyVM::YJIT.enabled?) && RubyVM::YJIT.enabled? + check_allocations(0, 0, "anon_splat(*array1, **nil#{block})") + check_allocations(1, 0, "anon_splat(*r2k_empty_array#{block})") + check_allocations(1, 1, "anon_splat(*r2k_array#{block})") + check_allocations(1, 0, "anon_splat(*r2k_empty_array1#{block})") + check_allocations(1, 1, "anon_splat(*r2k_array1#{block})") + end + RUBY + end + def test_anonymous_splat_and_anonymous_keyword_splat_parameters only_block = block.empty? ? block : block[2..] check_allocations(<<~RUBY) diff --git a/test/ruby/test_call.rb b/test/ruby/test_call.rb index 7843f3b476e6c9..1b30ed34d8826f 100644 --- a/test/ruby/test_call.rb +++ b/test/ruby/test_call.rb @@ -423,6 +423,35 @@ def self.s(*, kw: 0, **kws) [*->(*a){a}.call(*), kw, kws] end assert_equal([1, 2, {}], s(*r2ka)) end + def test_anon_splat_mutated_bug_21757 + args = [1, 2] + kw = {bug: true} + + def self.m(*); end + m(*args, bug: true) + assert_equal(2, args.length) + + proc = ->(*) { } + proc.(*args, bug: true) + assert_equal(2, args.length) + + def self.m2(*); end + m2(*args, **kw) + assert_equal(2, args.length) + + proc = ->(*) { } + proc.(*args, **kw) + assert_equal(2, args.length) + + def self.m3(*, **nil); end + assert_raise(ArgumentError) { m3(*args, bug: true) } + assert_equal(2, args.length) + + proc = ->(*, **nil) { } + assert_raise(ArgumentError) { proc.(*args, bug: true) } + assert_equal(2, args.length) + end + def test_kwsplat_block_eval_order def self.t(**kw, &b) [kw, b] end diff --git a/test/ruby/test_class.rb b/test/ruby/test_class.rb index 1faecd0cb25e13..22078514ad5cd3 100644 --- a/test/ruby/test_class.rb +++ b/test/ruby/test_class.rb @@ -601,7 +601,7 @@ def test_singleton_class_of_frozen_object obj = Object.new c = obj.singleton_class obj.freeze - assert_raise_with_message(FrozenError, /frozen object/) { + assert_raise_with_message(FrozenError, /frozen Object/) { c.class_eval {def f; end} } end diff --git a/test/ruby/test_frozen.rb b/test/ruby/test_frozen.rb index 2918a2afd822c7..6721cb112863f3 100644 --- a/test/ruby/test_frozen.rb +++ b/test/ruby/test_frozen.rb @@ -27,4 +27,20 @@ def test_setting_ivar_on_frozen_string_with_ivars str.freeze assert_raise(FrozenError) { str.instance_variable_set(:@b, 1) } end + + def test_setting_ivar_on_frozen_string_with_singleton_class + str = "str" + str.singleton_class + str.freeze + assert_raise_with_message(FrozenError, "can't modify frozen String: \"str\"") { str.instance_variable_set(:@a, 1) } + end + + class A + freeze + end + + def test_setting_ivar_on_frozen_class + assert_raise_with_message(FrozenError, "can't modify frozen Class: TestFrozen::A") { A.instance_variable_set(:@a, 1) } + assert_raise_with_message(FrozenError, "can't modify frozen Class: #") { A.singleton_class.instance_variable_set(:@a, 1) } + end end diff --git a/test/ruby/test_module.rb b/test/ruby/test_module.rb index 62b2a7164fb4ff..3a47c2551a813e 100644 --- a/test/ruby/test_module.rb +++ b/test/ruby/test_module.rb @@ -3016,17 +3016,17 @@ def test_frozen_visibility bug11532 = '[ruby-core:70828] [Bug #11532]' c = Class.new {const_set(:A, 1)}.freeze - assert_raise_with_message(FrozenError, /frozen class/, bug11532) { + assert_raise_with_message(FrozenError, /frozen Class/, bug11532) { c.class_eval {private_constant :A} } c = Class.new {const_set(:A, 1); private_constant :A}.freeze - assert_raise_with_message(FrozenError, /frozen class/, bug11532) { + assert_raise_with_message(FrozenError, /frozen Class/, bug11532) { c.class_eval {public_constant :A} } c = Class.new {const_set(:A, 1)}.freeze - assert_raise_with_message(FrozenError, /frozen class/, bug11532) { + assert_raise_with_message(FrozenError, /frozen Class/, bug11532) { c.class_eval {deprecate_constant :A} } end diff --git a/test/ruby/test_refinement.rb b/test/ruby/test_refinement.rb index bdc6667b8e81fe..209e55294b1889 100644 --- a/test/ruby/test_refinement.rb +++ b/test/ruby/test_refinement.rb @@ -1933,6 +1933,29 @@ module PublicCows end; end + def test_public_in_refine_for_method_in_superclass + assert_separately([], "#{<<-"begin;"}\n#{<<-"end;"}") + begin; + bug21446 = '[ruby-core:122558] [Bug #21446]' + + class CowSuper + private + def moo() "Moo"; end + end + class Cow < CowSuper + end + + module PublicCows + refine(Cow) { + public :moo + } + end + + using PublicCows + assert_equal("Moo", Cow.new.moo, bug21446) + end; + end + module SuperToModule class Parent end diff --git a/test/ruby/test_zjit.rb b/test/ruby/test_zjit.rb index 81d940407063f1..49b3616425ecd3 100644 --- a/test/ruby/test_zjit.rb +++ b/test/ruby/test_zjit.rb @@ -2057,7 +2057,7 @@ def self.test = @@x = 42 end def test_setclassvariable_raises - assert_compiles '"can\'t modify frozen #: Foo"', %q{ + assert_compiles '"can\'t modify frozen Class: Foo"', %q{ class Foo def self.test = @@x = 42 freeze diff --git a/thread_pthread.c b/thread_pthread.c index 93b32e55c0f72b..0a19f7f0310af1 100644 --- a/thread_pthread.c +++ b/thread_pthread.c @@ -1459,7 +1459,7 @@ rb_ractor_sched_barrier_start(rb_vm_t *vm, rb_ractor_t *cr) vm->ractor.sync.lock_owner = cr; } - // do not release ractor_sched_lock and threre is no newly added (resumed) thread + // do not release ractor_sched_lock and there is no newly added (resumed) thread // thread_sched_setup_running_threads } diff --git a/vm_args.c b/vm_args.c index 64ed88d0e1dcce..8d4042e35566ae 100644 --- a/vm_args.c +++ b/vm_args.c @@ -638,12 +638,26 @@ setup_parameters_complex(rb_execution_context_t * const ec, const rb_iseq_t * co given_argc == ISEQ_BODY(iseq)->param.lead_num + (kw_flag ? 2 : 1) && !ISEQ_BODY(iseq)->param.flags.has_opt && !ISEQ_BODY(iseq)->param.flags.has_post && - !ISEQ_BODY(iseq)->param.flags.ruby2_keywords && - (!kw_flag || - !ISEQ_BODY(iseq)->param.flags.has_kw || - !ISEQ_BODY(iseq)->param.flags.has_kwrest || - !ISEQ_BODY(iseq)->param.flags.accepts_no_kwarg)) { - args->rest_dupped = true; + !ISEQ_BODY(iseq)->param.flags.ruby2_keywords) { + if (kw_flag) { + if (ISEQ_BODY(iseq)->param.flags.has_kw || + ISEQ_BODY(iseq)->param.flags.has_kwrest) { + args->rest_dupped = true; + } + else if (kw_flag & VM_CALL_KW_SPLAT) { + VALUE kw_hash = locals[args->argc - 1]; + if (kw_hash == Qnil || + (RB_TYPE_P(kw_hash, T_HASH) && RHASH_EMPTY_P(kw_hash))) { + args->rest_dupped = true; + } + } + + } + else if (!ISEQ_BODY(iseq)->param.flags.has_kw && + !ISEQ_BODY(iseq)->param.flags.has_kwrest && + !ISEQ_BODY(iseq)->param.flags.accepts_no_kwarg) { + args->rest_dupped = true; + } } } diff --git a/vm_method.c b/vm_method.c index c4f391b5afe38a..dbc5ad97eded92 100644 --- a/vm_method.c +++ b/vm_method.c @@ -1281,6 +1281,7 @@ check_override_opt_method(VALUE klass, VALUE mid) } } +static inline rb_method_entry_t* search_method0(VALUE klass, ID id, VALUE *defined_class_ptr, bool skip_refined); /* * klass->method_table[mid] = method_entry(defined_class, visi, def) * @@ -1321,7 +1322,12 @@ rb_method_entry_make(VALUE klass, ID mid, VALUE defined_class, rb_method_visibil if (RB_TYPE_P(klass, T_MODULE) && FL_TEST(klass, RMODULE_IS_REFINEMENT)) { VALUE refined_class = rb_refinement_module_get_refined_class(klass); + bool search_superclass = type == VM_METHOD_TYPE_ZSUPER && !lookup_method_table(refined_class, mid); rb_add_refined_method_entry(refined_class, mid); + if (search_superclass) { + rb_method_entry_t *me = lookup_method_table(refined_class, mid); + me->def->body.refined.orig_me = search_method0(refined_class, mid, NULL, true); + } } if (type == VM_METHOD_TYPE_REFINED) { rb_method_entry_t *old_me = lookup_method_table(RCLASS_ORIGIN(klass), mid); diff --git a/zjit.c b/zjit.c index 7731bc908f6ab9..75cca281a45a91 100644 --- a/zjit.c +++ b/zjit.c @@ -315,6 +315,7 @@ VALUE rb_zjit_stats(rb_execution_context_t *ec, VALUE self, VALUE target_key); VALUE rb_zjit_reset_stats_bang(rb_execution_context_t *ec, VALUE self); VALUE rb_zjit_stats_enabled_p(rb_execution_context_t *ec, VALUE self); VALUE rb_zjit_print_stats_p(rb_execution_context_t *ec, VALUE self); +VALUE rb_zjit_get_stats_file_path_p(rb_execution_context_t *ec, VALUE self); VALUE rb_zjit_trace_exit_locations_enabled_p(rb_execution_context_t *ec, VALUE self); VALUE rb_zjit_get_exit_locations(rb_execution_context_t *ec, VALUE self); diff --git a/zjit.rb b/zjit.rb index d128adead6fe39..e2aa55f764eb9a 100644 --- a/zjit.rb +++ b/zjit.rb @@ -10,6 +10,9 @@ module RubyVM::ZJIT # Blocks that are called when YJIT is enabled @jit_hooks = [] # Avoid calling a Ruby method here to avoid interfering with compilation tests + if Primitive.rb_zjit_get_stats_file_path_p + at_exit { print_stats_file } + end if Primitive.rb_zjit_print_stats_p at_exit { print_stats } end @@ -333,6 +336,14 @@ def print_stats $stderr.write stats_string end + # Print ZJIT stats to file + def print_stats_file + filename = Primitive.rb_zjit_get_stats_file_path_p + File.open(filename, "wb") do |file| + file.write stats_string + end + end + def dump_locations # :nodoc: return unless trace_exit_locations_enabled? diff --git a/zjit/src/hir.rs b/zjit/src/hir.rs index 6d1fe70e271869..4e597db936c345 100644 --- a/zjit/src/hir.rs +++ b/zjit/src/hir.rs @@ -643,6 +643,40 @@ pub enum SendFallbackReason { Uncategorized(ruby_vminsn_type), } +impl Display for SendFallbackReason { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + match self { + SendWithoutBlockPolymorphic => write!(f, "SendWithoutBlock: polymorphic call site"), + SendWithoutBlockMegamorphic => write!(f, "SendWithoutBlock: megamorphic call site"), + SendWithoutBlockNoProfiles => write!(f, "SendWithoutBlock: no profile data available"), + SendWithoutBlockCfuncNotVariadic => write!(f, "SendWithoutBlock: C function is not variadic"), + SendWithoutBlockCfuncArrayVariadic => write!(f, "SendWithoutBlock: C function expects array variadic"), + SendWithoutBlockNotOptimizedMethodType(method_type) => write!(f, "SendWithoutBlock: unsupported method type {:?}", method_type), + SendWithoutBlockNotOptimizedMethodTypeOptimized(opt_type) => write!(f, "SendWithoutBlock: unsupported optimized method type {:?}", opt_type), + SendWithoutBlockBopRedefined => write!(f, "SendWithoutBlock: basic operation was redefined"), + SendWithoutBlockOperandsNotFixnum => write!(f, "SendWithoutBlock: operands are not fixnums"), + SendWithoutBlockDirectKeywordMismatch => write!(f, "SendWithoutBlockDirect: keyword mismatch"), + SendWithoutBlockDirectOptionalKeywords => write!(f, "SendWithoutBlockDirect: optional keywords"), + SendWithoutBlockDirectKeywordCountMismatch => write!(f, "SendWithoutBlockDirect: keyword count mismatch"), + SendWithoutBlockDirectMissingKeyword => write!(f, "SendWithoutBlockDirect: missing keyword"), + SendPolymorphic => write!(f, "Send: polymorphic call site"), + SendMegamorphic => write!(f, "Send: megamorphic call site"), + SendNoProfiles => write!(f, "Send: no profile data available"), + SendCfuncVariadic => write!(f, "Send: C function is variadic"), + SendCfuncArrayVariadic => write!(f, "Send: C function expects array variadic"), + SendNotOptimizedMethodType(method_type) => write!(f, "Send: unsupported method type {:?}", method_type), + CCallWithFrameTooManyArgs => write!(f, "CCallWithFrame: too many arguments"), + ObjToStringNotString => write!(f, "ObjToString: result is not a string"), + TooManyArgsForLir => write!(f, "Too many arguments for LIR"), + BmethodNonIseqProc => write!(f, "Bmethod: Proc object is not defined by an ISEQ"), + ArgcParamMismatch => write!(f, "Argument count does not match parameter count"), + ComplexArgPass => write!(f, "Complex argument passing"), + UnexpectedKeywordArgs => write!(f, "Unexpected Keyword Args"), + Uncategorized(insn) => write!(f, "Uncategorized({})", insn_name(*insn as usize)), + } + } +} + /// An instruction in the SSA IR. The output of an instruction is referred to by the index of /// the instruction ([`InsnId`]). SSA form enables this, and [`UnionFind`] ([`Function::find`]) /// helps with editing. @@ -1203,11 +1237,12 @@ impl<'a> std::fmt::Display for InsnPrinter<'a> { Insn::Jump(target) => { write!(f, "Jump {target}") } Insn::IfTrue { val, target } => { write!(f, "IfTrue {val}, {target}") } Insn::IfFalse { val, target } => { write!(f, "IfFalse {val}, {target}") } - Insn::SendWithoutBlock { recv, cd, args, .. } => { + Insn::SendWithoutBlock { recv, cd, args, reason, .. } => { write!(f, "SendWithoutBlock {recv}, :{}", ruby_call_method_name(*cd))?; for arg in args { write!(f, ", {arg}")?; } + write!(f, " # SendFallbackReason: {reason}")?; Ok(()) } Insn::SendWithoutBlockDirect { recv, cd, iseq, args, .. } => { @@ -1217,7 +1252,7 @@ impl<'a> std::fmt::Display for InsnPrinter<'a> { } Ok(()) } - Insn::Send { recv, cd, args, blockiseq, .. } => { + Insn::Send { recv, cd, args, blockiseq, reason, .. } => { // For tests, we want to check HIR snippets textually. Addresses change // between runs, making tests fail. Instead, pick an arbitrary hex value to // use as a "pointer" so we can check the rest of the HIR. @@ -1225,27 +1260,31 @@ impl<'a> std::fmt::Display for InsnPrinter<'a> { for arg in args { write!(f, ", {arg}")?; } + write!(f, " # SendFallbackReason: {reason}")?; Ok(()) } - Insn::SendForward { recv, cd, args, blockiseq, .. } => { + Insn::SendForward { recv, cd, args, blockiseq, reason, .. } => { write!(f, "SendForward {recv}, {:p}, :{}", self.ptr_map.map_ptr(blockiseq), ruby_call_method_name(*cd))?; for arg in args { write!(f, ", {arg}")?; } + write!(f, " # SendFallbackReason: {reason}")?; Ok(()) } - Insn::InvokeSuper { recv, blockiseq, args, .. } => { + Insn::InvokeSuper { recv, blockiseq, args, reason, .. } => { write!(f, "InvokeSuper {recv}, {:p}", self.ptr_map.map_ptr(blockiseq))?; for arg in args { write!(f, ", {arg}")?; } + write!(f, " # SendFallbackReason: {reason}")?; Ok(()) } - Insn::InvokeBlock { args, .. } => { + Insn::InvokeBlock { args, reason, .. } => { write!(f, "InvokeBlock")?; for arg in args { write!(f, ", {arg}")?; } + write!(f, " # SendFallbackReason: {reason}")?; Ok(()) } Insn::InvokeBuiltin { bf, args, leaf, .. } => { @@ -2044,7 +2083,7 @@ impl Function { /// Update DynamicSendReason for the instruction at insn_id fn set_dynamic_send_reason(&mut self, insn_id: InsnId, dynamic_send_reason: SendFallbackReason) { use Insn::*; - if get_option!(stats) { + if get_option!(stats) || get_option!(dump_hir_opt).is_some() || cfg!(test) { match self.insns.get_mut(insn_id.0).unwrap() { Send { reason, .. } | SendForward { reason, .. } diff --git a/zjit/src/hir/opt_tests.rs b/zjit/src/hir/opt_tests.rs index 0a0737469371d7..3e2db528158090 100644 --- a/zjit/src/hir/opt_tests.rs +++ b/zjit/src/hir/opt_tests.rs @@ -812,7 +812,7 @@ mod hir_opt_tests { EntryPoint JIT(0) Jump bb2(v4) bb2(v6:BasicObject): - v11:BasicObject = SendWithoutBlock v6, :foo + v11:BasicObject = SendWithoutBlock v6, :foo # SendFallbackReason: SendWithoutBlock: unsupported method type Null CheckInterrupts Return v11 "); @@ -2444,7 +2444,7 @@ mod hir_opt_tests { bb2(v6:BasicObject): v10:Fixnum[1] = Const Value(1) v12:Fixnum[0] = Const Value(0) - v14:BasicObject = SendWithoutBlock v10, :itself, v12 + v14:BasicObject = SendWithoutBlock v10, :itself, v12 # SendFallbackReason: SendWithoutBlock: unsupported method type Cfunc CheckInterrupts Return v14 "); @@ -2670,7 +2670,7 @@ mod hir_opt_tests { EntryPoint JIT(0) Jump bb2(v4) bb2(v6:BasicObject): - v11:BasicObject = Send v6, 0x1000, :foo + v11:BasicObject = Send v6, 0x1000, :foo # SendFallbackReason: Send: unsupported method type Iseq CheckInterrupts Return v11 "); @@ -2702,7 +2702,7 @@ mod hir_opt_tests { bb2(v8:BasicObject, v9:NilClass): v13:Fixnum[1] = Const Value(1) SetLocal :a, l0, EP@3, v13 - v19:BasicObject = Send v8, 0x1000, :foo + v19:BasicObject = Send v8, 0x1000, :foo # SendFallbackReason: Send: unsupported method type Iseq v20:BasicObject = GetLocal :a, l0, EP@3 v24:BasicObject = GetLocal :a, l0, EP@3 CheckInterrupts @@ -2730,7 +2730,7 @@ mod hir_opt_tests { bb2(v6:BasicObject): v11:Fixnum[1] = Const Value(1) IncrCounter complex_arg_pass_param_rest - v13:BasicObject = SendWithoutBlock v6, :foo, v11 + v13:BasicObject = SendWithoutBlock v6, :foo, v11 # SendFallbackReason: Complex argument passing CheckInterrupts Return v13 "); @@ -2755,7 +2755,7 @@ mod hir_opt_tests { bb2(v6:BasicObject): v11:Fixnum[10] = Const Value(10) IncrCounter complex_arg_pass_param_post - v13:BasicObject = SendWithoutBlock v6, :foo, v11 + v13:BasicObject = SendWithoutBlock v6, :foo, v11 # SendFallbackReason: Complex argument passing CheckInterrupts Return v13 "); @@ -2871,7 +2871,7 @@ mod hir_opt_tests { v11:Fixnum[0] = Const Value(0) v13:Fixnum[2] = Const Value(2) IncrCounter complex_arg_pass_param_kw_opt - v15:BasicObject = SendWithoutBlock v6, :foo, v11, v13 + v15:BasicObject = SendWithoutBlock v6, :foo, v11, v13 # SendFallbackReason: Complex argument passing CheckInterrupts Return v15 "); @@ -2936,7 +2936,7 @@ mod hir_opt_tests { bb2(v6:BasicObject): v11:Fixnum[2] = Const Value(2) IncrCounter complex_arg_pass_param_kw_opt - v13:BasicObject = SendWithoutBlock v6, :foo, v11 + v13:BasicObject = SendWithoutBlock v6, :foo, v11 # SendFallbackReason: Complex argument passing CheckInterrupts Return v13 "); @@ -2962,7 +2962,7 @@ mod hir_opt_tests { bb2(v6:BasicObject): v11:Fixnum[1] = Const Value(1) IncrCounter complex_arg_pass_param_kwrest - v13:BasicObject = SendWithoutBlock v6, :foo, v11 + v13:BasicObject = SendWithoutBlock v6, :foo, v11 # SendFallbackReason: Complex argument passing CheckInterrupts Return v13 "); @@ -2987,7 +2987,7 @@ mod hir_opt_tests { Jump bb2(v4) bb2(v6:BasicObject): IncrCounter complex_arg_pass_param_kw_opt - v11:BasicObject = SendWithoutBlock v6, :foo + v11:BasicObject = SendWithoutBlock v6, :foo # SendFallbackReason: Complex argument passing CheckInterrupts Return v11 "); @@ -3012,7 +3012,7 @@ mod hir_opt_tests { Jump bb2(v4) bb2(v6:BasicObject): IncrCounter complex_arg_pass_param_kwrest - v11:BasicObject = SendWithoutBlock v6, :foo + v11:BasicObject = SendWithoutBlock v6, :foo # SendFallbackReason: Complex argument passing CheckInterrupts Return v11 "); @@ -3038,7 +3038,7 @@ mod hir_opt_tests { v11:StringExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) v12:StringExact = StringCopy v11 v14:Fixnum[1] = Const Value(1) - v16:BasicObject = SendWithoutBlock v6, :sprintf, v12, v14 + v16:BasicObject = SendWithoutBlock v6, :sprintf, v12, v14 # SendFallbackReason: Complex argument passing CheckInterrupts Return v16 "); @@ -3072,7 +3072,7 @@ mod hir_opt_tests { SetLocal :a, l0, EP@3, v16 v22:TrueClass = Const Value(true) IncrCounter complex_arg_pass_caller_kwarg - v24:BasicObject = Send v11, 0x1000, :each_line, v22 + v24:BasicObject = Send v11, 0x1000, :each_line, v22 # SendFallbackReason: Complex argument passing v25:BasicObject = GetLocal :s, l0, EP@4 v26:BasicObject = GetLocal :a, l0, EP@3 v30:BasicObject = GetLocal :a, l0, EP@3 @@ -3337,7 +3337,7 @@ mod hir_opt_tests { v46:HashExact = ObjectAllocClass Hash:VALUE(0x1008) IncrCounter complex_arg_pass_param_block IncrCounter complex_arg_pass_param_kw_opt - v20:BasicObject = SendWithoutBlock v46, :initialize + v20:BasicObject = SendWithoutBlock v46, :initialize # SendFallbackReason: Complex argument passing CheckInterrupts CheckInterrupts Return v46 @@ -3541,7 +3541,7 @@ mod hir_opt_tests { bb2(v8:BasicObject, v9:BasicObject): GuardBlockParamProxy l0 v15:HeapObject[BlockParamProxy] = Const Value(VALUE(0x1000)) - v17:BasicObject = Send v8, 0x1008, :tap, v15 + v17:BasicObject = Send v8, 0x1008, :tap, v15 # SendFallbackReason: Uncategorized(send) CheckInterrupts Return v17 "); @@ -4018,7 +4018,7 @@ mod hir_opt_tests { PatchPoint MethodRedefined(Hash@0x1000, dup@0x1008, cme:0x1010) PatchPoint NoSingletonClass(Hash@0x1000) v22:BasicObject = CCallWithFrame v10, :Kernel#dup@0x1038 - v14:BasicObject = SendWithoutBlock v22, :freeze + v14:BasicObject = SendWithoutBlock v22, :freeze # SendFallbackReason: Uncategorized(opt_send_without_block) CheckInterrupts Return v14 "); @@ -4041,7 +4041,7 @@ mod hir_opt_tests { bb2(v6:BasicObject): v10:HashExact = NewHash v12:NilClass = Const Value(nil) - v14:BasicObject = SendWithoutBlock v10, :freeze, v12 + v14:BasicObject = SendWithoutBlock v10, :freeze, v12 # SendFallbackReason: SendWithoutBlock: unsupported method type Cfunc CheckInterrupts Return v14 "); @@ -4111,7 +4111,7 @@ mod hir_opt_tests { PatchPoint MethodRedefined(Array@0x1000, dup@0x1008, cme:0x1010) PatchPoint NoSingletonClass(Array@0x1000) v22:BasicObject = CCallWithFrame v10, :Kernel#dup@0x1038 - v14:BasicObject = SendWithoutBlock v22, :freeze + v14:BasicObject = SendWithoutBlock v22, :freeze # SendFallbackReason: Uncategorized(opt_send_without_block) CheckInterrupts Return v14 "); @@ -4134,7 +4134,7 @@ mod hir_opt_tests { bb2(v6:BasicObject): v10:ArrayExact = NewArray v12:NilClass = Const Value(nil) - v14:BasicObject = SendWithoutBlock v10, :freeze, v12 + v14:BasicObject = SendWithoutBlock v10, :freeze, v12 # SendFallbackReason: SendWithoutBlock: unsupported method type Cfunc CheckInterrupts Return v14 "); @@ -4205,7 +4205,7 @@ mod hir_opt_tests { PatchPoint MethodRedefined(String@0x1008, dup@0x1010, cme:0x1018) PatchPoint NoSingletonClass(String@0x1008) v23:BasicObject = CCallWithFrame v11, :String#dup@0x1040 - v15:BasicObject = SendWithoutBlock v23, :freeze + v15:BasicObject = SendWithoutBlock v23, :freeze # SendFallbackReason: Uncategorized(opt_send_without_block) CheckInterrupts Return v15 "); @@ -4229,7 +4229,7 @@ mod hir_opt_tests { v10:StringExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) v11:StringExact = StringCopy v10 v13:NilClass = Const Value(nil) - v15:BasicObject = SendWithoutBlock v11, :freeze, v13 + v15:BasicObject = SendWithoutBlock v11, :freeze, v13 # SendFallbackReason: SendWithoutBlock: unsupported method type Cfunc CheckInterrupts Return v15 "); @@ -4300,7 +4300,7 @@ mod hir_opt_tests { PatchPoint MethodRedefined(String@0x1008, dup@0x1010, cme:0x1018) PatchPoint NoSingletonClass(String@0x1008) v23:BasicObject = CCallWithFrame v11, :String#dup@0x1040 - v15:BasicObject = SendWithoutBlock v23, :-@ + v15:BasicObject = SendWithoutBlock v23, :-@ # SendFallbackReason: Uncategorized(opt_send_without_block) CheckInterrupts Return v15 "); @@ -4805,7 +4805,7 @@ mod hir_opt_tests { Jump bb2(v4) bb2(v6:BasicObject): v11:Fixnum[100] = Const Value(100) - v13:BasicObject = SendWithoutBlock v6, :identity, v11 + v13:BasicObject = SendWithoutBlock v6, :identity, v11 # SendFallbackReason: Bmethod: Proc object is not defined by an ISEQ CheckInterrupts Return v13 "); @@ -4828,7 +4828,7 @@ mod hir_opt_tests { EntryPoint JIT(0) Jump bb2(v4) bb2(v6:BasicObject): - v11:BasicObject = Send v6, 0x1000, :bmethod + v11:BasicObject = Send v6, 0x1000, :bmethod # SendFallbackReason: Send: unsupported method type Bmethod CheckInterrupts Return v11 "); @@ -5667,7 +5667,7 @@ mod hir_opt_tests { EntryPoint JIT(0) Jump bb2(v4) bb2(v6:BasicObject): - v11:BasicObject = SendWithoutBlock v6, :foo + v11:BasicObject = SendWithoutBlock v6, :foo # SendFallbackReason: Uncategorized(opt_send_without_block) CheckInterrupts Return v11 "); @@ -5710,7 +5710,7 @@ mod hir_opt_tests { EntryPoint JIT(0) Jump bb2(v5, v6) bb2(v8:BasicObject, v9:BasicObject): - v14:BasicObject = SendWithoutBlock v9, :foo + v14:BasicObject = SendWithoutBlock v9, :foo # SendFallbackReason: Uncategorized(opt_send_without_block) CheckInterrupts Return v14 "); @@ -5844,7 +5844,7 @@ mod hir_opt_tests { GuardBlockParamProxy l0 v16:HeapObject[BlockParamProxy] = Const Value(VALUE(0x1000)) IncrCounter complex_arg_pass_caller_blockarg - v18:BasicObject = Send v13, 0x1008, :map, v16 + v18:BasicObject = Send v13, 0x1008, :map, v16 # SendFallbackReason: Complex argument passing CheckInterrupts Return v18 "); @@ -5870,7 +5870,7 @@ mod hir_opt_tests { EntryPoint JIT(0) Jump bb2(v4) bb2(v6:BasicObject): - v11:BasicObject = Send v6, 0x1000, :foo + v11:BasicObject = Send v6, 0x1000, :foo # SendFallbackReason: Send: unsupported method type Iseq CheckInterrupts Return v11 "); @@ -7589,7 +7589,7 @@ mod hir_opt_tests { v12:Fixnum[3] = Const Value(3) v14:Fixnum[3] = Const Value(3) v16:Fixnum[3] = Const Value(3) - v18:BasicObject = SendWithoutBlock v10, :foo, v12, v14, v16 + v18:BasicObject = SendWithoutBlock v10, :foo, v12, v14, v16 # SendFallbackReason: Argument count does not match parameter count CheckInterrupts Return v18 "); @@ -7639,7 +7639,7 @@ mod hir_opt_tests { Jump bb2(v4) bb2(v6:BasicObject): v10:Fixnum[0] = Const Value(0) - v12:BasicObject = SendWithoutBlock v10, :foo + v12:BasicObject = SendWithoutBlock v10, :foo # SendFallbackReason: Argument count does not match parameter count CheckInterrupts Return v12 "); @@ -7662,7 +7662,7 @@ mod hir_opt_tests { bb2(v6:BasicObject): v10:Fixnum[4] = Const Value(4) v12:Fixnum[1] = Const Value(1) - v14:BasicObject = SendWithoutBlock v10, :succ, v12 + v14:BasicObject = SendWithoutBlock v10, :succ, v12 # SendFallbackReason: SendWithoutBlock: unsupported method type Cfunc CheckInterrupts Return v14 "); @@ -7816,7 +7816,7 @@ mod hir_opt_tests { EntryPoint JIT(0) Jump bb2(v6, v7, v8) bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): - v17:BasicObject = SendWithoutBlock v11, :^ + v17:BasicObject = SendWithoutBlock v11, :^ # SendFallbackReason: Uncategorized(opt_send_without_block) CheckInterrupts Return v17 "); @@ -8491,17 +8491,17 @@ mod hir_opt_tests { v13:ArrayExact = NewArray v19:ArrayExact = ToArray v13 IncrCounter complex_arg_pass_caller_splat - v21:BasicObject = SendWithoutBlock v8, :foo, v19 + v21:BasicObject = SendWithoutBlock v8, :foo, v19 # SendFallbackReason: Complex argument passing v25:StringExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) v26:StringExact = StringCopy v25 PatchPoint NoEPEscape(test) v31:ArrayExact = ToArray v13 IncrCounter complex_arg_pass_caller_splat - v33:BasicObject = SendWithoutBlock v26, :display, v31 + v33:BasicObject = SendWithoutBlock v26, :display, v31 # SendFallbackReason: Complex argument passing PatchPoint NoEPEscape(test) v41:ArrayExact = ToArray v13 IncrCounter complex_arg_pass_caller_splat - v43:BasicObject = SendWithoutBlock v8, :itself, v41 + v43:BasicObject = SendWithoutBlock v8, :itself, v41 # SendFallbackReason: Complex argument passing CheckInterrupts Return v43 "); @@ -9186,7 +9186,7 @@ mod hir_opt_tests { IncrCounter complex_arg_pass_param_block IncrCounter complex_arg_pass_param_kwrest IncrCounter complex_arg_pass_param_kw_opt - v13:BasicObject = SendWithoutBlock v6, :fancy, v11 + v13:BasicObject = SendWithoutBlock v6, :fancy, v11 # SendFallbackReason: Complex argument passing CheckInterrupts Return v13 "); @@ -9210,7 +9210,7 @@ mod hir_opt_tests { Jump bb2(v4) bb2(v6:BasicObject): IncrCounter complex_arg_pass_param_forwardable - v11:BasicObject = SendWithoutBlock v6, :forwardable + v11:BasicObject = SendWithoutBlock v6, :forwardable # SendFallbackReason: Complex argument passing CheckInterrupts Return v11 "); diff --git a/zjit/src/hir/tests.rs b/zjit/src/hir/tests.rs index 7ef7671fa444f6..49f092337e9816 100644 --- a/zjit/src/hir/tests.rs +++ b/zjit/src/hir/tests.rs @@ -524,7 +524,7 @@ pub mod hir_build_tests { bb2(v6:BasicObject): v10:Fixnum[1] = Const Value(1) v12:Fixnum[2] = Const Value(2) - v15:BasicObject = SendWithoutBlock v10, :+, v12 + v15:BasicObject = SendWithoutBlock v10, :+, v12 # SendFallbackReason: Uncategorized(opt_plus) CheckInterrupts Return v15 "); @@ -777,11 +777,11 @@ pub mod hir_build_tests { SetLocal :l1, l1, EP@3, v10 v15:BasicObject = GetLocal :l1, l1, EP@3 v17:BasicObject = GetLocal :l2, l2, EP@4 - v20:BasicObject = SendWithoutBlock v15, :+, v17 + v20:BasicObject = SendWithoutBlock v15, :+, v17 # SendFallbackReason: Uncategorized(opt_plus) SetLocal :l2, l2, EP@4, v20 v25:BasicObject = GetLocal :l2, l2, EP@4 v27:BasicObject = GetLocal :l3, l3, EP@5 - v30:BasicObject = SendWithoutBlock v25, :+, v27 + v30:BasicObject = SendWithoutBlock v25, :+, v27 # SendFallbackReason: Uncategorized(opt_plus) SetLocal :l3, l3, EP@5, v30 CheckInterrupts Return v30 @@ -1102,7 +1102,7 @@ pub mod hir_build_tests { EntryPoint JIT(0) Jump bb2(v6, v7, v8) bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): - v19:BasicObject = SendWithoutBlock v11, :+, v12 + v19:BasicObject = SendWithoutBlock v11, :+, v12 # SendFallbackReason: Uncategorized(opt_plus) CheckInterrupts Return v19 "); @@ -1127,7 +1127,7 @@ pub mod hir_build_tests { EntryPoint JIT(0) Jump bb2(v6, v7, v8) bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): - v19:BasicObject = SendWithoutBlock v11, :-, v12 + v19:BasicObject = SendWithoutBlock v11, :-, v12 # SendFallbackReason: Uncategorized(opt_minus) CheckInterrupts Return v19 "); @@ -1152,7 +1152,7 @@ pub mod hir_build_tests { EntryPoint JIT(0) Jump bb2(v6, v7, v8) bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): - v19:BasicObject = SendWithoutBlock v11, :*, v12 + v19:BasicObject = SendWithoutBlock v11, :*, v12 # SendFallbackReason: Uncategorized(opt_mult) CheckInterrupts Return v19 "); @@ -1177,7 +1177,7 @@ pub mod hir_build_tests { EntryPoint JIT(0) Jump bb2(v6, v7, v8) bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): - v19:BasicObject = SendWithoutBlock v11, :/, v12 + v19:BasicObject = SendWithoutBlock v11, :/, v12 # SendFallbackReason: Uncategorized(opt_div) CheckInterrupts Return v19 "); @@ -1202,7 +1202,7 @@ pub mod hir_build_tests { EntryPoint JIT(0) Jump bb2(v6, v7, v8) bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): - v19:BasicObject = SendWithoutBlock v11, :%, v12 + v19:BasicObject = SendWithoutBlock v11, :%, v12 # SendFallbackReason: Uncategorized(opt_mod) CheckInterrupts Return v19 "); @@ -1227,7 +1227,7 @@ pub mod hir_build_tests { EntryPoint JIT(0) Jump bb2(v6, v7, v8) bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): - v19:BasicObject = SendWithoutBlock v11, :==, v12 + v19:BasicObject = SendWithoutBlock v11, :==, v12 # SendFallbackReason: Uncategorized(opt_eq) CheckInterrupts Return v19 "); @@ -1252,7 +1252,7 @@ pub mod hir_build_tests { EntryPoint JIT(0) Jump bb2(v6, v7, v8) bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): - v19:BasicObject = SendWithoutBlock v11, :!=, v12 + v19:BasicObject = SendWithoutBlock v11, :!=, v12 # SendFallbackReason: Uncategorized(opt_neq) CheckInterrupts Return v19 "); @@ -1277,7 +1277,7 @@ pub mod hir_build_tests { EntryPoint JIT(0) Jump bb2(v6, v7, v8) bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): - v19:BasicObject = SendWithoutBlock v11, :<, v12 + v19:BasicObject = SendWithoutBlock v11, :<, v12 # SendFallbackReason: Uncategorized(opt_lt) CheckInterrupts Return v19 "); @@ -1302,7 +1302,7 @@ pub mod hir_build_tests { EntryPoint JIT(0) Jump bb2(v6, v7, v8) bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): - v19:BasicObject = SendWithoutBlock v11, :<=, v12 + v19:BasicObject = SendWithoutBlock v11, :<=, v12 # SendFallbackReason: Uncategorized(opt_le) CheckInterrupts Return v19 "); @@ -1327,7 +1327,7 @@ pub mod hir_build_tests { EntryPoint JIT(0) Jump bb2(v6, v7, v8) bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): - v19:BasicObject = SendWithoutBlock v11, :>, v12 + v19:BasicObject = SendWithoutBlock v11, :>, v12 # SendFallbackReason: Uncategorized(opt_gt) CheckInterrupts Return v19 "); @@ -1368,7 +1368,7 @@ pub mod hir_build_tests { bb4(v26:BasicObject, v27:BasicObject, v28:BasicObject): PatchPoint NoEPEscape(test) v34:Fixnum[0] = Const Value(0) - v37:BasicObject = SendWithoutBlock v28, :>, v34 + v37:BasicObject = SendWithoutBlock v28, :>, v34 # SendFallbackReason: Uncategorized(opt_gt) CheckInterrupts v40:CBool = Test v37 IfTrue v40, bb3(v26, v27, v28) @@ -1379,9 +1379,9 @@ pub mod hir_build_tests { bb3(v53:BasicObject, v54:BasicObject, v55:BasicObject): PatchPoint NoEPEscape(test) v62:Fixnum[1] = Const Value(1) - v65:BasicObject = SendWithoutBlock v54, :+, v62 + v65:BasicObject = SendWithoutBlock v54, :+, v62 # SendFallbackReason: Uncategorized(opt_plus) v70:Fixnum[1] = Const Value(1) - v73:BasicObject = SendWithoutBlock v55, :-, v70 + v73:BasicObject = SendWithoutBlock v55, :-, v70 # SendFallbackReason: Uncategorized(opt_minus) Jump bb4(v53, v65, v73) "); } @@ -1405,7 +1405,7 @@ pub mod hir_build_tests { EntryPoint JIT(0) Jump bb2(v6, v7, v8) bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): - v19:BasicObject = SendWithoutBlock v11, :>=, v12 + v19:BasicObject = SendWithoutBlock v11, :>=, v12 # SendFallbackReason: Uncategorized(opt_ge) CheckInterrupts Return v19 "); @@ -1472,7 +1472,7 @@ pub mod hir_build_tests { bb2(v6:BasicObject): v11:Fixnum[2] = Const Value(2) v13:Fixnum[3] = Const Value(3) - v15:BasicObject = SendWithoutBlock v6, :bar, v11, v13 + v15:BasicObject = SendWithoutBlock v6, :bar, v11, v13 # SendFallbackReason: Uncategorized(opt_send_without_block) CheckInterrupts Return v15 "); @@ -1500,7 +1500,7 @@ pub mod hir_build_tests { EntryPoint JIT(0) Jump bb2(v5, v6) bb2(v8:BasicObject, v9:BasicObject): - v14:BasicObject = Send v9, 0x1000, :each + v14:BasicObject = Send v9, 0x1000, :each # SendFallbackReason: Uncategorized(send) v15:BasicObject = GetLocal :a, l0, EP@3 CheckInterrupts Return v14 @@ -1559,7 +1559,7 @@ pub mod hir_build_tests { v18:StringExact = StringCopy v17 v20:StringExact[VALUE(0x1010)] = Const Value(VALUE(0x1010)) v21:StringExact = StringCopy v20 - v23:BasicObject = SendWithoutBlock v6, :unknown_method, v12, v15, v18, v21 + v23:BasicObject = SendWithoutBlock v6, :unknown_method, v12, v15, v18, v21 # SendFallbackReason: Uncategorized(opt_send_without_block) CheckInterrupts Return v23 "); @@ -1582,7 +1582,7 @@ pub mod hir_build_tests { Jump bb2(v5, v6) bb2(v8:BasicObject, v9:BasicObject): v15:ArrayExact = ToArray v9 - v17:BasicObject = SendWithoutBlock v8, :foo, v15 + v17:BasicObject = SendWithoutBlock v8, :foo, v15 # SendFallbackReason: Uncategorized(opt_send_without_block) CheckInterrupts Return v17 "); @@ -1604,7 +1604,7 @@ pub mod hir_build_tests { EntryPoint JIT(0) Jump bb2(v5, v6) bb2(v8:BasicObject, v9:BasicObject): - v15:BasicObject = Send v8, 0x1000, :foo, v9 + v15:BasicObject = Send v8, 0x1000, :foo, v9 # SendFallbackReason: Uncategorized(send) CheckInterrupts Return v15 "); @@ -1627,7 +1627,7 @@ pub mod hir_build_tests { Jump bb2(v5, v6) bb2(v8:BasicObject, v9:BasicObject): v14:Fixnum[1] = Const Value(1) - v16:BasicObject = SendWithoutBlock v8, :foo, v14 + v16:BasicObject = SendWithoutBlock v8, :foo, v14 # SendFallbackReason: Uncategorized(opt_send_without_block) CheckInterrupts Return v16 "); @@ -1649,7 +1649,7 @@ pub mod hir_build_tests { EntryPoint JIT(0) Jump bb2(v5, v6) bb2(v8:BasicObject, v9:BasicObject): - v15:BasicObject = SendWithoutBlock v8, :foo, v9 + v15:BasicObject = SendWithoutBlock v8, :foo, v9 # SendFallbackReason: Uncategorized(opt_send_without_block) CheckInterrupts Return v15 "); @@ -1672,7 +1672,7 @@ pub mod hir_build_tests { EntryPoint JIT(0) Jump bb2(v4) bb2(v6:BasicObject): - v11:BasicObject = InvokeSuper v6, 0x1000 + v11:BasicObject = InvokeSuper v6, 0x1000 # SendFallbackReason: Uncategorized(invokesuper) CheckInterrupts Return v11 "); @@ -1693,7 +1693,7 @@ pub mod hir_build_tests { EntryPoint JIT(0) Jump bb2(v4) bb2(v6:BasicObject): - v11:BasicObject = InvokeSuper v6, 0x1000 + v11:BasicObject = InvokeSuper v6, 0x1000 # SendFallbackReason: Uncategorized(invokesuper) CheckInterrupts Return v11 "); @@ -1715,7 +1715,7 @@ pub mod hir_build_tests { Jump bb2(v4) bb2(v6:BasicObject): v11:NilClass = Const Value(nil) - v13:BasicObject = InvokeSuper v6, 0x1000, v11 + v13:BasicObject = InvokeSuper v6, 0x1000, v11 # SendFallbackReason: Uncategorized(invokesuper) CheckInterrupts Return v13 "); @@ -1782,12 +1782,12 @@ pub mod hir_build_tests { v14:Class[VMFrozenCore] = Const Value(VALUE(0x1000)) v16:HashExact = NewHash PatchPoint NoEPEscape(test) - v21:BasicObject = SendWithoutBlock v14, :core#hash_merge_kwd, v16, v9 + v21:BasicObject = SendWithoutBlock v14, :core#hash_merge_kwd, v16, v9 # SendFallbackReason: Uncategorized(opt_send_without_block) v23:Class[VMFrozenCore] = Const Value(VALUE(0x1000)) v26:StaticSymbol[:b] = Const Value(VALUE(0x1008)) v28:Fixnum[1] = Const Value(1) - v30:BasicObject = SendWithoutBlock v23, :core#hash_merge_ptr, v21, v26, v28 - v32:BasicObject = SendWithoutBlock v8, :foo, v30 + v30:BasicObject = SendWithoutBlock v23, :core#hash_merge_ptr, v21, v26, v28 # SendFallbackReason: Uncategorized(opt_send_without_block) + v32:BasicObject = SendWithoutBlock v8, :foo, v30 # SendFallbackReason: Uncategorized(opt_send_without_block) CheckInterrupts Return v32 "); @@ -1812,7 +1812,7 @@ pub mod hir_build_tests { v15:ArrayExact = ToNewArray v9 v17:Fixnum[1] = Const Value(1) ArrayPush v15, v17 - v21:BasicObject = SendWithoutBlock v8, :foo, v15 + v21:BasicObject = SendWithoutBlock v8, :foo, v15 # SendFallbackReason: Uncategorized(opt_send_without_block) CheckInterrupts Return v21 "); @@ -1834,7 +1834,7 @@ pub mod hir_build_tests { EntryPoint JIT(0) Jump bb2(v5, v6) bb2(v8:BasicObject, v9:BasicObject): - v15:BasicObject = SendForward v8, 0x1000, :foo, v9 + v15:BasicObject = SendForward v8, 0x1000, :foo, v9 # SendFallbackReason: Uncategorized(sendforward) CheckInterrupts Return v15 "); @@ -1891,11 +1891,11 @@ pub mod hir_build_tests { v16:CBool = IsMethodCFunc v11, :new IfFalse v16, bb3(v6, v13, v11) v18:HeapBasicObject = ObjectAlloc v11 - v20:BasicObject = SendWithoutBlock v18, :initialize + v20:BasicObject = SendWithoutBlock v18, :initialize # SendFallbackReason: Uncategorized(opt_send_without_block) CheckInterrupts Jump bb4(v6, v18, v20) bb3(v24:BasicObject, v25:NilClass, v26:BasicObject): - v29:BasicObject = SendWithoutBlock v26, :new + v29:BasicObject = SendWithoutBlock v26, :new # SendFallbackReason: Uncategorized(opt_send_without_block) Jump bb4(v24, v29, v25) bb4(v32:BasicObject, v33:BasicObject, v34:BasicObject): CheckInterrupts @@ -2008,7 +2008,7 @@ pub mod hir_build_tests { v12:NilClass = Const Value(nil) Jump bb2(v8, v9, v10, v11, v12) bb2(v14:BasicObject, v15:BasicObject, v16:BasicObject, v17:NilClass, v18:NilClass): - v25:BasicObject = SendWithoutBlock v15, :+, v16 + v25:BasicObject = SendWithoutBlock v15, :+, v16 # SendFallbackReason: Uncategorized(opt_plus) SideExit UnhandledNewarraySend(MIN) "); } @@ -2040,13 +2040,13 @@ pub mod hir_build_tests { v12:NilClass = Const Value(nil) Jump bb2(v8, v9, v10, v11, v12) bb2(v14:BasicObject, v15:BasicObject, v16:BasicObject, v17:NilClass, v18:NilClass): - v25:BasicObject = SendWithoutBlock v15, :+, v16 + v25:BasicObject = SendWithoutBlock v15, :+, v16 # SendFallbackReason: Uncategorized(opt_plus) PatchPoint BOPRedefined(ARRAY_REDEFINED_OP_FLAG, BOP_HASH) v32:Fixnum = ArrayHash v15, v16 PatchPoint NoEPEscape(test) v39:ArrayExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) v40:ArrayExact = ArrayDup v39 - v42:BasicObject = SendWithoutBlock v14, :puts, v40 + v42:BasicObject = SendWithoutBlock v14, :puts, v40 # SendFallbackReason: Uncategorized(opt_send_without_block) PatchPoint NoEPEscape(test) CheckInterrupts Return v32 @@ -2082,7 +2082,7 @@ pub mod hir_build_tests { v12:NilClass = Const Value(nil) Jump bb2(v8, v9, v10, v11, v12) bb2(v14:BasicObject, v15:BasicObject, v16:BasicObject, v17:NilClass, v18:NilClass): - v25:BasicObject = SendWithoutBlock v15, :+, v16 + v25:BasicObject = SendWithoutBlock v15, :+, v16 # SendFallbackReason: Uncategorized(opt_plus) SideExit PatchPoint(BOPRedefined(ARRAY_REDEFINED_OP_FLAG, BOP_HASH)) "); } @@ -2114,7 +2114,7 @@ pub mod hir_build_tests { v12:NilClass = Const Value(nil) Jump bb2(v8, v9, v10, v11, v12) bb2(v14:BasicObject, v15:BasicObject, v16:BasicObject, v17:NilClass, v18:NilClass): - v25:BasicObject = SendWithoutBlock v15, :+, v16 + v25:BasicObject = SendWithoutBlock v15, :+, v16 # SendFallbackReason: Uncategorized(opt_plus) v31:StringExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) v32:StringExact = StringCopy v31 SideExit UnhandledNewarraySend(PACK) @@ -2148,7 +2148,7 @@ pub mod hir_build_tests { v12:NilClass = Const Value(nil) Jump bb2(v8, v9, v10, v11, v12) bb2(v14:BasicObject, v15:BasicObject, v16:BasicObject, v17:NilClass, v18:NilClass): - v25:BasicObject = SendWithoutBlock v15, :+, v16 + v25:BasicObject = SendWithoutBlock v15, :+, v16 # SendFallbackReason: Uncategorized(opt_plus) v29:StringExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) v30:StringExact = StringCopy v29 v36:StringExact[VALUE(0x1008)] = Const Value(VALUE(0x1008)) @@ -2192,7 +2192,7 @@ pub mod hir_build_tests { v12:NilClass = Const Value(nil) Jump bb2(v8, v9, v10, v11, v12) bb2(v14:BasicObject, v15:BasicObject, v16:BasicObject, v17:NilClass, v18:NilClass): - v25:BasicObject = SendWithoutBlock v15, :+, v16 + v25:BasicObject = SendWithoutBlock v15, :+, v16 # SendFallbackReason: Uncategorized(opt_plus) v29:StringExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) v30:StringExact = StringCopy v29 v36:StringExact[VALUE(0x1008)] = Const Value(VALUE(0x1008)) @@ -2229,13 +2229,13 @@ pub mod hir_build_tests { v12:NilClass = Const Value(nil) Jump bb2(v8, v9, v10, v11, v12) bb2(v14:BasicObject, v15:BasicObject, v16:BasicObject, v17:NilClass, v18:NilClass): - v25:BasicObject = SendWithoutBlock v15, :+, v16 + v25:BasicObject = SendWithoutBlock v15, :+, v16 # SendFallbackReason: Uncategorized(opt_plus) PatchPoint BOPRedefined(ARRAY_REDEFINED_OP_FLAG, BOP_INCLUDE_P) v33:BoolExact = ArrayInclude v15, v16 | v16 PatchPoint NoEPEscape(test) v40:ArrayExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) v41:ArrayExact = ArrayDup v40 - v43:BasicObject = SendWithoutBlock v14, :puts, v41 + v43:BasicObject = SendWithoutBlock v14, :puts, v41 # SendFallbackReason: Uncategorized(opt_send_without_block) PatchPoint NoEPEscape(test) CheckInterrupts Return v33 @@ -2276,7 +2276,7 @@ pub mod hir_build_tests { v12:NilClass = Const Value(nil) Jump bb2(v8, v9, v10, v11, v12) bb2(v14:BasicObject, v15:BasicObject, v16:BasicObject, v17:NilClass, v18:NilClass): - v25:BasicObject = SendWithoutBlock v15, :+, v16 + v25:BasicObject = SendWithoutBlock v15, :+, v16 # SendFallbackReason: Uncategorized(opt_plus) SideExit PatchPoint(BOPRedefined(ARRAY_REDEFINED_OP_FLAG, BOP_INCLUDE_P)) "); } @@ -2355,7 +2355,7 @@ pub mod hir_build_tests { Jump bb2(v6, v7, v8) bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): v18:ArrayExact = NewArray v11, v12 - v21:BasicObject = SendWithoutBlock v18, :length + v21:BasicObject = SendWithoutBlock v18, :length # SendFallbackReason: Uncategorized(opt_length) CheckInterrupts Return v21 "); @@ -2380,7 +2380,7 @@ pub mod hir_build_tests { Jump bb2(v6, v7, v8) bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): v18:ArrayExact = NewArray v11, v12 - v21:BasicObject = SendWithoutBlock v18, :size + v21:BasicObject = SendWithoutBlock v18, :size # SendFallbackReason: Uncategorized(opt_size) CheckInterrupts Return v21 "); @@ -2685,7 +2685,7 @@ pub mod hir_build_tests { bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): v16:NilClass = Const Value(nil) v20:Fixnum[1] = Const Value(1) - v24:BasicObject = SendWithoutBlock v11, :[]=, v12, v20 + v24:BasicObject = SendWithoutBlock v11, :[]=, v12, v20 # SendFallbackReason: Uncategorized(opt_aset) CheckInterrupts Return v20 "); @@ -2709,7 +2709,7 @@ pub mod hir_build_tests { EntryPoint JIT(0) Jump bb2(v6, v7, v8) bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): - v19:BasicObject = SendWithoutBlock v11, :[], v12 + v19:BasicObject = SendWithoutBlock v11, :[], v12 # SendFallbackReason: Uncategorized(opt_aref) CheckInterrupts Return v19 "); @@ -2732,7 +2732,7 @@ pub mod hir_build_tests { EntryPoint JIT(0) Jump bb2(v5, v6) bb2(v8:BasicObject, v9:BasicObject): - v15:BasicObject = SendWithoutBlock v9, :empty? + v15:BasicObject = SendWithoutBlock v9, :empty? # SendFallbackReason: Uncategorized(opt_empty_p) CheckInterrupts Return v15 "); @@ -2755,7 +2755,7 @@ pub mod hir_build_tests { EntryPoint JIT(0) Jump bb2(v5, v6) bb2(v8:BasicObject, v9:BasicObject): - v15:BasicObject = SendWithoutBlock v9, :succ + v15:BasicObject = SendWithoutBlock v9, :succ # SendFallbackReason: Uncategorized(opt_succ) CheckInterrupts Return v15 "); @@ -2779,7 +2779,7 @@ pub mod hir_build_tests { EntryPoint JIT(0) Jump bb2(v6, v7, v8) bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): - v19:BasicObject = SendWithoutBlock v11, :&, v12 + v19:BasicObject = SendWithoutBlock v11, :&, v12 # SendFallbackReason: Uncategorized(opt_and) CheckInterrupts Return v19 "); @@ -2803,7 +2803,7 @@ pub mod hir_build_tests { EntryPoint JIT(0) Jump bb2(v6, v7, v8) bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): - v19:BasicObject = SendWithoutBlock v11, :|, v12 + v19:BasicObject = SendWithoutBlock v11, :|, v12 # SendFallbackReason: Uncategorized(opt_or) CheckInterrupts Return v19 "); @@ -2826,7 +2826,7 @@ pub mod hir_build_tests { EntryPoint JIT(0) Jump bb2(v5, v6) bb2(v8:BasicObject, v9:BasicObject): - v15:BasicObject = SendWithoutBlock v9, :! + v15:BasicObject = SendWithoutBlock v9, :! # SendFallbackReason: Uncategorized(opt_not) CheckInterrupts Return v15 "); @@ -2850,7 +2850,7 @@ pub mod hir_build_tests { EntryPoint JIT(0) Jump bb2(v6, v7, v8) bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): - v19:BasicObject = SendWithoutBlock v11, :=~, v12 + v19:BasicObject = SendWithoutBlock v11, :=~, v12 # SendFallbackReason: Uncategorized(opt_regexpmatch2) CheckInterrupts Return v19 "); @@ -2880,7 +2880,7 @@ pub mod hir_build_tests { v12:BasicObject = PutSpecialObject CBase v14:StaticSymbol[:aliased] = Const Value(VALUE(0x1008)) v16:StaticSymbol[:__callee__] = Const Value(VALUE(0x1010)) - v18:BasicObject = SendWithoutBlock v10, :core#set_method_alias, v12, v14, v16 + v18:BasicObject = SendWithoutBlock v10, :core#set_method_alias, v12, v14, v16 # SendFallbackReason: Uncategorized(opt_send_without_block) CheckInterrupts Return v18 "); @@ -2980,7 +2980,7 @@ pub mod hir_build_tests { CheckInterrupts v16:CBool = IsNil v9 IfTrue v16, bb3(v8, v9, v9) - v19:BasicObject = SendWithoutBlock v9, :itself + v19:BasicObject = SendWithoutBlock v9, :itself # SendFallbackReason: Uncategorized(opt_send_without_block) Jump bb3(v8, v9, v19) bb3(v21:BasicObject, v22:BasicObject, v23:BasicObject): CheckInterrupts @@ -3065,7 +3065,7 @@ pub mod hir_build_tests { v35:CBool[true] = Test v32 IfFalse v35, bb3(v16, v17, v18, v19, v20, v25) PatchPoint NoEPEscape(open) - v42:BasicObject = InvokeBlock, v25 + v42:BasicObject = InvokeBlock, v25 # SendFallbackReason: Uncategorized(invokeblock) v45:BasicObject = InvokeBuiltin dir_s_close, v16, v25 CheckInterrupts Return v42 @@ -3190,12 +3190,12 @@ pub mod hir_build_tests { v13:NilClass = Const Value(nil) v16:Fixnum[0] = Const Value(0) v18:Fixnum[1] = Const Value(1) - v21:BasicObject = SendWithoutBlock v9, :[], v16, v18 + v21:BasicObject = SendWithoutBlock v9, :[], v16, v18 # SendFallbackReason: Uncategorized(opt_send_without_block) CheckInterrupts v25:CBool = Test v21 IfTrue v25, bb3(v8, v9, v13, v9, v16, v18, v21) v29:Fixnum[2] = Const Value(2) - v32:BasicObject = SendWithoutBlock v9, :[]=, v16, v18, v29 + v32:BasicObject = SendWithoutBlock v9, :[]=, v16, v18, v29 # SendFallbackReason: Uncategorized(opt_send_without_block) CheckInterrupts Return v29 bb3(v38:BasicObject, v39:BasicObject, v40:NilClass, v41:BasicObject, v42:Fixnum[0], v43:Fixnum[1], v44:BasicObject): @@ -3398,7 +3398,7 @@ pub mod hir_build_tests { EntryPoint JIT(0) Jump bb2(v4) bb2(v6:BasicObject): - v10:BasicObject = InvokeBlock + v10:BasicObject = InvokeBlock # SendFallbackReason: Uncategorized(invokeblock) CheckInterrupts Return v10 "); @@ -3423,7 +3423,7 @@ pub mod hir_build_tests { EntryPoint JIT(0) Jump bb2(v6, v7, v8) bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): - v18:BasicObject = InvokeBlock, v11, v12 + v18:BasicObject = InvokeBlock, v11, v12 # SendFallbackReason: Uncategorized(invokeblock) CheckInterrupts Return v18 "); @@ -3547,7 +3547,7 @@ pub mod hir_build_tests { IfTrue v19, bb3(v10, v11, v12) v22:Fixnum[1] = Const Value(1) v24:Fixnum[1] = Const Value(1) - v27:BasicObject = SendWithoutBlock v22, :+, v24 + v27:BasicObject = SendWithoutBlock v22, :+, v24 # SendFallbackReason: Uncategorized(opt_plus) PatchPoint NoEPEscape(test) Jump bb3(v10, v27, v12) bb3(v32:BasicObject, v33:BasicObject, v34:BasicObject): diff --git a/zjit/src/options.rs b/zjit/src/options.rs index b7e2c71cefcd65..ea9dc3249b82ff 100644 --- a/zjit/src/options.rs +++ b/zjit/src/options.rs @@ -51,6 +51,9 @@ pub struct Options { /// Print stats on exit (when stats is also true) pub print_stats: bool, + /// Print stats to file on exit (when stats is also true) + pub print_stats_file: Option, + /// Enable debug logging pub debug: bool, @@ -103,6 +106,7 @@ impl Default for Options { num_profiles: DEFAULT_NUM_PROFILES, stats: false, print_stats: false, + print_stats_file: None, debug: false, disable: false, disable_hir_opt: false, @@ -131,7 +135,10 @@ pub const ZJIT_OPTIONS: &[(&str, &str)] = &[ "Number of calls to trigger JIT (default: 30)."), ("--zjit-num-profiles=num", "Number of profiled calls before JIT (default: 5)."), - ("--zjit-stats[=quiet]", "Enable collecting ZJIT statistics (=quiet to suppress output)."), + ("--zjit-stats-quiet", + "Collect ZJIT stats and suppress output."), + ("--zjit-stats[=file]", + "Collect ZJIT stats (=file to write to a file)."), ("--zjit-disable", "Disable ZJIT for lazily enabling it with RubyVM::ZJIT.enable."), ("--zjit-perf", "Dump ISEQ symbols into /tmp/perf-{}.map for Linux perf."), @@ -303,13 +310,28 @@ fn parse_option(str_ptr: *const std::os::raw::c_char) -> Option<()> { Err(_) => return None, }, + + ("stats-quiet", _) => { + options.stats = true; + options.print_stats = false; + } + ("stats", "") => { options.stats = true; options.print_stats = true; } - ("stats", "quiet") => { + ("stats", path) => { + // Truncate the file if it exists + std::fs::OpenOptions::new() + .create(true) + .write(true) + .truncate(true) + .open(path) + .map_err(|e| eprintln!("Failed to open file '{}': {}", path, e)) + .ok(); + let canonical_path = std::fs::canonicalize(opt_val).unwrap_or_else(|_| opt_val.into()); options.stats = true; - options.print_stats = false; + options.print_stats_file = Some(canonical_path); } ("trace-exits", exits) => { @@ -488,3 +510,14 @@ pub extern "C" fn rb_zjit_print_stats_p(_ec: EcPtr, _self: VALUE) -> VALUE { Qfalse } } + +/// Return path if stats should be printed at exit to a specified file, else Qnil. +#[unsafe(no_mangle)] +pub extern "C" fn rb_zjit_get_stats_file_path_p(_ec: EcPtr, _self: VALUE) -> VALUE { + if let Some(opts) = unsafe { OPTIONS.as_ref() } { + if let Some(ref path) = opts.print_stats_file { + return rust_str_to_ruby(path.as_os_str().to_str().unwrap()); + } + } + Qnil +}