From de92dd9a63f2065253cee082e3408de935313acd Mon Sep 17 00:00:00 2001 From: Max Bernstein Date: Wed, 24 Sep 2025 16:54:23 -0400 Subject: [PATCH 1/4] ZJIT: Add Ruby class objects to HIR type lattice automatically (#14647) This: * gets us out of the business of manually writing a bunch of `if`s * gets us more type information * cleans up the code * also adds `types::Numeric` --- zjit/src/hir.rs | 41 ++++---- zjit/src/hir_type/gen_hir_type.rb | 54 +++++++---- zjit/src/hir_type/hir_type.inc.rs | 64 +++++++++---- zjit/src/hir_type/mod.rs | 154 +++++++++++++----------------- 4 files changed, 171 insertions(+), 142 deletions(-) diff --git a/zjit/src/hir.rs b/zjit/src/hir.rs index 6e3fd78e0a8945..e5286cd5e099a4 100644 --- a/zjit/src/hir.rs +++ b/zjit/src/hir.rs @@ -829,7 +829,10 @@ impl<'a> std::fmt::Display for InsnPrinter<'a> { Insn::ArrayDup { val, .. } => { write!(f, "ArrayDup {val}") } Insn::HashDup { val, .. } => { write!(f, "HashDup {val}") } Insn::ObjectAlloc { val, .. } => { write!(f, "ObjectAlloc {val}") } - Insn::ObjectAllocClass { class, .. } => { write!(f, "ObjectAllocClass {}", class.print(self.ptr_map)) } + &Insn::ObjectAllocClass { class, .. } => { + let class_name = get_class_name(class); + write!(f, "ObjectAllocClass {class_name}:{}", class.print(self.ptr_map)) + } Insn::StringCopy { val, .. } => { write!(f, "StringCopy {val}") } Insn::StringConcat { strings, .. } => { write!(f, "StringConcat")?; @@ -5637,7 +5640,7 @@ mod tests { v10:ArrayExact = ToArray v2 PatchPoint NoEPEscape(test) GuardBlockParamProxy l0 - v15:BasicObject[BlockParamProxy] = Const Value(VALUE(0x1000)) + v15:HeapObject[BlockParamProxy] = Const Value(VALUE(0x1000)) SideExit UnhandledYARVInsn(splatkw) "); } @@ -6221,16 +6224,16 @@ mod tests { v10:BasicObject = InvokeBuiltin dir_s_open, v0, v1, v2 PatchPoint NoEPEscape(open) GuardBlockParamProxy l0 - v17:BasicObject[BlockParamProxy] = Const Value(VALUE(0x1000)) + v17:HeapObject[BlockParamProxy] = Const Value(VALUE(0x1000)) CheckInterrupts - v20:CBool = Test v17 + v20:CBool[true] = Test v17 IfFalse v20, bb1(v0, v1, v2, v3, v4, v10) PatchPoint NoEPEscape(open) v27:BasicObject = InvokeBlock, v10 v31:BasicObject = InvokeBuiltin dir_s_close, v0, v10 CheckInterrupts Return v27 - bb1(v37:BasicObject, v38:BasicObject, v39:BasicObject, v40:BasicObject, v41:BasicObject, v42:BasicObject): + bb1(v37, v38, v39, v40, v41, v42): PatchPoint NoEPEscape(open) CheckInterrupts Return v42 @@ -8033,7 +8036,7 @@ mod opt_tests { bb0(v0:BasicObject): PatchPoint SingleRactorMode PatchPoint StableConstantNames(0x1000, MY_MODULE) - v13:BasicObject[VALUE(0x1008)] = Const Value(VALUE(0x1008)) + v13:HeapObject[VALUE(0x1008)] = Const Value(VALUE(0x1008)) CheckInterrupts Return v13 "); @@ -8378,7 +8381,7 @@ mod opt_tests { v34:Class[VALUE(0x1008)] = Const Value(VALUE(0x1008)) v6:NilClass = Const Value(nil) PatchPoint MethodRedefined(C@0x1008, new@0x1010, cme:0x1018) - v37:HeapObject[class_exact:C] = ObjectAllocClass VALUE(0x1008) + v37:HeapObject[class_exact:C] = ObjectAllocClass C:VALUE(0x1008) PatchPoint MethodRedefined(C@0x1008, initialize@0x1040, cme:0x1048) v39:NilClass = CCall initialize@0x1070, v37 CheckInterrupts @@ -8407,7 +8410,7 @@ mod opt_tests { v6:NilClass = Const Value(nil) v7:Fixnum[1] = Const Value(1) PatchPoint MethodRedefined(C@0x1008, new@0x1010, cme:0x1018) - v39:HeapObject[class_exact:C] = ObjectAllocClass VALUE(0x1008) + v39:HeapObject[class_exact:C] = ObjectAllocClass C:VALUE(0x1008) PatchPoint MethodRedefined(C@0x1008, initialize@0x1040, cme:0x1048) v41:BasicObject = SendWithoutBlockDirect v39, :initialize (0x1070), v7 CheckInterrupts @@ -8430,7 +8433,7 @@ mod opt_tests { v34:Class[VALUE(0x1008)] = Const Value(VALUE(0x1008)) v6:NilClass = Const Value(nil) PatchPoint MethodRedefined(Object@0x1008, new@0x1010, cme:0x1018) - v37:HeapObject[class_exact:Object] = ObjectAllocClass VALUE(0x1008) + v37:ObjectExact = ObjectAllocClass Object:VALUE(0x1008) PatchPoint MethodRedefined(Object@0x1008, initialize@0x1040, cme:0x1048) v39:NilClass = CCall initialize@0x1070, v37 CheckInterrupts @@ -8453,7 +8456,7 @@ mod opt_tests { v34:Class[VALUE(0x1008)] = Const Value(VALUE(0x1008)) v6:NilClass = Const Value(nil) PatchPoint MethodRedefined(BasicObject@0x1008, new@0x1010, cme:0x1018) - v37:HeapObject[class_exact:BasicObject] = ObjectAllocClass VALUE(0x1008) + v37:BasicObjectExact = ObjectAllocClass BasicObject:VALUE(0x1008) PatchPoint MethodRedefined(BasicObject@0x1008, initialize@0x1040, cme:0x1048) v39:NilClass = CCall initialize@0x1070, v37 CheckInterrupts @@ -8476,7 +8479,7 @@ mod opt_tests { v34:Class[VALUE(0x1008)] = Const Value(VALUE(0x1008)) v6:NilClass = Const Value(nil) PatchPoint MethodRedefined(Hash@0x1008, new@0x1010, cme:0x1018) - v37:HashExact = ObjectAllocClass VALUE(0x1008) + v37:HashExact = ObjectAllocClass Hash:VALUE(0x1008) v12:BasicObject = SendWithoutBlock v37, :initialize CheckInterrupts CheckInterrupts @@ -8523,7 +8526,7 @@ mod opt_tests { PatchPoint MethodRedefined(Set@0x1008, new@0x1010, cme:0x1018) v10:HeapObject = ObjectAlloc v34 PatchPoint MethodRedefined(Set@0x1008, initialize@0x1040, cme:0x1048) - v39:HeapObject[class_exact:Set] = GuardType v10, HeapObject[class_exact:Set] + v39:SetExact = GuardType v10, SetExact v40:BasicObject = CCallVariadic initialize@0x1070, v39 CheckInterrupts CheckInterrupts @@ -8568,7 +8571,7 @@ mod opt_tests { v7:StringExact[VALUE(0x1010)] = Const Value(VALUE(0x1010)) v9:StringExact = StringCopy v7 PatchPoint MethodRedefined(Regexp@0x1008, new@0x1018, cme:0x1020) - v41:HeapObject[class_exact:Regexp] = ObjectAllocClass VALUE(0x1008) + v41:RegexpExact = ObjectAllocClass Regexp:VALUE(0x1008) PatchPoint MethodRedefined(Regexp@0x1008, initialize@0x1048, cme:0x1050) v44:BasicObject = CCallVariadic initialize@0x1078, v41, v9 CheckInterrupts @@ -8618,7 +8621,7 @@ mod opt_tests { fn test@:2: bb0(v0:BasicObject, v1:BasicObject): GuardBlockParamProxy l0 - v7:BasicObject[BlockParamProxy] = Const Value(VALUE(0x1000)) + v7:HeapObject[BlockParamProxy] = Const Value(VALUE(0x1000)) v9:BasicObject = Send v0, 0x1008, :tap, v7 CheckInterrupts Return v9 @@ -9632,10 +9635,9 @@ mod opt_tests { bb0(v0:BasicObject): PatchPoint SingleRactorMode PatchPoint StableConstantNames(0x1000, O) - v15:BasicObject[VALUE(0x1008)] = Const Value(VALUE(0x1008)) + v15:HeapObject[VALUE(0x1008)] = Const Value(VALUE(0x1008)) PatchPoint MethodRedefined(C@0x1010, foo@0x1018, cme:0x1020) - v18:HeapObject[VALUE(0x1008)] = GuardType v15, HeapObject - v19:HeapObject[VALUE(0x1008)] = GuardShape v18, 0x1048 + v19:HeapObject[VALUE(0x1008)] = GuardShape v15, 0x1048 v20:NilClass = Const Value(nil) CheckInterrupts Return v20 @@ -9659,10 +9661,9 @@ mod opt_tests { bb0(v0:BasicObject): PatchPoint SingleRactorMode PatchPoint StableConstantNames(0x1000, O) - v15:BasicObject[VALUE(0x1008)] = Const Value(VALUE(0x1008)) + v15:HeapObject[VALUE(0x1008)] = Const Value(VALUE(0x1008)) PatchPoint MethodRedefined(C@0x1010, foo@0x1018, cme:0x1020) - v18:HeapObject[VALUE(0x1008)] = GuardType v15, HeapObject - v19:HeapObject[VALUE(0x1008)] = GuardShape v18, 0x1048 + v19:HeapObject[VALUE(0x1008)] = GuardShape v15, 0x1048 v20:NilClass = Const Value(nil) CheckInterrupts Return v20 diff --git a/zjit/src/hir_type/gen_hir_type.rb b/zjit/src/hir_type/gen_hir_type.rb index 15aa68a6004c86..1ab6adf2eb16f1 100644 --- a/zjit/src/hir_type/gen_hir_type.rb +++ b/zjit/src/hir_type/gen_hir_type.rb @@ -58,10 +58,19 @@ def to_graphviz type $subclass = [basic_object_subclass.name, object_subclass.name] $builtin_exact = [basic_object_exact.name, object_exact.name] +$c_names = { + "ObjectExact" => "rb_cObject", + "BasicObjectExact" => "rb_cBasicObject", +} + # Define a new type that can be subclassed (most of them). -def base_type name +# If c_name is given, mark the rb_cXYZ object as equivalent to this exact type. +def base_type name, c_name: nil type = $object.subtype name exact = type.subtype(name+"Exact") + if c_name + $c_names[exact.name] = c_name + end subclass = type.subtype(name+"Subclass") $builtin_exact << exact.name $subclass << subclass.name @@ -69,39 +78,45 @@ def base_type name end # Define a new type that cannot be subclassed. -def final_type name - type = $object.subtype name +# If c_name is given, mark the rb_cXYZ object as equivalent to this type. +def final_type name, base: $object, c_name: nil + if c_name + $c_names[name] = c_name + end + type = base.subtype name $builtin_exact << type.name type end -base_type "String" -base_type "Array" -base_type "Hash" -base_type "Range" -base_type "Set" -base_type "Regexp" -module_class, _ = base_type "Module" -module_class.subtype "Class" +base_type "String", c_name: "rb_cString" +base_type "Array", c_name: "rb_cArray" +base_type "Hash", c_name: "rb_cHash" +base_type "Range", c_name: "rb_cRange" +base_type "Set", c_name: "rb_cSet" +base_type "Regexp", c_name: "rb_cRegexp" +module_class, _ = base_type "Module", c_name: "rb_cModule" +class_ = final_type "Class", base: module_class, c_name: "rb_cClass" + +numeric, _ = base_type "Numeric", c_name: "rb_cNumeric" -integer_exact = final_type "Integer" +integer_exact = final_type "Integer", base: numeric, c_name: "rb_cInteger" # CRuby partitions Integer into immediate and non-immediate variants. fixnum = integer_exact.subtype "Fixnum" integer_exact.subtype "Bignum" -float_exact = final_type "Float" +float_exact = final_type "Float", base: numeric, c_name: "rb_cFloat" # CRuby partitions Float into immediate and non-immediate variants. flonum = float_exact.subtype "Flonum" float_exact.subtype "HeapFloat" -symbol_exact = final_type "Symbol" +symbol_exact = final_type "Symbol", c_name: "rb_cSymbol" # CRuby partitions Symbol into immediate and non-immediate variants. static_sym = symbol_exact.subtype "StaticSymbol" symbol_exact.subtype "DynamicSymbol" -nil_exact = final_type "NilClass" -true_exact = final_type "TrueClass" -false_exact = final_type "FalseClass" +nil_exact = final_type "NilClass", c_name: "rb_cNilClass" +true_exact = final_type "TrueClass", c_name: "rb_cTrueClass" +false_exact = final_type "FalseClass", c_name: "rb_cFalseClass" # Build the cvalue object universe. This is for C-level types that may be # passed around when calling into the Ruby VM or after some strength reduction @@ -183,4 +198,9 @@ def add_union name, type_names $bits.keys.sort.map {|type_name| puts " pub const #{type_name}: Type = Type::from_bits(bits::#{type_name});" } +puts " pub const ExactBitsAndClass: [(u64, *const VALUE); #{$c_names.size}] = [" +$c_names.each {|type_name, c_name| + puts " (bits::#{type_name}, &raw const crate::cruby::#{c_name})," +} +puts " ];" puts "}" diff --git a/zjit/src/hir_type/hir_type.inc.rs b/zjit/src/hir_type/hir_type.inc.rs index 2e03fdac96b8fc..c392735742d386 100644 --- a/zjit/src/hir_type/hir_type.inc.rs +++ b/zjit/src/hir_type/hir_type.inc.rs @@ -9,7 +9,7 @@ mod bits { pub const BasicObjectSubclass: u64 = 1u64 << 3; pub const Bignum: u64 = 1u64 << 4; pub const BoolExact: u64 = FalseClass | TrueClass; - pub const BuiltinExact: u64 = ArrayExact | BasicObjectExact | FalseClass | Float | HashExact | Integer | ModuleExact | NilClass | ObjectExact | RangeExact | RegexpExact | SetExact | StringExact | Symbol | TrueClass; + pub const BuiltinExact: u64 = ArrayExact | BasicObjectExact | Class | FalseClass | Float | HashExact | Integer | ModuleExact | NilClass | NumericExact | ObjectExact | RangeExact | RegexpExact | SetExact | StringExact | Symbol | TrueClass; pub const CBool: u64 = 1u64 << 5; pub const CDouble: u64 = 1u64 << 6; pub const CInt: u64 = CSigned | CUnsigned; @@ -45,28 +45,31 @@ mod bits { pub const ModuleExact: u64 = 1u64 << 26; pub const ModuleSubclass: u64 = 1u64 << 27; pub const NilClass: u64 = 1u64 << 28; - pub const Object: u64 = Array | FalseClass | Float | Hash | Integer | Module | NilClass | ObjectExact | ObjectSubclass | Range | Regexp | Set | String | Symbol | TrueClass; - pub const ObjectExact: u64 = 1u64 << 29; - pub const ObjectSubclass: u64 = 1u64 << 30; + pub const Numeric: u64 = Float | Integer | NumericExact | NumericSubclass; + pub const NumericExact: u64 = 1u64 << 29; + pub const NumericSubclass: u64 = 1u64 << 30; + pub const Object: u64 = Array | FalseClass | Hash | Module | NilClass | Numeric | ObjectExact | ObjectSubclass | Range | Regexp | Set | String | Symbol | TrueClass; + pub const ObjectExact: u64 = 1u64 << 31; + pub const ObjectSubclass: u64 = 1u64 << 32; pub const Range: u64 = RangeExact | RangeSubclass; - pub const RangeExact: u64 = 1u64 << 31; - pub const RangeSubclass: u64 = 1u64 << 32; + pub const RangeExact: u64 = 1u64 << 33; + pub const RangeSubclass: u64 = 1u64 << 34; pub const Regexp: u64 = RegexpExact | RegexpSubclass; - pub const RegexpExact: u64 = 1u64 << 33; - pub const RegexpSubclass: u64 = 1u64 << 34; + pub const RegexpExact: u64 = 1u64 << 35; + pub const RegexpSubclass: u64 = 1u64 << 36; pub const RubyValue: u64 = BasicObject | CallableMethodEntry | Undef; pub const Set: u64 = SetExact | SetSubclass; - pub const SetExact: u64 = 1u64 << 35; - pub const SetSubclass: u64 = 1u64 << 36; - pub const StaticSymbol: u64 = 1u64 << 37; + pub const SetExact: u64 = 1u64 << 37; + pub const SetSubclass: u64 = 1u64 << 38; + pub const StaticSymbol: u64 = 1u64 << 39; pub const String: u64 = StringExact | StringSubclass; - pub const StringExact: u64 = 1u64 << 38; - pub const StringSubclass: u64 = 1u64 << 39; - pub const Subclass: u64 = ArraySubclass | BasicObjectSubclass | HashSubclass | ModuleSubclass | ObjectSubclass | RangeSubclass | RegexpSubclass | SetSubclass | StringSubclass; + pub const StringExact: u64 = 1u64 << 40; + pub const StringSubclass: u64 = 1u64 << 41; + pub const Subclass: u64 = ArraySubclass | BasicObjectSubclass | HashSubclass | ModuleSubclass | NumericSubclass | ObjectSubclass | RangeSubclass | RegexpSubclass | SetSubclass | StringSubclass; pub const Symbol: u64 = DynamicSymbol | StaticSymbol; - pub const TrueClass: u64 = 1u64 << 40; - pub const Undef: u64 = 1u64 << 41; - pub const AllBitPatterns: [(&str, u64); 66] = [ + pub const TrueClass: u64 = 1u64 << 42; + pub const Undef: u64 = 1u64 << 43; + pub const AllBitPatterns: [(&'static str, u64); 69] = [ ("Any", Any), ("RubyValue", RubyValue), ("Immediate", Immediate), @@ -94,6 +97,9 @@ mod bits { ("RangeExact", RangeExact), ("ObjectSubclass", ObjectSubclass), ("ObjectExact", ObjectExact), + ("Numeric", Numeric), + ("NumericSubclass", NumericSubclass), + ("NumericExact", NumericExact), ("NilClass", NilClass), ("Module", Module), ("ModuleSubclass", ModuleSubclass), @@ -134,7 +140,7 @@ mod bits { ("ArrayExact", ArrayExact), ("Empty", Empty), ]; - pub const NumTypeBits: u64 = 42; + pub const NumTypeBits: u64 = 44; } pub mod types { use super::*; @@ -183,6 +189,9 @@ pub mod types { pub const ModuleExact: Type = Type::from_bits(bits::ModuleExact); pub const ModuleSubclass: Type = Type::from_bits(bits::ModuleSubclass); pub const NilClass: Type = Type::from_bits(bits::NilClass); + pub const Numeric: Type = Type::from_bits(bits::Numeric); + pub const NumericExact: Type = Type::from_bits(bits::NumericExact); + pub const NumericSubclass: Type = Type::from_bits(bits::NumericSubclass); pub const Object: Type = Type::from_bits(bits::Object); pub const ObjectExact: Type = Type::from_bits(bits::ObjectExact); pub const ObjectSubclass: Type = Type::from_bits(bits::ObjectSubclass); @@ -204,4 +213,23 @@ pub mod types { pub const Symbol: Type = Type::from_bits(bits::Symbol); pub const TrueClass: Type = Type::from_bits(bits::TrueClass); pub const Undef: Type = Type::from_bits(bits::Undef); + pub const ExactBitsAndClass: [(u64, *const VALUE); 17] = [ + (bits::ObjectExact, &raw const crate::cruby::rb_cObject), + (bits::BasicObjectExact, &raw const crate::cruby::rb_cBasicObject), + (bits::StringExact, &raw const crate::cruby::rb_cString), + (bits::ArrayExact, &raw const crate::cruby::rb_cArray), + (bits::HashExact, &raw const crate::cruby::rb_cHash), + (bits::RangeExact, &raw const crate::cruby::rb_cRange), + (bits::SetExact, &raw const crate::cruby::rb_cSet), + (bits::RegexpExact, &raw const crate::cruby::rb_cRegexp), + (bits::ModuleExact, &raw const crate::cruby::rb_cModule), + (bits::Class, &raw const crate::cruby::rb_cClass), + (bits::NumericExact, &raw const crate::cruby::rb_cNumeric), + (bits::Integer, &raw const crate::cruby::rb_cInteger), + (bits::Float, &raw const crate::cruby::rb_cFloat), + (bits::Symbol, &raw const crate::cruby::rb_cSymbol), + (bits::NilClass, &raw const crate::cruby::rb_cNilClass), + (bits::TrueClass, &raw const crate::cruby::rb_cTrueClass), + (bits::FalseClass, &raw const crate::cruby::rb_cFalseClass), + ]; } diff --git a/zjit/src/hir_type/mod.rs b/zjit/src/hir_type/mod.rs index f2fb8702570cf7..5478653a235b3d 100644 --- a/zjit/src/hir_type/mod.rs +++ b/zjit/src/hir_type/mod.rs @@ -2,7 +2,7 @@ #![allow(non_upper_case_globals)] use crate::cruby::{rb_block_param_proxy, Qfalse, Qnil, Qtrue, RUBY_T_ARRAY, RUBY_T_CLASS, RUBY_T_HASH, RUBY_T_MODULE, RUBY_T_STRING, VALUE}; -use crate::cruby::{rb_cInteger, rb_cFloat, rb_cArray, rb_cHash, rb_cString, rb_cSymbol, rb_cObject, rb_cTrueClass, rb_cFalseClass, rb_cNilClass, rb_cRange, rb_cSet, rb_cRegexp, rb_cClass, rb_cModule, rb_zjit_singleton_class_p}; +use crate::cruby::{rb_cInteger, rb_cFloat, rb_cArray, rb_cHash, rb_cString, rb_cSymbol, rb_cRange, rb_cModule, rb_zjit_singleton_class_p}; use crate::cruby::ClassRelationship; use crate::cruby::get_class_name; use crate::cruby::ruby_sym_to_rust_string; @@ -177,10 +177,43 @@ impl Type { } } + fn bits_from_exact_class(class: VALUE) -> Option { + types::ExactBitsAndClass + .iter() + .find(|&(_, class_object)| unsafe { **class_object } == class) + .map(|&(bits, _)| bits) + } + + fn from_heap_object(val: VALUE) -> Type { + assert!(!val.special_const_p(), "val should be a heap object"); + let bits = + // GC-hidden types + if is_array_exact(val) { bits::ArrayExact } + else if is_hash_exact(val) { bits::HashExact } + else if is_string_exact(val) { bits::StringExact } + // Singleton classes + else if is_module_exact(val) { bits::ModuleExact } + else if val.builtin_type() == RUBY_T_CLASS { bits::Class } + // Classes that have an immediate/heap split + else if val.class_of() == unsafe { rb_cInteger } { bits::Bignum } + else if val.class_of() == unsafe { rb_cFloat } { bits::HeapFloat } + else if val.class_of() == unsafe { rb_cSymbol } { bits::DynamicSymbol } + else { + Self::bits_from_exact_class(val.class_of()).unwrap_or({ + // We don't have a specific built-in bit pattern for this class, so generalize + // as HeapObject with object specialization. + bits::HeapObject + }) + }; + let spec = Specialization::Object(val); + Type { bits, spec } + } + /// Create a `Type` from a Ruby `VALUE`. The type is not guaranteed to have object /// specialization in its `specialization` field (for example, `Qnil` will just be /// `types::NilClass`), but will be available via `ruby_object()`. pub fn from_value(val: VALUE) -> Type { + // Immediates if val.fixnum_p() { Type { bits: bits::Fixnum, spec: Specialization::Object(val) } } @@ -199,45 +232,8 @@ impl Type { // valid on imemo. Type { bits: bits::CallableMethodEntry, spec: Specialization::Object(val) } } - else if val.class_of() == unsafe { rb_cInteger } { - Type { bits: bits::Bignum, spec: Specialization::Object(val) } - } - else if val.class_of() == unsafe { rb_cFloat } { - Type { bits: bits::HeapFloat, spec: Specialization::Object(val) } - } - else if val.class_of() == unsafe { rb_cSymbol } { - Type { bits: bits::DynamicSymbol, spec: Specialization::Object(val) } - } - else if is_array_exact(val) { - Type { bits: bits::ArrayExact, spec: Specialization::Object(val) } - } - else if is_hash_exact(val) { - Type { bits: bits::HashExact, spec: Specialization::Object(val) } - } - else if is_range_exact(val) { - Type { bits: bits::RangeExact, spec: Specialization::Object(val) } - } - else if is_string_exact(val) { - Type { bits: bits::StringExact, spec: Specialization::Object(val) } - } - else if is_module_exact(val) { - Type { bits: bits::ModuleExact, spec: Specialization::Object(val) } - } - else if val.builtin_type() == RUBY_T_CLASS { - Type { bits: bits::Class, spec: Specialization::Object(val) } - } - else if val.class_of() == unsafe { rb_cRegexp } { - Type { bits: bits::RegexpExact, spec: Specialization::Object(val) } - } - else if val.class_of() == unsafe { rb_cSet } { - Type { bits: bits::SetExact, spec: Specialization::Object(val) } - } - else if val.class_of() == unsafe { rb_cObject } { - Type { bits: bits::ObjectExact, spec: Specialization::Object(val) } - } else { - // TODO(max): Add more cases for inferring type bits from built-in types - Type { bits: bits::BasicObject, spec: Specialization::Object(val) } + Self::from_heap_object(val) } } @@ -248,26 +244,17 @@ impl Type { else if val.is_nil() { types::NilClass } else if val.is_true() { types::TrueClass } else if val.is_false() { types::FalseClass } - else if val.class() == unsafe { rb_cString } { types::StringExact } - else if val.class() == unsafe { rb_cArray } { types::ArrayExact } - else if val.class() == unsafe { rb_cHash } { types::HashExact } - else { - // TODO(max): Add more cases for inferring type bits from built-in types - Type { bits: bits::HeapObject, spec: Specialization::TypeExact(val.class()) } - } + else { Self::from_class(val.class()) } } pub fn from_class(class: VALUE) -> Type { - if class == unsafe { rb_cArray } { types::ArrayExact } - else if class == unsafe { rb_cFalseClass } { types::FalseClass } - else if class == unsafe { rb_cHash } { types::HashExact } - else if class == unsafe { rb_cInteger } { types::Integer} - else if class == unsafe { rb_cNilClass } { types::NilClass } - else if class == unsafe { rb_cString } { types::StringExact } - else if class == unsafe { rb_cTrueClass } { types::TrueClass } - else { - // TODO(max): Add more cases for inferring type bits from built-in types - Type { bits: bits::HeapObject, spec: Specialization::TypeExact(class) } + match Self::bits_from_exact_class(class) { + Some(bits) => Type::from_bits(bits), + None => { + // We don't have a specific built-in bit pattern for this class, so generalize + // as HeapObject with object specialization. + Type { bits: bits::HeapObject, spec: Specialization::TypeExact(class) } + } } } @@ -361,21 +348,10 @@ impl Type { } fn is_builtin(class: VALUE) -> bool { - if class == unsafe { rb_cArray } { return true; } - if class == unsafe { rb_cClass } { return true; } - if class == unsafe { rb_cFalseClass } { return true; } - if class == unsafe { rb_cFloat } { return true; } - if class == unsafe { rb_cHash } { return true; } - if class == unsafe { rb_cInteger } { return true; } - if class == unsafe { rb_cModule } { return true; } - if class == unsafe { rb_cNilClass } { return true; } - if class == unsafe { rb_cObject } { return true; } - if class == unsafe { rb_cRange } { return true; } - if class == unsafe { rb_cRegexp } { return true; } - if class == unsafe { rb_cString } { return true; } - if class == unsafe { rb_cSymbol } { return true; } - if class == unsafe { rb_cTrueClass } { return true; } - false + types::ExactBitsAndClass + .iter() + .find(|&(_, class_object)| unsafe { **class_object } == class) + .is_some() } /// Union both types together, preserving specialization if possible. @@ -471,22 +447,10 @@ impl Type { if let Some(val) = self.exact_ruby_class() { return Some(val); } - if self.is_subtype(types::ArrayExact) { return Some(unsafe { rb_cArray }); } - if self.is_subtype(types::Class) { return Some(unsafe { rb_cClass }); } - if self.is_subtype(types::FalseClass) { return Some(unsafe { rb_cFalseClass }); } - if self.is_subtype(types::Float) { return Some(unsafe { rb_cFloat }); } - if self.is_subtype(types::HashExact) { return Some(unsafe { rb_cHash }); } - if self.is_subtype(types::Integer) { return Some(unsafe { rb_cInteger }); } - if self.is_subtype(types::ModuleExact) { return Some(unsafe { rb_cModule }); } - if self.is_subtype(types::NilClass) { return Some(unsafe { rb_cNilClass }); } - if self.is_subtype(types::ObjectExact) { return Some(unsafe { rb_cObject }); } - if self.is_subtype(types::RangeExact) { return Some(unsafe { rb_cRange }); } - if self.is_subtype(types::RegexpExact) { return Some(unsafe { rb_cRegexp }); } - if self.is_subtype(types::SetExact) { return Some(unsafe { rb_cSet }); } - if self.is_subtype(types::StringExact) { return Some(unsafe { rb_cString }); } - if self.is_subtype(types::Symbol) { return Some(unsafe { rb_cSymbol }); } - if self.is_subtype(types::TrueClass) { return Some(unsafe { rb_cTrueClass }); } - None + types::ExactBitsAndClass + .iter() + .find(|&(bits, _)| self.is_subtype(Type::from_bits(*bits))) + .map(|&(_, class_object)| unsafe { *class_object }) } /// Check bit equality of two `Type`s. Do not use! You are probably looking for [`Type::is_subtype`]. @@ -534,6 +498,11 @@ mod tests { use crate::cruby::rb_hash_new; use crate::cruby::rb_float_new; use crate::cruby::define_class; + use crate::cruby::rb_cObject; + use crate::cruby::rb_cSet; + use crate::cruby::rb_cTrueClass; + use crate::cruby::rb_cFalseClass; + use crate::cruby::rb_cNilClass; #[track_caller] fn assert_bit_equal(left: Type, right: Type) { @@ -591,6 +560,17 @@ mod tests { assert_subtype(types::HeapFloat, types::Float); } + #[test] + fn numeric() { + assert_subtype(types::Integer, types::Numeric); + assert_subtype(types::Float, types::Numeric); + assert_subtype(types::Float.union(types::Integer), types::Numeric); + assert_bit_equal(types::Float + .union(types::Integer) + .union(types::NumericExact) + .union(types::NumericSubclass), types::Numeric); + } + #[test] fn symbol() { assert_subtype(types::StaticSymbol, types::Symbol); From 44d0b019548a26c289d60eb3699f75dc208e5481 Mon Sep 17 00:00:00 2001 From: Alan Wu Date: Wed, 24 Sep 2025 15:37:56 -0400 Subject: [PATCH 2/4] Don't require to set PC before allocating hidden object ZJIT doesn't set PC before rb_set_ivar(), and that allocates a managed ID table. Was a false positive from gc_validate_pc(). --- gc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gc.c b/gc.c index 507d24d21590a0..da74c24c3f5e54 100644 --- a/gc.c +++ b/gc.c @@ -974,9 +974,12 @@ static inline void gc_validate_pc(VALUE obj) { #if RUBY_DEBUG + // IMEMOs and objects without a class (e.g managed id table) are not traceable + if (RB_TYPE_P(obj, T_IMEMO) || !CLASS_OF(obj)) return; + rb_execution_context_t *ec = GET_EC(); const rb_control_frame_t *cfp = ec->cfp; - if (!RB_TYPE_P(obj, T_IMEMO) && cfp && VM_FRAME_RUBYFRAME_P(cfp) && cfp->pc) { + if (cfp && VM_FRAME_RUBYFRAME_P(cfp) && cfp->pc) { const VALUE *iseq_encoded = ISEQ_BODY(cfp->iseq)->iseq_encoded; const VALUE *iseq_encoded_end = iseq_encoded + ISEQ_BODY(cfp->iseq)->iseq_size; RUBY_ASSERT(cfp->pc >= iseq_encoded, "PC not set when allocating, breaking tracing"); From a5c98a7b263907e928a4076ec9daa8987b7db928 Mon Sep 17 00:00:00 2001 From: Takashi Kokubun Date: Wed, 24 Sep 2025 15:38:11 -0700 Subject: [PATCH 3/4] ZJIT: Incorporate bb0-prologue and PC check into HIR (#14643) * ZJIT: Incorporate bb0-prologue and PC check into HIR * Fix an outdated comment * Use shallow clone for LoadPC and EntryPoint * Reproduce the actual HIR graph to pass validation * Fill out param types for jit_entry_block * Add Type::from_cptr * Add a TODO comment about Const::CPtr printing --- test/ruby/test_zjit.rb | 7 +- zjit/src/backend/lir.rs | 9 +- zjit/src/codegen.rs | 120 +- zjit/src/gc.rs | 12 +- zjit/src/hir.rs | 4468 ++++++++++++++++++++++++++------------ zjit/src/hir_type/mod.rs | 7 +- zjit/src/stats.rs | 1 + 7 files changed, 3209 insertions(+), 1415 deletions(-) diff --git a/test/ruby/test_zjit.rb b/test/ruby/test_zjit.rb index 563be8c966e06c..564e62c070698f 100644 --- a/test/ruby/test_zjit.rb +++ b/test/ruby/test_zjit.rb @@ -540,7 +540,8 @@ def test end def test_invokebuiltin - assert_compiles '["."]', %q{ + # Not using assert_compiles due to register spill + assert_runs '["."]', %q{ def test = Dir.glob(".") test } @@ -1519,7 +1520,9 @@ def a(n1,n2,n3,n4,n5,n6,n7,n8) = [n8] def test_forty_param_method # This used to a trigger a miscomp on A64 due # to a memory displacement larger than 9 bits. - assert_compiles '1', %Q{ + # Using assert_runs again due to register spill. + # TODO: It should be fixed by register spill support. + assert_runs '1', %Q{ def foo(#{'_,' * 39} n40) = n40 foo(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1) diff --git a/zjit/src/backend/lir.rs b/zjit/src/backend/lir.rs index 21adc42cd1c753..e931e14e8f24e9 100644 --- a/zjit/src/backend/lir.rs +++ b/zjit/src/backend/lir.rs @@ -1607,9 +1607,12 @@ impl Assembler self.store(Opnd::mem(64, SP, (-local_size_and_idx_to_ep_offset(locals.len(), idx) - 1) * SIZEOF_VALUE_I32), opnd); } - asm_comment!(self, "save cfp->pc"); - self.load_into(SCRATCH_OPND, Opnd::const_ptr(pc)); - self.store(Opnd::mem(64, CFP, RUBY_OFFSET_CFP_PC), SCRATCH_OPND); + // Avoid setting cfp->pc when exiting entry_block with optional arguments + if !pc.is_null() { + asm_comment!(self, "save cfp->pc"); + self.load_into(SCRATCH_OPND, Opnd::const_ptr(pc)); + self.store(Opnd::mem(64, CFP, RUBY_OFFSET_CFP_PC), SCRATCH_OPND); + } asm_comment!(self, "save cfp->sp"); self.lea_into(SCRATCH_OPND, Opnd::mem(64, SP, stack.len() as i32 * SIZEOF_VALUE_I32)); diff --git a/zjit/src/codegen.rs b/zjit/src/codegen.rs index 41e196ca8e4f64..5e53c829f0b6eb 100644 --- a/zjit/src/codegen.rs +++ b/zjit/src/codegen.rs @@ -10,7 +10,7 @@ use std::slice; use crate::asm::Label; use crate::backend::current::{Reg, ALLOC_REGS}; use crate::invariants::{track_bop_assumption, track_cme_assumption, track_no_ep_escape_assumption, track_no_trace_point_assumption, track_single_ractor_assumption, track_stable_constant_names_assumption}; -use crate::gc::{append_gc_offsets, get_or_create_iseq_payload, get_or_create_iseq_payload_ptr, IseqPayload, IseqStatus}; +use crate::gc::{append_gc_offsets, get_or_create_iseq_payload, get_or_create_iseq_payload_ptr, IseqCodePtrs, IseqPayload, IseqStatus}; use crate::state::ZJITState; use crate::stats::{exit_counter_for_compile_error, incr_counter, incr_counter_by, CompileError}; use crate::stats::{counter_ptr, with_time_stat, Counter, send_fallback_counter, Counter::{compile_time_ns, exit_compile_error}}; @@ -33,6 +33,9 @@ struct JITState { /// Labels for each basic block indexed by the BlockId labels: Vec>, + /// JIT entry point for the `iseq` + jit_entry: Option>>, + /// ISEQ calls that need to be compiled later iseq_calls: Vec>>, @@ -47,6 +50,7 @@ impl JITState { iseq, opnds: vec![None; num_insns], labels: vec![None; num_blocks], + jit_entry: None, iseq_calls: Vec::default(), c_stack_slots, } @@ -117,7 +121,7 @@ fn gen_iseq_entry_point(cb: &mut CodeBlock, iseq: IseqPtr, jit_exception: bool) })?; // Compile the High-level IR - let start_ptr = gen_iseq(cb, iseq, Some(&function)).inspect_err(|err| { + let IseqCodePtrs { start_ptr, .. } = gen_iseq(cb, iseq, Some(&function)).inspect_err(|err| { debug!("{err:?}: gen_iseq failed: {}", iseq_get_location(iseq, 0)); })?; @@ -164,7 +168,7 @@ fn gen_entry(cb: &mut CodeBlock, iseq: IseqPtr, function: &Function, function_pt // Set up registers for CFP, EC, SP, and basic block arguments let mut asm = Assembler::new(); gen_entry_prologue(&mut asm, iseq); - gen_entry_params(&mut asm, iseq, function.block(BlockId(0))); + gen_entry_params(&mut asm, iseq, function.entry_block()); // Jump to the first block using a call instruction asm.ccall(function_ptr.raw_ptr(cb), vec![]); @@ -191,20 +195,20 @@ fn gen_entry(cb: &mut CodeBlock, iseq: IseqPtr, function: &Function, function_pt } /// Compile an ISEQ into machine code if not compiled yet -fn gen_iseq(cb: &mut CodeBlock, iseq: IseqPtr, function: Option<&Function>) -> Result { +fn gen_iseq(cb: &mut CodeBlock, iseq: IseqPtr, function: Option<&Function>) -> Result { // Return an existing pointer if it's already compiled let payload = get_or_create_iseq_payload(iseq); match &payload.status { - IseqStatus::Compiled(start_ptr) => return Ok(*start_ptr), + IseqStatus::Compiled(code_ptrs) => return Ok(code_ptrs.clone()), IseqStatus::CantCompile(err) => return Err(err.clone()), IseqStatus::NotCompiled => {}, } // Compile the ISEQ - let code_ptr = gen_iseq_body(cb, iseq, function, payload); - match &code_ptr { - Ok(start_ptr) => { - payload.status = IseqStatus::Compiled(*start_ptr); + let code_ptrs = gen_iseq_body(cb, iseq, function, payload); + match &code_ptrs { + Ok(code_ptrs) => { + payload.status = IseqStatus::Compiled(code_ptrs.clone()); incr_counter!(compiled_iseq_count); } Err(err) => { @@ -212,11 +216,11 @@ fn gen_iseq(cb: &mut CodeBlock, iseq: IseqPtr, function: Option<&Function>) -> R incr_counter!(failed_iseq_count); } } - code_ptr + code_ptrs } /// Compile an ISEQ into machine code -fn gen_iseq_body(cb: &mut CodeBlock, iseq: IseqPtr, function: Option<&Function>, payload: &mut IseqPayload) -> Result { +fn gen_iseq_body(cb: &mut CodeBlock, iseq: IseqPtr, function: Option<&Function>, payload: &mut IseqPayload) -> Result { // Convert ISEQ into optimized High-level IR if not given let function = match function { Some(function) => function, @@ -224,7 +228,7 @@ fn gen_iseq_body(cb: &mut CodeBlock, iseq: IseqPtr, function: Option<&Function>, }; // Compile the High-level IR - let (start_ptr, gc_offsets, iseq_calls) = gen_function(cb, iseq, function)?; + let (start_ptr, jit_entry_ptr, gc_offsets, iseq_calls) = gen_function(cb, iseq, function)?; // Stub callee ISEQs for JIT-to-JIT calls for iseq_call in iseq_calls.iter() { @@ -234,11 +238,11 @@ fn gen_iseq_body(cb: &mut CodeBlock, iseq: IseqPtr, function: Option<&Function>, // Prepare for GC payload.iseq_calls.extend(iseq_calls.clone()); append_gc_offsets(iseq, &gc_offsets); - Ok(start_ptr) + Ok(IseqCodePtrs { start_ptr, jit_entry_ptr }) } /// Compile a function -fn gen_function(cb: &mut CodeBlock, iseq: IseqPtr, function: &Function) -> Result<(CodePtr, Vec, Vec), CompileError> { +fn gen_function(cb: &mut CodeBlock, iseq: IseqPtr, function: &Function) -> Result<(CodePtr, CodePtr, Vec, Vec), CompileError> { let c_stack_slots = max_num_params(function).saturating_sub(ALLOC_REGS.len()); let mut jit = JITState::new(iseq, function.num_insns(), function.num_blocks(), c_stack_slots); let mut asm = Assembler::new(); @@ -257,11 +261,6 @@ fn gen_function(cb: &mut CodeBlock, iseq: IseqPtr, function: &Function) -> Resul let label = jit.get_label(&mut asm, block_id); asm.write_label(label); - // Set up the frame at the first block. :bb0-prologue: - if block_id == BlockId(0) { - asm.frame_setup(&[], jit.c_stack_slots); - } - // Compile all parameters for &insn_id in block.params() { match function.find(insn_id) { @@ -307,7 +306,10 @@ fn gen_function(cb: &mut CodeBlock, iseq: IseqPtr, function: &Function) -> Resul ZJITState::log_compile(iseq_name); } } - result.map(|(start_ptr, gc_offsets)| (start_ptr, gc_offsets, jit.iseq_calls)) + result.map(|(start_ptr, gc_offsets)| { + let jit_entry_ptr = jit.jit_entry.unwrap().borrow().start_addr.get().unwrap(); + (start_ptr, jit_entry_ptr, gc_offsets, jit.iseq_calls) + }) } /// Compile an instruction @@ -338,7 +340,8 @@ fn gen_insn(cb: &mut CodeBlock, jit: &mut JITState, asm: &mut Assembler, functio } let out_opnd = match insn { - Insn::Const { val: Const::Value(val) } => gen_const(*val), + &Insn::Const { val: Const::Value(val) } => gen_const_value(val), + &Insn::Const { val: Const::CPtr(val) } => gen_const_cptr(val), Insn::Const { .. } => panic!("Unexpected Const in gen_insn: {insn}"), Insn::NewArray { elements, state } => gen_new_array(asm, opnds!(elements), &function.frame_state(*state)), Insn::NewHash { elements, state } => gen_new_hash(jit, asm, opnds!(elements), &function.frame_state(*state)), @@ -372,6 +375,7 @@ fn gen_insn(cb: &mut CodeBlock, jit: &mut JITState, asm: &mut Assembler, functio // TODO remove this check when we have stack args (we can use Time.new to test it) Insn::InvokeBuiltin { bf, state, .. } if bf.argc + 2 > (C_ARG_OPNDS.len() as i32) => return Err(*state), Insn::InvokeBuiltin { bf, args, state, .. } => gen_invokebuiltin(jit, asm, &function.frame_state(*state), bf, opnds!(args)), + &Insn::EntryPoint { jit_entry } => no_output!(gen_entry_point(jit, asm, jit_entry)), Insn::Return { val } => no_output!(gen_return(asm, opnd!(val))), Insn::FixnumAdd { left, right, state } => gen_fixnum_add(jit, asm, opnd!(left), opnd!(right), &function.frame_state(*state)), Insn::FixnumSub { left, right, state } => gen_fixnum_sub(jit, asm, opnd!(left), opnd!(right), &function.frame_state(*state)), @@ -386,6 +390,7 @@ fn gen_insn(cb: &mut CodeBlock, jit: &mut JITState, asm: &mut Assembler, functio Insn::FixnumOr { left, right } => gen_fixnum_or(asm, opnd!(left), opnd!(right)), Insn::IsNil { val } => gen_isnil(asm, opnd!(val)), &Insn::IsMethodCfunc { val, cd, cfunc, state: _ } => gen_is_method_cfunc(jit, asm, opnd!(val), cd, cfunc), + &Insn::IsBitEqual { left, right } => gen_is_bit_equal(asm, opnd!(left), opnd!(right)), Insn::Test { val } => gen_test(asm, opnd!(val)), Insn::GuardType { val, guard_type, state } => gen_guard_type(jit, asm, opnd!(val), *guard_type, &function.frame_state(*state)), Insn::GuardTypeNot { val, guard_type, state } => gen_guard_type_not(jit, asm, opnd!(val), *guard_type, &function.frame_state(*state)), @@ -419,6 +424,7 @@ fn gen_insn(cb: &mut CodeBlock, jit: &mut JITState, asm: &mut Assembler, functio &Insn::DefinedIvar { self_val, id, pushval, .. } => { gen_defined_ivar(asm, opnd!(self_val), id, pushval) }, &Insn::ArrayExtend { left, right, state } => { no_output!(gen_array_extend(jit, asm, opnd!(left), opnd!(right), &function.frame_state(state))) }, &Insn::GuardShape { val, shape, state } => gen_guard_shape(jit, asm, opnd!(val), shape, &function.frame_state(state)), + Insn::LoadPC => gen_load_pc(), &Insn::LoadIvarEmbedded { self_val, id, index } => gen_load_ivar_embedded(asm, opnd!(self_val), id, index), &Insn::LoadIvarExtended { self_val, id, index } => gen_load_ivar_extended(asm, opnd!(self_val), id, index), &Insn::ArrayMax { state, .. } @@ -819,6 +825,10 @@ fn gen_guard_shape(jit: &mut JITState, asm: &mut Assembler, val: Opnd, shape: Sh val } +fn gen_load_pc() -> Opnd { + Opnd::mem(64, CFP, RUBY_OFFSET_CFP_PC) +} + fn gen_load_ivar_embedded(asm: &mut Assembler, self_val: Opnd, id: ID, index: u16) -> Opnd { // See ROBJECT_FIELDS() from include/ruby/internal/core/robject.h @@ -854,23 +864,6 @@ fn gen_entry_prologue(asm: &mut Assembler, iseq: IseqPtr) { // Load the current SP from the CFP into REG_SP asm.mov(SP, Opnd::mem(64, CFP, RUBY_OFFSET_CFP_SP)); - - // Currently, we support only the case that no optional arguments are given. - // Bail out if any optional argument is supplied. - let opt_num = unsafe { get_iseq_body_param_opt_num(iseq) }; - if opt_num > 0 { - asm_comment!(asm, "guard no optional arguments"); - let no_opts_pc = unsafe { rb_iseq_pc_at_idx(iseq, 0) }; - asm.cmp(Opnd::mem(64, CFP, RUBY_OFFSET_CFP_PC), Opnd::const_ptr(no_opts_pc)); - let no_opts_label = asm.new_label("no_opts"); - asm.je(no_opts_label.clone()); - - gen_incr_counter(asm, Counter::exit_optional_arguments); - asm.frame_teardown(lir::JIT_PRESERVED_REGS); - asm.cret(Qundef.into()); - - asm.write_label(no_opts_label); - } } /// Assign method arguments to basic block arguments at JIT entry @@ -966,11 +959,16 @@ fn gen_entry_param(asm: &mut Assembler, iseq: IseqPtr, local_idx: usize) -> lir: } /// Compile a constant -fn gen_const(val: VALUE) -> lir::Opnd { +fn gen_const_value(val: VALUE) -> lir::Opnd { // Just propagate the constant value and generate nothing Opnd::Value(val) } +/// Compile Const::CPtr +fn gen_const_cptr(val: *mut u8) -> lir::Opnd { + Opnd::UImm(val as u64) +} + /// Compile a basic block argument fn gen_param(asm: &mut Assembler, idx: usize) -> lir::Opnd { // Allocate a register or a stack slot @@ -1315,6 +1313,19 @@ fn gen_object_alloc_class(asm: &mut Assembler, class: VALUE, state: &FrameState) } } +/// Compile a frame setup. If is_jit_entry is true, remember the address of it as a JIT entry. +fn gen_entry_point(jit: &mut JITState, asm: &mut Assembler, is_jit_entry: bool) { + if is_jit_entry { + assert!(jit.jit_entry.is_none(), "only one jit_entry is expected"); + let jit_entry = JITEntry::new(); + jit.jit_entry = Some(jit_entry.clone()); + asm.pos_marker(move |code_ptr, _| { + jit_entry.borrow_mut().start_addr.set(Some(code_ptr)); + }); + } + asm.frame_setup(&[], jit.c_stack_slots); +} + /// Compile code that exits from JIT code with a return value fn gen_return(asm: &mut Assembler, val: lir::Opnd) { // Pop the current frame (ec->cfp++) @@ -1329,7 +1340,7 @@ fn gen_return(asm: &mut Assembler, val: lir::Opnd) { asm.load_into(C_RET_OPND, val); // Return from the function - asm.frame_teardown(&[]); // matching the setup in :bb0-prologue: + asm.frame_teardown(&[]); // matching the setup in gen_entry_point() asm.cret(C_RET_OPND); } @@ -1424,6 +1435,11 @@ fn gen_is_method_cfunc(jit: &JITState, asm: &mut Assembler, val: lir::Opnd, cd: asm_ccall!(asm, rb_vm_method_cfunc_is, VALUE(jit.iseq as usize).into(), (cd as usize).into(), val, (cfunc as usize).into()) } +fn gen_is_bit_equal(asm: &mut Assembler, left: lir::Opnd, right: lir::Opnd) -> lir::Opnd { + asm.cmp(left, right); + asm.csel_e(Opnd::Imm(1), Opnd::Imm(0)) +} + fn gen_anytostring(asm: &mut Assembler, val: lir::Opnd, str: lir::Opnd, state: &FrameState) -> lir::Opnd { gen_prepare_leaf_call_with_gc(asm, state); @@ -1912,19 +1928,19 @@ c_callable! { /// Compile an ISEQ for a function stub fn function_stub_hit_body(cb: &mut CodeBlock, iseq_call: &Rc>) -> Result { // Compile the stubbed ISEQ - let code_ptr = gen_iseq(cb, iseq_call.borrow().iseq, None).inspect_err(|err| { + let IseqCodePtrs { jit_entry_ptr, .. } = gen_iseq(cb, iseq_call.borrow().iseq, None).inspect_err(|err| { debug!("{err:?}: gen_iseq failed: {}", iseq_get_location(iseq_call.borrow().iseq, 0)); })?; // Update the stub to call the code pointer - let code_addr = code_ptr.raw_ptr(cb); + let code_addr = jit_entry_ptr.raw_ptr(cb); let iseq = iseq_call.borrow().iseq; iseq_call.borrow_mut().regenerate(cb, |asm| { asm_comment!(asm, "call compiled function: {}", iseq_get_location(iseq, 0)); asm.ccall(code_addr, vec![]); }); - Ok(code_ptr) + Ok(jit_entry_ptr) } /// Compile a stub for an ISEQ called by SendWithoutBlockDirect @@ -1983,7 +1999,7 @@ pub fn gen_exit_trampoline(cb: &mut CodeBlock) -> Result let mut asm = Assembler::new(); asm_comment!(asm, "side-exit trampoline"); - asm.frame_teardown(&[]); // matching the setup in :bb0-prologue: + asm.frame_teardown(&[]); // matching the setup in gen_entry_point() asm.cret(Qundef.into()); asm.compile(cb).map(|(code_ptr, gc_offsets)| { @@ -2113,6 +2129,22 @@ impl Assembler { } } +/// Store info about a JIT entry point +pub struct JITEntry { + /// Position where the entry point starts + start_addr: Cell>, +} + +impl JITEntry { + /// Allocate a new JITEntry + fn new() -> Rc> { + let jit_entry = JITEntry { + start_addr: Cell::new(None), + }; + Rc::new(RefCell::new(jit_entry)) + } +} + /// Store info about a JIT-to-JIT call #[derive(Debug)] pub struct IseqCall { diff --git a/zjit/src/gc.rs b/zjit/src/gc.rs index 49f8cbe2812aca..bf07f1f340f7d6 100644 --- a/zjit/src/gc.rs +++ b/zjit/src/gc.rs @@ -35,10 +35,18 @@ impl IseqPayload { } } +/// Set of CodePtrs for an ISEQ +#[derive(Clone, Debug, PartialEq)] +pub struct IseqCodePtrs { + /// Entry for the interpreter + pub start_ptr: CodePtr, + /// Entry for JIT-to-JIT calls + pub jit_entry_ptr: CodePtr, +} + #[derive(Debug, PartialEq)] pub enum IseqStatus { - /// CodePtr has the JIT code address of the first block - Compiled(CodePtr), + Compiled(IseqCodePtrs), CantCompile(CompileError), NotCompiled, } diff --git a/zjit/src/hir.rs b/zjit/src/hir.rs index e5286cd5e099a4..d040e4e7a30182 100644 --- a/zjit/src/hir.rs +++ b/zjit/src/hir.rs @@ -281,7 +281,7 @@ impl std::fmt::Display for Const { } impl Const { - fn print<'a>(&'a self, ptr_map: &'a PtrPrintMap) -> ConstPrinter<'a> { + pub fn print<'a>(&'a self, ptr_map: &'a PtrPrintMap) -> ConstPrinter<'a> { ConstPrinter { inner: self, ptr_map } } } @@ -341,7 +341,7 @@ impl TryFrom for SpecialBackrefSymbol { } /// Print adaptor for [`Const`]. See [`PtrPrintMap`]. -struct ConstPrinter<'a> { +pub struct ConstPrinter<'a> { inner: &'a Const, ptr_map: &'a PtrPrintMap, } @@ -350,7 +350,11 @@ impl<'a> std::fmt::Display for ConstPrinter<'a> { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { match self.inner { Const::Value(val) => write!(f, "Value({})", val.print(self.ptr_map)), - Const::CPtr(val) => write!(f, "CPtr({:p})", self.ptr_map.map_ptr(val)), + // TODO: Break out CPtr as a special case. For some reason, + // when we do that now, {:p} prints a completely different + // number than {:?} does and we don't know why. + // We'll have to resolve that first. + Const::CPtr(val) => write!(f, "CPtr({:?})", self.ptr_map.map_ptr(val)), _ => write!(f, "{:?}", self.inner), } } @@ -391,7 +395,7 @@ impl PtrPrintMap { impl PtrPrintMap { /// Map a pointer for printing - fn map_ptr(&self, ptr: *const T) -> *const T { + pub fn map_ptr(&self, ptr: *const T) -> *const T { // When testing, address stability is not a concern so print real address to enable code // reuse if !self.map_ptrs { @@ -452,6 +456,7 @@ pub enum SideExitReason { BlockParamProxyModified, BlockParamProxyNotIseqOrIfunc, StackOverflow, + OptionalArgumentsSupplied, } #[derive(Debug, Clone, Copy)] @@ -565,6 +570,8 @@ pub enum Insn { IsNil { val: InsnId }, /// Return C `true` if `val`'s method on cd resolves to the cfunc. IsMethodCfunc { val: InsnId, cd: *const rb_call_data, cfunc: *const u8, state: InsnId }, + /// Return C `true` if left == right + IsBitEqual { left: InsnId, right: InsnId }, Defined { op_type: usize, obj: VALUE, pushval: VALUE, v: InsnId, state: InsnId }, GetConstantPath { ic: *const iseq_inline_constant_cache, state: InsnId }, @@ -581,6 +588,8 @@ pub enum Insn { /// Check whether an instance variable exists on `self_val` DefinedIvar { self_val: InsnId, id: ID, pushval: VALUE, state: InsnId }, + /// Load cfp->pc + LoadPC, /// Read an instance variable at the given index, embedded in the object LoadIvarEmbedded { self_val: InsnId, id: ID, index: u16 }, /// Read an instance variable at the given index, from the extended table @@ -652,6 +661,8 @@ pub enum Insn { return_type: Option, // None for unannotated builtins }, + /// Set up frame and remember the address as a JIT entry if jit_entry is true + EntryPoint { jit_entry: bool }, /// Control flow instructions Return { val: InsnId }, /// Non-local control flow. See the throw YARV instruction @@ -707,7 +718,7 @@ impl Insn { pub fn has_output(&self) -> bool { match self { Insn::Jump(_) - | Insn::IfTrue { .. } | Insn::IfFalse { .. } | Insn::Return { .. } + | Insn::IfTrue { .. } | Insn::IfFalse { .. } | Insn::EntryPoint { .. } | Insn::Return { .. } | Insn::PatchPoint { .. } | Insn::SetIvar { .. } | Insn::ArrayExtend { .. } | Insn::ArrayPush { .. } | Insn::SideExit { .. } | Insn::SetGlobal { .. } | Insn::SetLocal { .. } | Insn::Throw { .. } | Insn::IncrCounter(_) @@ -869,6 +880,7 @@ impl<'a> std::fmt::Display for InsnPrinter<'a> { Insn::Test { val } => { write!(f, "Test {val}") } Insn::IsNil { val } => { write!(f, "IsNil {val}") } Insn::IsMethodCfunc { val, cd, .. } => { write!(f, "IsMethodCFunc {val}, :{}", ruby_call_method_name(*cd)) } + Insn::IsBitEqual { left, right } => write!(f, "IsBitEqual {left}, {right}"), 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}") } @@ -924,6 +936,7 @@ impl<'a> std::fmt::Display for InsnPrinter<'a> { } Ok(()) } + &Insn::EntryPoint { jit_entry } => write!(f, "EntryPoint {}", if jit_entry { "JIT" } else { "interpreter" }), Insn::Return { val } => { write!(f, "Return {val}") } Insn::FixnumAdd { left, right, .. } => { write!(f, "FixnumAdd {left}, {right}") }, Insn::FixnumSub { left, right, .. } => { write!(f, "FixnumSub {left}, {right}") }, @@ -978,6 +991,7 @@ impl<'a> std::fmt::Display for InsnPrinter<'a> { } Insn::DefinedIvar { self_val, id, .. } => write!(f, "DefinedIvar {self_val}, :{}", id.contents_lossy()), Insn::GetIvar { self_val, id, .. } => write!(f, "GetIvar {self_val}, :{}", id.contents_lossy()), + Insn::LoadPC => write!(f, "LoadPC"), &Insn::LoadIvarEmbedded { self_val, id, index } => write!(f, "LoadIvarEmbedded {self_val}, :{}@{:p}", id.contents_lossy(), self.ptr_map.map_index(index as u64)), &Insn::LoadIvarExtended { self_val, id, index } => write!(f, "LoadIvarExtended {self_val}, :{}@{:p}", id.contents_lossy(), self.ptr_map.map_index(index as u64)), Insn::SetIvar { self_val, id, val, .. } => write!(f, "SetIvar {self_val}, :{}, {val}", id.contents_lossy()), @@ -1216,7 +1230,10 @@ pub struct Function { union_find: std::cell::RefCell>, insn_types: Vec, blocks: Vec, + /// Entry block for the interpreter entry_block: BlockId, + /// Entry block for JIT-to-JIT calls + jit_entry_block: BlockId, profiles: Option, } @@ -1227,8 +1244,9 @@ impl Function { insns: vec![], insn_types: vec![], union_find: UnionFind::new().into(), - blocks: vec![Block::default()], + blocks: vec![Block::default(), Block::default()], entry_block: BlockId(0), + jit_entry_block: BlockId(1), param_types: vec![], profiles: None, } @@ -1292,6 +1310,11 @@ impl Function { &self.blocks[block_id.0] } + /// Return a reference to the entry block. + pub fn entry_block(&self) -> &Block { + &self.blocks[self.entry_block.0] + } + /// Return the number of blocks pub fn num_blocks(&self) -> usize { self.blocks.len() @@ -1350,6 +1373,8 @@ impl Function { | GetGlobal {..} | GetLocal {..} | SideExit {..} + | EntryPoint {..} + | LoadPC | IncrCounter(_)) => result.clone(), &Snapshot { state: FrameState { iseq, insn_idx, pc, ref stack, ref locals } } => Snapshot { @@ -1370,6 +1395,7 @@ impl Function { &Test { val } => Test { val: find!(val) }, &IsNil { val } => IsNil { val: find!(val) }, &IsMethodCfunc { val, cd, cfunc, state } => IsMethodCfunc { val: find!(val), cd, cfunc, state }, + &IsBitEqual { left, right } => IsBitEqual { left: find!(left), right: find!(right) }, Jump(target) => Jump(find_branch_edge!(target)), &IfTrue { val, ref target } => IfTrue { val: find!(val), target: find_branch_edge!(target) }, &IfFalse { val, ref target } => IfFalse { val: find!(val), target: find_branch_edge!(target) }, @@ -1494,7 +1520,7 @@ impl Function { assert!(self.insns[insn.0].has_output()); match &self.insns[insn.0] { Insn::Param { .. } => unimplemented!("params should not be present in block.insns"), - Insn::SetGlobal { .. } | Insn::Jump(_) + Insn::SetGlobal { .. } | Insn::Jump(_) | Insn::EntryPoint { .. } | Insn::IfTrue { .. } | Insn::IfFalse { .. } | Insn::Return { .. } | Insn::Throw { .. } | Insn::PatchPoint { .. } | Insn::SetIvar { .. } | Insn::ArrayExtend { .. } | Insn::ArrayPush { .. } | Insn::SideExit { .. } | Insn::SetLocal { .. } | Insn::IncrCounter(_) @@ -1510,7 +1536,7 @@ impl Function { Insn::Const { val: Const::CUInt16(val) } => Type::from_cint(types::CUInt16, *val as i64), Insn::Const { val: Const::CUInt32(val) } => Type::from_cint(types::CUInt32, *val as i64), Insn::Const { val: Const::CUInt64(val) } => Type::from_cint(types::CUInt64, *val as i64), - Insn::Const { val: Const::CPtr(val) } => Type::from_cint(types::CPtr, *val as i64), + Insn::Const { val: Const::CPtr(val) } => Type::from_cptr(*val), Insn::Const { val: Const::CDouble(val) } => Type::from_double(*val), Insn::Test { val } if self.type_of(*val).is_known_falsy() => Type::from_cbool(false), Insn::Test { val } if self.type_of(*val).is_known_truthy() => Type::from_cbool(true), @@ -1519,6 +1545,7 @@ impl Function { Insn::IsNil { val } if !self.type_of(*val).could_be(types::NilClass) => Type::from_cbool(false), Insn::IsNil { .. } => types::CBool, Insn::IsMethodCfunc { .. } => types::CBool, + Insn::IsBitEqual { .. } => types::CBool, Insn::StringCopy { .. } => types::StringExact, Insn::StringIntern { .. } => types::Symbol, Insn::StringConcat { .. } => types::StringExact, @@ -1564,6 +1591,7 @@ impl Function { Insn::ArrayMax { .. } => types::BasicObject, Insn::GetGlobal { .. } => types::BasicObject, Insn::GetIvar { .. } => types::BasicObject, + Insn::LoadPC => types::CPtr, Insn::LoadIvarEmbedded { .. } => types::BasicObject, Insn::LoadIvarExtended { .. } => types::BasicObject, Insn::GetSpecialSymbol { .. } => types::BasicObject, @@ -1584,17 +1612,31 @@ impl Function { self.insn_types.fill(types::Empty); // Fill parameter types + // TODO: Remove this when HIR incorporates parameter loads as well let entry_params = self.blocks[self.entry_block.0].params.iter(); let param_types = self.param_types.iter(); assert_eq!( entry_params.len(), + param_types.len(), + "param types should be initialized before type inference" + ); + for (param, param_type) in std::iter::zip(entry_params, param_types.clone()) { + // We know that function parameters are BasicObject or some subclass + self.insn_types[param.0] = *param_type; + } + + // Fill JIT entry parameter types + let entry_params = self.blocks[self.jit_entry_block.0].params.iter(); + assert_eq!( entry_params.len(), + param_types.len(), "param types should be initialized before type inference" ); for (param, param_type) in std::iter::zip(entry_params, param_types) { // We know that function parameters are BasicObject or some subclass self.insn_types[param.0] = *param_type; } + let rpo = self.rpo(); // Walk the graph, computing types until fixpoint let mut reachable = BlockSet::with_capacity(self.blocks.len()); @@ -2350,6 +2392,8 @@ impl Function { match insn { &Insn::Const { .. } | &Insn::Param { .. } + | &Insn::EntryPoint { .. } + | &Insn::LoadPC { .. } | &Insn::GetLocal { .. } | &Insn::PutSpecialObject { .. } | &Insn::IncrCounter(_) => @@ -2422,6 +2466,7 @@ impl Function { | &Insn::FixnumNeq { left, right } | &Insn::FixnumAnd { left, right } | &Insn::FixnumOr { left, right } + | &Insn::IsBitEqual { left, right } => { worklist.push_back(left); worklist.push_back(right); @@ -2582,6 +2627,7 @@ impl Function { pub fn rpo(&self) -> Vec { let mut result = self.po_from(self.entry_block); result.reverse(); + result.insert(1, self.jit_entry_block); // Put jit_entry_block after entry_block result } @@ -3088,6 +3134,7 @@ fn compute_bytecode_info(iseq: *const rb_iseq_t) -> BytecodeInfo { let iseq_size = unsafe { get_iseq_encoded_size(iseq) }; let mut insn_idx = 0; let mut jump_targets = HashSet::new(); + jump_targets.insert(0); // entry blocks jump to the first instruction let mut has_blockiseq = false; while insn_idx < iseq_size { // Get the current pc and opcode @@ -3214,9 +3261,6 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result { let BytecodeInfo { jump_targets, has_blockiseq } = compute_bytecode_info(iseq); let mut insn_idx_to_block = HashMap::new(); for insn_idx in jump_targets { - if insn_idx == 0 { - todo!("Separate entry block for param/self/..."); - } insn_idx_to_block.insert(insn_idx, fun.new_block(insn_idx)); } @@ -3224,6 +3268,13 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result { // optimizing locals in that case because they're shared with other frames. let ep_escaped = iseq_escapes_ep(iseq); + // Compile an interpreter entry to the first block + let first_block = insn_idx_to_block[&0]; + compile_entry_block(fun.entry_block, first_block, &mut fun, false); + + // Compile a JIT entry to the first block + compile_entry_block(fun.jit_entry_block, first_block, &mut fun, true); + // Iteratively fill out basic blocks using a queue // TODO(max): Basic block arguments at edges let mut queue = std::collections::VecDeque::new(); @@ -3240,23 +3291,23 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result { // item between commas in the source increase the parameter count by one, // regardless of parameter kind. let mut entry_state = FrameState::new(iseq); - fun.push_insn(fun.entry_block, Insn::Param { idx: SELF_PARAM_IDX }); + fun.push_insn(first_block, Insn::Param { idx: SELF_PARAM_IDX }); fun.param_types.push(types::BasicObject); // self for local_idx in 0..num_locals(iseq) { if local_idx < unsafe { get_iseq_body_param_size(iseq) }.as_usize() { - entry_state.locals.push(fun.push_insn(fun.entry_block, Insn::Param { idx: local_idx + 1 })); // +1 for self - } else { - entry_state.locals.push(fun.push_insn(fun.entry_block, Insn::Const { val: Const::Value(Qnil) })); - } + entry_state.locals.push(fun.push_insn(first_block, Insn::Param { idx: local_idx + 1 })); // +1 for self - let mut param_type = types::BasicObject; - // Rest parameters are always ArrayExact - if let Ok(true) = c_int::try_from(local_idx).map(|idx| idx == rest_param_idx) { - param_type = types::ArrayExact; + let mut param_type = types::BasicObject; + // Rest parameters are always ArrayExact + if let Ok(true) = c_int::try_from(local_idx).map(|idx| idx == rest_param_idx) { + param_type = types::ArrayExact; + } + fun.param_types.push(param_type); + } else { + entry_state.locals.push(fun.push_insn(first_block, Insn::Const { val: Const::Value(Qnil) })); } - fun.param_types.push(param_type); } - queue.push_back((entry_state, fun.entry_block, /*insn_idx=*/0_u32, /*local_inval=*/false)); + queue.push_back((entry_state.clone(), first_block, /*insn_idx=*/0_u32, /*local_inval=*/false)); let mut visited = HashSet::new(); @@ -3265,7 +3316,7 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result { if visited.contains(&block) { continue; } visited.insert(block); let (self_param, mut state) = if insn_idx == 0 { - (fun.blocks[fun.entry_block.0].params[SELF_PARAM_IDX], incoming_state.clone()) + (fun.blocks[block.0].params[SELF_PARAM_IDX], incoming_state.clone()) } else { let self_param = fun.push_insn(block, Insn::Param { idx: SELF_PARAM_IDX }); let mut result = FrameState::new(iseq); @@ -4071,6 +4122,40 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result { Ok(fun) } +/// Compile entry_block that jumps to first_block. Add prologue for the interpreter if jit_entry is false. +fn compile_entry_block(entry_block: BlockId, first_block: BlockId, fun: &mut Function, jit_entry: bool) { + fun.push_insn(entry_block, Insn::EntryPoint { jit_entry }); + + // Prepare entry_state with basic block params + let iseq = fun.iseq; + let mut entry_state = FrameState::new(iseq); + let self_param = fun.push_insn(entry_block, Insn::Param { idx: SELF_PARAM_IDX }); + for local_idx in 0..unsafe { get_iseq_body_param_size(iseq) }.as_usize() { + entry_state.locals.push(fun.push_insn(entry_block, Insn::Param { idx: local_idx + 1 })); // +1 for self + } + + // Jump to the first_block. Conditionally side-exit for interpreter entry with optional arguments. + // TODO: Compile gen_entry_params() for !jit_entry here + let opt_num = unsafe { get_iseq_body_param_opt_num(iseq) }; + if !jit_entry && opt_num > 0 { + let pc = fun.push_insn(entry_block, Insn::LoadPC); + let no_opts_pc = fun.push_insn(entry_block, Insn::Const { val: Const::CPtr(unsafe { rb_iseq_pc_at_idx(iseq, 0) } as *mut u8) }); + let test_id = fun.push_insn(entry_block, Insn::IsBitEqual { left: pc, right: no_opts_pc }); + + // Jump to the first_block if no optional arguments are supplied + fun.push_insn(entry_block, Insn::IfTrue { + val: test_id, + target: BranchEdge { target: first_block, args: entry_state.as_args(self_param) }, + }); + + // Side-exit if any optional argument is supplied + let state = fun.push_insn(entry_block, Insn::Snapshot { state: FrameState::new(iseq) }); // no need to spill params + fun.push_insn(entry_block, Insn::SideExit { state, reason: SideExitReason::OptionalArgumentsSupplied }); + } else { + fun.push_insn(entry_block, Insn::Jump(BranchEdge { target: first_block, args: entry_state.as_args(self_param) })); + } +} + #[cfg(test)] mod union_find_tests { use super::UnionFind; @@ -4116,26 +4201,29 @@ mod rpo_tests { fn one_block() { let mut function = Function::new(std::ptr::null()); let entry = function.entry_block; + let jit_entry = function.jit_entry_block; let val = function.push_insn(entry, Insn::Const { val: Const::Value(Qnil) }); function.push_insn(entry, Insn::Return { val }); - assert_eq!(function.rpo(), vec![entry]); + assert_eq!(function.rpo(), vec![entry, jit_entry]); } #[test] fn jump() { let mut function = Function::new(std::ptr::null()); let entry = function.entry_block; + let jit_entry = function.jit_entry_block; let exit = function.new_block(0); function.push_insn(entry, Insn::Jump(BranchEdge { target: exit, args: vec![] })); let val = function.push_insn(entry, Insn::Const { val: Const::Value(Qnil) }); function.push_insn(entry, Insn::Return { val }); - assert_eq!(function.rpo(), vec![entry, exit]); + assert_eq!(function.rpo(), vec![entry, jit_entry, exit]); } #[test] fn diamond_iftrue() { let mut function = Function::new(std::ptr::null()); let entry = function.entry_block; + let jit_entry = function.jit_entry_block; let side = function.new_block(0); let exit = function.new_block(0); function.push_insn(side, Insn::Jump(BranchEdge { target: exit, args: vec![] })); @@ -4144,13 +4232,14 @@ mod rpo_tests { function.push_insn(entry, Insn::Jump(BranchEdge { target: exit, args: vec![] })); let val = function.push_insn(entry, Insn::Const { val: Const::Value(Qnil) }); function.push_insn(entry, Insn::Return { val }); - assert_eq!(function.rpo(), vec![entry, side, exit]); + assert_eq!(function.rpo(), vec![entry, jit_entry, side, exit]); } #[test] fn diamond_iffalse() { let mut function = Function::new(std::ptr::null()); let entry = function.entry_block; + let jit_entry = function.jit_entry_block; let side = function.new_block(0); let exit = function.new_block(0); function.push_insn(side, Insn::Jump(BranchEdge { target: exit, args: vec![] })); @@ -4159,15 +4248,16 @@ mod rpo_tests { function.push_insn(entry, Insn::Jump(BranchEdge { target: exit, args: vec![] })); let val = function.push_insn(entry, Insn::Const { val: Const::Value(Qnil) }); function.push_insn(entry, Insn::Return { val }); - assert_eq!(function.rpo(), vec![entry, side, exit]); + assert_eq!(function.rpo(), vec![entry, jit_entry, side, exit]); } #[test] fn a_loop() { let mut function = Function::new(std::ptr::null()); let entry = function.entry_block; + let jit_entry = function.jit_entry_block; function.push_insn(entry, Insn::Jump(BranchEdge { target: entry, args: vec![] })); - assert_eq!(function.rpo(), vec![entry]); + assert_eq!(function.rpo(), vec![entry, jit_entry]); } } @@ -4296,31 +4386,46 @@ mod validation_tests { #[test] fn instruction_appears_twice_in_same_block() { let mut function = Function::new(std::ptr::null()); - let entry = function.entry_block; - let val = function.push_insn(entry, Insn::Const { val: Const::Value(Qnil) }); - function.push_insn_id(entry, val); - function.push_insn(entry, Insn::Return { val }); - assert_matches_err(function.validate(), ValidationError::DuplicateInstruction(entry, val)); + let block = function.new_block(0); + + // Add jumps from entry blocks to avoid BlockHasNoterminator + function.push_insn(function.entry_block, Insn::Jump(BranchEdge { target: block, args: vec![] })); + function.push_insn(function.jit_entry_block, Insn::Jump(BranchEdge { target: block, args: vec![] })); + + let val = function.push_insn(block, Insn::Const { val: Const::Value(Qnil) }); + function.push_insn_id(block, val); + function.push_insn(block, Insn::Return { val }); + assert_matches_err(function.validate(), ValidationError::DuplicateInstruction(block, val)); } #[test] fn instruction_appears_twice_with_different_ids() { let mut function = Function::new(std::ptr::null()); - let entry = function.entry_block; - let val0 = function.push_insn(entry, Insn::Const { val: Const::Value(Qnil) }); - let val1 = function.push_insn(entry, Insn::Const { val: Const::Value(Qnil) }); + let block = function.new_block(0); + + // Add jumps from entry blocks to avoid BlockHasNoterminator + function.push_insn(function.entry_block, Insn::Jump(BranchEdge { target: block, args: vec![] })); + function.push_insn(function.jit_entry_block, Insn::Jump(BranchEdge { target: block, args: vec![] })); + + let val0 = function.push_insn(block, Insn::Const { val: Const::Value(Qnil) }); + let val1 = function.push_insn(block, Insn::Const { val: Const::Value(Qnil) }); function.make_equal_to(val1, val0); - function.push_insn(entry, Insn::Return { val: val0 }); - assert_matches_err(function.validate(), ValidationError::DuplicateInstruction(entry, val0)); + function.push_insn(block, Insn::Return { val: val0 }); + assert_matches_err(function.validate(), ValidationError::DuplicateInstruction(block, val0)); } #[test] fn instruction_appears_twice_in_different_blocks() { let mut function = Function::new(std::ptr::null()); - let entry = function.entry_block; - let val = function.push_insn(entry, Insn::Const { val: Const::Value(Qnil) }); + let block = function.new_block(0); + + // Add jumps from entry blocks to avoid BlockHasNoterminator + function.push_insn(function.entry_block, Insn::Jump(BranchEdge { target: block, args: vec![] })); + function.push_insn(function.jit_entry_block, Insn::Jump(BranchEdge { target: block, args: vec![] })); + + let val = function.push_insn(block, Insn::Const { val: Const::Value(Qnil) }); let exit = function.new_block(0); - function.push_insn(entry, Insn::Jump(BranchEdge { target: exit, args: vec![] })); + function.push_insn(block, Insn::Jump(BranchEdge { target: exit, args: vec![] })); function.push_insn_id(exit, val); function.push_insn(exit, Insn::Return { val }); assert_matches_err(function.validate(), ValidationError::DuplicateInstruction(exit, val)); @@ -4386,6 +4491,7 @@ mod infer_tests { crate::cruby::with_rubyvm(|| { let mut function = Function::new(std::ptr::null()); let param = function.push_insn(function.entry_block, Insn::Param { idx: SELF_PARAM_IDX }); + function.push_insn(function.jit_entry_block, Insn::Param { idx: SELF_PARAM_IDX }); function.param_types.push(types::BasicObject); // self let val = function.push_insn(function.entry_block, Insn::Test { val: param }); function.infer_types(); @@ -4467,17 +4573,23 @@ mod snapshot_tests { eval("def test(a, b) = [a, b]"); assert_snapshot!(hir_string("test"), @r" fn test@:1: - bb0(v0:BasicObject, v1:BasicObject, v2:BasicObject): - v3:Any = Snapshot FrameState { pc: 0x1000, stack: [], locals: [a=v1, b=v2] } - v4:Any = Snapshot FrameState { pc: 0x1008, stack: [], locals: [a=v1, b=v2] } + bb0(v1:BasicObject, v2:BasicObject, v3:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2, v3) + bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): + EntryPoint JIT + Jump bb2(v6, v7, v8) + bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): + v13:Any = Snapshot FrameState { pc: 0x1000, stack: [], locals: [a=v11, b=v12] } + v14:Any = Snapshot FrameState { pc: 0x1008, stack: [], locals: [a=v11, b=v12] } PatchPoint NoTracePoint - v6:Any = Snapshot FrameState { pc: 0x1010, stack: [v1, v2], locals: [a=v1, b=v2] } - v7:ArrayExact = NewArray v1, v2 - v8:Any = Snapshot FrameState { pc: 0x1018, stack: [v7], locals: [a=v1, b=v2] } + v16:Any = Snapshot FrameState { pc: 0x1010, stack: [v11, v12], locals: [a=v11, b=v12] } + v17:ArrayExact = NewArray v11, v12 + v18:Any = Snapshot FrameState { pc: 0x1018, stack: [v17], locals: [a=v11, b=v12] } PatchPoint NoTracePoint - v10:Any = Snapshot FrameState { pc: 0x1018, stack: [v7], locals: [a=v1, b=v2] } + v20:Any = Snapshot FrameState { pc: 0x1018, stack: [v17], locals: [a=v11, b=v12] } CheckInterrupts - Return v7 + Return v17 "); } } @@ -4549,11 +4661,21 @@ mod tests { eval("def test(x=1) = 123"); assert_snapshot!(hir_string("test"), @r" fn test@:1: - bb0(v0:BasicObject, v1:BasicObject): - v3:Fixnum[1] = Const Value(1) - v6:Fixnum[123] = Const Value(123) + bb0(v1:BasicObject, v2:BasicObject): + EntryPoint interpreter + v3:CPtr = LoadPC + v4:CPtr[CPtr(0x1000)] = Const CPtr(0x1008) + v5:CBool = IsBitEqual v3, v4 + IfTrue v5, bb2(v1, v2) + SideExit OptionalArgumentsSupplied + bb1(v10:BasicObject, v11:BasicObject): + EntryPoint JIT + Jump bb2(v10, v11) + bb2(v13:BasicObject, v14:BasicObject): + v16:Fixnum[1] = Const Value(1) + v19:Fixnum[123] = Const Value(123) CheckInterrupts - Return v6 + Return v19 "); } @@ -4563,10 +4685,16 @@ mod tests { assert_contains_opcode("test", YARVINSN_putobject); assert_snapshot!(hir_string("test"), @r" fn test@:1: - bb0(v0:BasicObject): - v4:Fixnum[123] = Const Value(123) + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v10:Fixnum[123] = Const Value(123) CheckInterrupts - Return v4 + Return v10 "); } @@ -4576,10 +4704,16 @@ mod tests { assert_contains_opcode("test", YARVINSN_newarray); assert_snapshot!(hir_string("test"), @r" fn test@:1: - bb0(v0:BasicObject): - v5:ArrayExact = NewArray + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v11:ArrayExact = NewArray CheckInterrupts - Return v5 + Return v11 "); } @@ -4589,10 +4723,16 @@ mod tests { assert_contains_opcode("test", YARVINSN_newarray); assert_snapshot!(hir_string("test"), @r" fn test@:1: - bb0(v0:BasicObject, v1:BasicObject): - v6:ArrayExact = NewArray v1 + bb0(v1:BasicObject, v2:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:BasicObject): + EntryPoint JIT + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:BasicObject): + v14:ArrayExact = NewArray v9 CheckInterrupts - Return v6 + Return v14 "); } @@ -4602,10 +4742,16 @@ mod tests { assert_contains_opcode("test", YARVINSN_newarray); assert_snapshot!(hir_string("test"), @r" fn test@:1: - bb0(v0:BasicObject, v1:BasicObject, v2:BasicObject): - v7:ArrayExact = NewArray v1, v2 + bb0(v1:BasicObject, v2:BasicObject, v3:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2, v3) + bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): + EntryPoint JIT + Jump bb2(v6, v7, v8) + bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): + v17:ArrayExact = NewArray v11, v12 CheckInterrupts - Return v7 + Return v17 "); } @@ -4615,11 +4761,17 @@ mod tests { assert_contains_opcode("test", YARVINSN_newrange); assert_snapshot!(hir_string("test"), @r" fn test@:1: - bb0(v0:BasicObject, v1:BasicObject): - v5:Fixnum[10] = Const Value(10) - v7:RangeExact = NewRange v1 NewRangeInclusive v5 + bb0(v1:BasicObject, v2:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:BasicObject): + EntryPoint JIT + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:BasicObject): + v13:Fixnum[10] = Const Value(10) + v15:RangeExact = NewRange v9 NewRangeInclusive v13 CheckInterrupts - Return v7 + Return v15 "); } @@ -4629,10 +4781,16 @@ mod tests { assert_contains_opcode("test", YARVINSN_newrange); assert_snapshot!(hir_string("test"), @r" fn test@:1: - bb0(v0:BasicObject, v1:BasicObject, v2:BasicObject): - v7:RangeExact = NewRange v1 NewRangeInclusive v2 + bb0(v1:BasicObject, v2:BasicObject, v3:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2, v3) + bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): + EntryPoint JIT + Jump bb2(v6, v7, v8) + bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): + v17:RangeExact = NewRange v11 NewRangeInclusive v12 CheckInterrupts - Return v7 + Return v17 "); } @@ -4642,11 +4800,17 @@ mod tests { assert_contains_opcode("test", YARVINSN_newrange); assert_snapshot!(hir_string("test"), @r" fn test@:1: - bb0(v0:BasicObject, v1:BasicObject): - v5:Fixnum[10] = Const Value(10) - v7:RangeExact = NewRange v1 NewRangeExclusive v5 + bb0(v1:BasicObject, v2:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:BasicObject): + EntryPoint JIT + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:BasicObject): + v13:Fixnum[10] = Const Value(10) + v15:RangeExact = NewRange v9 NewRangeExclusive v13 CheckInterrupts - Return v7 + Return v15 "); } @@ -4656,10 +4820,16 @@ mod tests { assert_contains_opcode("test", YARVINSN_newrange); assert_snapshot!(hir_string("test"), @r" fn test@:1: - bb0(v0:BasicObject, v1:BasicObject, v2:BasicObject): - v7:RangeExact = NewRange v1 NewRangeExclusive v2 + bb0(v1:BasicObject, v2:BasicObject, v3:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2, v3) + bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): + EntryPoint JIT + Jump bb2(v6, v7, v8) + bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): + v17:RangeExact = NewRange v11 NewRangeExclusive v12 CheckInterrupts - Return v7 + Return v17 "); } @@ -4669,11 +4839,17 @@ mod tests { assert_contains_opcode("test", YARVINSN_duparray); assert_snapshot!(hir_string("test"), @r" fn test@:1: - bb0(v0:BasicObject): - v4:ArrayExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) - v6:ArrayExact = ArrayDup v4 + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v10:ArrayExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) + v12:ArrayExact = ArrayDup v10 CheckInterrupts - Return v6 + Return v12 "); } @@ -4683,11 +4859,17 @@ mod tests { assert_contains_opcode("test", YARVINSN_duphash); assert_snapshot!(hir_string("test"), @r" fn test@:1: - bb0(v0:BasicObject): - v4:HashExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) - v6:HashExact = HashDup v4 + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v10:HashExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) + v12:HashExact = HashDup v10 CheckInterrupts - Return v6 + Return v12 "); } @@ -4697,10 +4879,16 @@ mod tests { assert_contains_opcode("test", YARVINSN_newhash); assert_snapshot!(hir_string("test"), @r" fn test@:1: - bb0(v0:BasicObject): - v5:HashExact = NewHash + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v11:HashExact = NewHash CheckInterrupts - Return v5 + Return v11 "); } @@ -4710,12 +4898,18 @@ mod tests { assert_contains_opcode("test", YARVINSN_newhash); assert_snapshot!(hir_string("test"), @r" fn test@:1: - bb0(v0:BasicObject, v1:BasicObject, v2:BasicObject): - v6:StaticSymbol[:a] = Const Value(VALUE(0x1000)) - v7:StaticSymbol[:b] = Const Value(VALUE(0x1008)) - v9:HashExact = NewHash v6: v1, v7: v2 + bb0(v1:BasicObject, v2:BasicObject, v3:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2, v3) + bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): + EntryPoint JIT + Jump bb2(v6, v7, v8) + bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): + v16:StaticSymbol[:a] = Const Value(VALUE(0x1000)) + v17:StaticSymbol[:b] = Const Value(VALUE(0x1008)) + v19:HashExact = NewHash v16: v11, v17: v12 CheckInterrupts - Return v9 + Return v19 "); } @@ -4725,11 +4919,17 @@ mod tests { assert_contains_opcode("test", YARVINSN_putchilledstring); assert_snapshot!(hir_string("test"), @r" fn test@:1: - bb0(v0:BasicObject): - v4:StringExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) - v6:StringExact = StringCopy v4 + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v10:StringExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) + v12:StringExact = StringCopy v10 CheckInterrupts - Return v6 + Return v12 "); } @@ -4739,10 +4939,16 @@ mod tests { assert_contains_opcode("test", YARVINSN_putobject); assert_snapshot!(hir_string("test"), @r" fn test@:1: - bb0(v0:BasicObject): - v4:Bignum[VALUE(0x1000)] = Const Value(VALUE(0x1000)) + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v10:Bignum[VALUE(0x1000)] = Const Value(VALUE(0x1000)) CheckInterrupts - Return v4 + Return v10 "); } @@ -4752,10 +4958,16 @@ mod tests { assert_contains_opcode("test", YARVINSN_putobject); assert_snapshot!(hir_string("test"), @r" fn test@:1: - bb0(v0:BasicObject): - v4:Flonum[VALUE(0x1000)] = Const Value(VALUE(0x1000)) + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v10:Flonum[VALUE(0x1000)] = Const Value(VALUE(0x1000)) CheckInterrupts - Return v4 + Return v10 "); } @@ -4765,10 +4977,16 @@ mod tests { assert_contains_opcode("test", YARVINSN_putobject); assert_snapshot!(hir_string("test"), @r" fn test@:1: - bb0(v0:BasicObject): - v4:HeapFloat[VALUE(0x1000)] = Const Value(VALUE(0x1000)) + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v10:HeapFloat[VALUE(0x1000)] = Const Value(VALUE(0x1000)) CheckInterrupts - Return v4 + Return v10 "); } @@ -4778,10 +4996,16 @@ mod tests { assert_contains_opcode("test", YARVINSN_putobject); assert_snapshot!(hir_string("test"), @r" fn test@:1: - bb0(v0:BasicObject): - v4:StaticSymbol[:foo] = Const Value(VALUE(0x1000)) + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v10:StaticSymbol[:foo] = Const Value(VALUE(0x1000)) CheckInterrupts - Return v4 + Return v10 "); } @@ -4791,12 +5015,18 @@ mod tests { assert_contains_opcode("test", YARVINSN_opt_plus); assert_snapshot!(hir_string("test"), @r" fn test@:1: - bb0(v0:BasicObject): - v4:Fixnum[1] = Const Value(1) - v5:Fixnum[2] = Const Value(2) - v9:BasicObject = SendWithoutBlock v4, :+, v5 + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v10:Fixnum[1] = Const Value(1) + v11:Fixnum[2] = Const Value(2) + v15:BasicObject = SendWithoutBlock v10, :+, v11 CheckInterrupts - Return v9 + Return v15 "); } @@ -4808,11 +5038,17 @@ mod tests { assert_contains_opcode("test", YARVINSN_opt_hash_freeze); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject): + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): PatchPoint BOPRedefined(HASH_REDEFINED_OP_FLAG, BOP_FREEZE) - v6:HashExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) + v12:HashExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) CheckInterrupts - Return v6 + Return v12 "); } @@ -4827,7 +5063,13 @@ mod tests { assert_contains_opcode("test", YARVINSN_opt_hash_freeze); assert_snapshot!(hir_string("test"), @r" fn test@:5: - bb0(v0:BasicObject): + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): SideExit PatchPoint(BOPRedefined(HASH_REDEFINED_OP_FLAG, BOP_FREEZE)) "); } @@ -4840,11 +5082,17 @@ mod tests { assert_contains_opcode("test", YARVINSN_opt_ary_freeze); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject): + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): PatchPoint BOPRedefined(ARRAY_REDEFINED_OP_FLAG, BOP_FREEZE) - v6:ArrayExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) + v12:ArrayExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) CheckInterrupts - Return v6 + Return v12 "); } @@ -4859,7 +5107,13 @@ mod tests { assert_contains_opcode("test", YARVINSN_opt_ary_freeze); assert_snapshot!(hir_string("test"), @r" fn test@:5: - bb0(v0:BasicObject): + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): SideExit PatchPoint(BOPRedefined(ARRAY_REDEFINED_OP_FLAG, BOP_FREEZE)) "); } @@ -4872,11 +5126,17 @@ mod tests { assert_contains_opcode("test", YARVINSN_opt_str_freeze); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject): + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): PatchPoint BOPRedefined(STRING_REDEFINED_OP_FLAG, BOP_FREEZE) - v6:StringExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) + v12:StringExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) CheckInterrupts - Return v6 + Return v12 "); } @@ -4891,7 +5151,13 @@ mod tests { assert_contains_opcode("test", YARVINSN_opt_str_freeze); assert_snapshot!(hir_string("test"), @r" fn test@:5: - bb0(v0:BasicObject): + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): SideExit PatchPoint(BOPRedefined(STRING_REDEFINED_OP_FLAG, BOP_FREEZE)) "); } @@ -4904,11 +5170,17 @@ mod tests { assert_contains_opcode("test", YARVINSN_opt_str_uminus); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject): + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): PatchPoint BOPRedefined(STRING_REDEFINED_OP_FLAG, BOP_UMINUS) - v6:StringExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) + v12:StringExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) CheckInterrupts - Return v6 + Return v12 "); } @@ -4923,7 +5195,13 @@ mod tests { assert_contains_opcode("test", YARVINSN_opt_str_uminus); assert_snapshot!(hir_string("test"), @r" fn test@:5: - bb0(v0:BasicObject): + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): SideExit PatchPoint(BOPRedefined(STRING_REDEFINED_OP_FLAG, BOP_UMINUS)) "); } @@ -4939,11 +5217,17 @@ mod tests { assert_contains_opcodes("test", &[YARVINSN_getlocal_WC_0, YARVINSN_setlocal_WC_0]); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject): - v1:NilClass = Const Value(nil) - v5:Fixnum[1] = Const Value(1) + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v7:NilClass = Const Value(nil) + v11:Fixnum[1] = Const Value(1) CheckInterrupts - Return v5 + Return v11 "); } @@ -4971,19 +5255,25 @@ mod tests { YARVINSN_getlocal, YARVINSN_setlocal]); assert_snapshot!(hir_string("test"), @r" fn block (3 levels) in @:10: - bb0(v0:BasicObject): - v4:BasicObject = GetLocal l2, EP@4 - SetLocal l1, EP@3, v4 - v8:BasicObject = GetLocal l1, EP@3 - v9:BasicObject = GetLocal l2, EP@4 - v13:BasicObject = SendWithoutBlock v8, :+, v9 - SetLocal l2, EP@4, v13 - v17:BasicObject = GetLocal l2, EP@4 - v18:BasicObject = GetLocal l3, EP@5 - v22:BasicObject = SendWithoutBlock v17, :+, v18 - SetLocal l3, EP@5, v22 + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v10:BasicObject = GetLocal l2, EP@4 + SetLocal l1, EP@3, v10 + v14:BasicObject = GetLocal l1, EP@3 + v15:BasicObject = GetLocal l2, EP@4 + v19:BasicObject = SendWithoutBlock v14, :+, v15 + SetLocal l2, EP@4, v19 + v23:BasicObject = GetLocal l2, EP@4 + v24:BasicObject = GetLocal l3, EP@5 + v28:BasicObject = SendWithoutBlock v23, :+, v24 + SetLocal l3, EP@5, v28 CheckInterrupts - Return v22 + Return v28 " ); } @@ -4996,10 +5286,16 @@ mod tests { assert_contains_opcode("test", YARVINSN_definedivar); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject): - v5:StringExact|NilClass = DefinedIvar v0, :@foo + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v11:StringExact|NilClass = DefinedIvar v6, :@foo CheckInterrupts - Return v5 + Return v11 "); } @@ -5017,18 +5313,24 @@ mod tests { assert_contains_opcode("test", YARVINSN_definedivar); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject): - v5:TrueClass|NilClass = DefinedIvar v0, :@foo - CheckInterrupts - v8:CBool = Test v5 - IfFalse v8, bb1(v0) - v12:Fixnum[3] = Const Value(3) + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v11:TrueClass|NilClass = DefinedIvar v6, :@foo + CheckInterrupts + v14:CBool = Test v11 + IfFalse v14, bb3(v6) + v18:Fixnum[3] = Const Value(3) CheckInterrupts - Return v12 - bb1(v18:BasicObject): - v22:Fixnum[4] = Const Value(4) + Return v18 + bb3(v24:BasicObject): + v28:Fixnum[4] = Const Value(4) CheckInterrupts - Return v22 + Return v28 "); } @@ -5040,15 +5342,21 @@ mod tests { assert_contains_opcode("test", YARVINSN_defined); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject): - v4:NilClass = Const Value(nil) - v6:StringExact|NilClass = Defined constant, v4 - v8:StringExact|NilClass = Defined func, v0 - v9:NilClass = Const Value(nil) - v11:StringExact|NilClass = Defined global-variable, v9 - v13:ArrayExact = NewArray v6, v8, v11 + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v10:NilClass = Const Value(nil) + v12:StringExact|NilClass = Defined constant, v10 + v14:StringExact|NilClass = Defined func, v6 + v15:NilClass = Const Value(nil) + v17:StringExact|NilClass = Defined global-variable, v15 + v19:ArrayExact = NewArray v12, v14, v17 CheckInterrupts - Return v13 + Return v19 "); } @@ -5066,17 +5374,23 @@ mod tests { assert_contains_opcode("test", YARVINSN_leave); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject, v1:BasicObject): - CheckInterrupts - v7:CBool = Test v1 - IfFalse v7, bb1(v0, v1) - v11:Fixnum[3] = Const Value(3) + bb0(v1:BasicObject, v2:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:BasicObject): + EntryPoint JIT + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:BasicObject): + CheckInterrupts + v15:CBool = Test v9 + IfFalse v15, bb3(v8, v9) + v19:Fixnum[3] = Const Value(3) CheckInterrupts - Return v11 - bb1(v17:BasicObject, v18:BasicObject): - v22:Fixnum[4] = Const Value(4) + Return v19 + bb3(v25:BasicObject, v26:BasicObject): + v30:Fixnum[4] = Const Value(4) CheckInterrupts - Return v22 + Return v30 "); } @@ -5094,23 +5408,29 @@ mod tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject, v1:BasicObject): - v2:NilClass = Const Value(nil) - CheckInterrupts - v8:CBool = Test v1 - IfFalse v8, bb1(v0, v1, v2) - v12:Fixnum[3] = Const Value(3) + bb0(v1:BasicObject, v2:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:BasicObject): + EntryPoint JIT + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:BasicObject): + v10:NilClass = Const Value(nil) + CheckInterrupts + v16:CBool = Test v9 + IfFalse v16, bb3(v8, v9, v10) + v20:Fixnum[3] = Const Value(3) PatchPoint NoEPEscape(test) CheckInterrupts - Jump bb2(v0, v1, v12) - bb1(v18:BasicObject, v19:BasicObject, v20:NilClass): - v24:Fixnum[4] = Const Value(4) + Jump bb4(v8, v9, v20) + bb3(v26:BasicObject, v27:BasicObject, v28:NilClass): + v32:Fixnum[4] = Const Value(4) PatchPoint NoEPEscape(test) - Jump bb2(v18, v19, v24) - bb2(v28:BasicObject, v29:BasicObject, v30:Fixnum): + Jump bb4(v26, v27, v32) + bb4(v36:BasicObject, v37:BasicObject, v38:Fixnum): PatchPoint NoEPEscape(test) CheckInterrupts - Return v30 + Return v38 "); } @@ -5123,10 +5443,16 @@ mod tests { assert_contains_opcode("test", YARVINSN_opt_plus); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject, v1:BasicObject, v2:BasicObject): - v9:BasicObject = SendWithoutBlock v1, :+, v2 + bb0(v1:BasicObject, v2:BasicObject, v3:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2, v3) + bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): + EntryPoint JIT + Jump bb2(v6, v7, v8) + bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): + v19:BasicObject = SendWithoutBlock v11, :+, v12 CheckInterrupts - Return v9 + Return v19 "); } @@ -5139,10 +5465,16 @@ mod tests { assert_contains_opcode("test", YARVINSN_opt_minus); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject, v1:BasicObject, v2:BasicObject): - v9:BasicObject = SendWithoutBlock v1, :-, v2 + bb0(v1:BasicObject, v2:BasicObject, v3:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2, v3) + bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): + EntryPoint JIT + Jump bb2(v6, v7, v8) + bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): + v19:BasicObject = SendWithoutBlock v11, :-, v12 CheckInterrupts - Return v9 + Return v19 "); } @@ -5155,10 +5487,16 @@ mod tests { assert_contains_opcode("test", YARVINSN_opt_mult); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject, v1:BasicObject, v2:BasicObject): - v9:BasicObject = SendWithoutBlock v1, :*, v2 + bb0(v1:BasicObject, v2:BasicObject, v3:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2, v3) + bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): + EntryPoint JIT + Jump bb2(v6, v7, v8) + bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): + v19:BasicObject = SendWithoutBlock v11, :*, v12 CheckInterrupts - Return v9 + Return v19 "); } @@ -5171,10 +5509,16 @@ mod tests { assert_contains_opcode("test", YARVINSN_opt_div); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject, v1:BasicObject, v2:BasicObject): - v9:BasicObject = SendWithoutBlock v1, :/, v2 + bb0(v1:BasicObject, v2:BasicObject, v3:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2, v3) + bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): + EntryPoint JIT + Jump bb2(v6, v7, v8) + bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): + v19:BasicObject = SendWithoutBlock v11, :/, v12 CheckInterrupts - Return v9 + Return v19 "); } @@ -5187,10 +5531,16 @@ mod tests { assert_contains_opcode("test", YARVINSN_opt_mod); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject, v1:BasicObject, v2:BasicObject): - v9:BasicObject = SendWithoutBlock v1, :%, v2 + bb0(v1:BasicObject, v2:BasicObject, v3:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2, v3) + bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): + EntryPoint JIT + Jump bb2(v6, v7, v8) + bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): + v19:BasicObject = SendWithoutBlock v11, :%, v12 CheckInterrupts - Return v9 + Return v19 "); } @@ -5203,10 +5553,16 @@ mod tests { assert_contains_opcode("test", YARVINSN_opt_eq); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject, v1:BasicObject, v2:BasicObject): - v9:BasicObject = SendWithoutBlock v1, :==, v2 + bb0(v1:BasicObject, v2:BasicObject, v3:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2, v3) + bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): + EntryPoint JIT + Jump bb2(v6, v7, v8) + bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): + v19:BasicObject = SendWithoutBlock v11, :==, v12 CheckInterrupts - Return v9 + Return v19 "); } @@ -5219,10 +5575,16 @@ mod tests { assert_contains_opcode("test", YARVINSN_opt_neq); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject, v1:BasicObject, v2:BasicObject): - v9:BasicObject = SendWithoutBlock v1, :!=, v2 + bb0(v1:BasicObject, v2:BasicObject, v3:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2, v3) + bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): + EntryPoint JIT + Jump bb2(v6, v7, v8) + bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): + v19:BasicObject = SendWithoutBlock v11, :!=, v12 CheckInterrupts - Return v9 + Return v19 "); } @@ -5235,10 +5597,16 @@ mod tests { assert_contains_opcode("test", YARVINSN_opt_lt); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject, v1:BasicObject, v2:BasicObject): - v9:BasicObject = SendWithoutBlock v1, :<, v2 + bb0(v1:BasicObject, v2:BasicObject, v3:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2, v3) + bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): + EntryPoint JIT + Jump bb2(v6, v7, v8) + bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): + v19:BasicObject = SendWithoutBlock v11, :<, v12 CheckInterrupts - Return v9 + Return v19 "); } @@ -5251,10 +5619,16 @@ mod tests { assert_contains_opcode("test", YARVINSN_opt_le); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject, v1:BasicObject, v2:BasicObject): - v9:BasicObject = SendWithoutBlock v1, :<=, v2 + bb0(v1:BasicObject, v2:BasicObject, v3:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2, v3) + bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): + EntryPoint JIT + Jump bb2(v6, v7, v8) + bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): + v19:BasicObject = SendWithoutBlock v11, :<=, v12 CheckInterrupts - Return v9 + Return v19 "); } @@ -5267,10 +5641,16 @@ mod tests { assert_contains_opcode("test", YARVINSN_opt_gt); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject, v1:BasicObject, v2:BasicObject): - v9:BasicObject = SendWithoutBlock v1, :>, v2 + bb0(v1:BasicObject, v2:BasicObject, v3:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2, v3) + bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): + EntryPoint JIT + Jump bb2(v6, v7, v8) + bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): + v19:BasicObject = SendWithoutBlock v11, :>, v12 CheckInterrupts - Return v9 + Return v19 "); } @@ -5290,31 +5670,37 @@ mod tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject): - v1:NilClass = Const Value(nil) - v2:NilClass = Const Value(nil) - v6:Fixnum[0] = Const Value(0) - v9:Fixnum[10] = Const Value(10) - CheckInterrupts - Jump bb2(v0, v6, v9) - bb2(v15:BasicObject, v16:BasicObject, v17:BasicObject): + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v7:NilClass = Const Value(nil) + v8:NilClass = Const Value(nil) + v12:Fixnum[0] = Const Value(0) + v15:Fixnum[10] = Const Value(10) + CheckInterrupts + Jump bb4(v6, v12, v15) + bb4(v21:BasicObject, v22:BasicObject, v23:BasicObject): PatchPoint NoEPEscape(test) - v21:Fixnum[0] = Const Value(0) - v25:BasicObject = SendWithoutBlock v17, :>, v21 + v27:Fixnum[0] = Const Value(0) + v31:BasicObject = SendWithoutBlock v23, :>, v27 CheckInterrupts - v28:CBool = Test v25 - IfTrue v28, bb1(v15, v16, v17) - v30:NilClass = Const Value(nil) + v34:CBool = Test v31 + IfTrue v34, bb3(v21, v22, v23) + v36:NilClass = Const Value(nil) PatchPoint NoEPEscape(test) CheckInterrupts - Return v16 - bb1(v40:BasicObject, v41:BasicObject, v42:BasicObject): + Return v22 + bb3(v46:BasicObject, v47:BasicObject, v48:BasicObject): PatchPoint NoEPEscape(test) - v48:Fixnum[1] = Const Value(1) - v52:BasicObject = SendWithoutBlock v41, :+, v48 - v55:Fixnum[1] = Const Value(1) - v59:BasicObject = SendWithoutBlock v42, :-, v55 - Jump bb2(v40, v52, v59) + v54:Fixnum[1] = Const Value(1) + v58:BasicObject = SendWithoutBlock v47, :+, v54 + v61:Fixnum[1] = Const Value(1) + v65:BasicObject = SendWithoutBlock v48, :-, v61 + Jump bb4(v46, v58, v65) "); } @@ -5327,10 +5713,16 @@ mod tests { assert_contains_opcode("test", YARVINSN_opt_ge); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject, v1:BasicObject, v2:BasicObject): - v9:BasicObject = SendWithoutBlock v1, :>=, v2 + bb0(v1:BasicObject, v2:BasicObject, v3:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2, v3) + bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): + EntryPoint JIT + Jump bb2(v6, v7, v8) + bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): + v19:BasicObject = SendWithoutBlock v11, :>=, v12 CheckInterrupts - Return v9 + Return v19 "); } @@ -5348,19 +5740,25 @@ mod tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject): - v1:NilClass = Const Value(nil) - v5:TrueClass = Const Value(true) + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v7:NilClass = Const Value(nil) + v11:TrueClass = Const Value(true) CheckInterrupts - v10:CBool[true] = Test v5 - IfFalse v10, bb1(v0, v5) - v14:Fixnum[3] = Const Value(3) + v16:CBool[true] = Test v11 + IfFalse v16, bb3(v6, v11) + v20:Fixnum[3] = Const Value(3) CheckInterrupts - Return v14 - bb1(v20, v21): - v25 = Const Value(4) + Return v20 + bb3(v26, v27): + v31 = Const Value(4) CheckInterrupts - Return v25 + Return v31 "); } @@ -5377,12 +5775,18 @@ mod tests { assert_contains_opcode("test", YARVINSN_opt_send_without_block); assert_snapshot!(hir_string("test"), @r" fn test@:6: - bb0(v0:BasicObject): - v4:Fixnum[2] = Const Value(2) - v5:Fixnum[3] = Const Value(3) - v7:BasicObject = SendWithoutBlock v0, :bar, v4, v5 + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v10:Fixnum[2] = Const Value(2) + v11:Fixnum[3] = Const Value(3) + v13:BasicObject = SendWithoutBlock v6, :bar, v10, v11 CheckInterrupts - Return v7 + Return v13 "); } @@ -5399,12 +5803,18 @@ mod tests { assert_contains_opcode("test", YARVINSN_send); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject, v1:BasicObject): - v5:BasicObject = GetLocal l0, EP@3 - v7:BasicObject = Send v5, 0x1000, :each - v8:BasicObject = GetLocal l0, EP@3 + bb0(v1:BasicObject, v2:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:BasicObject): + EntryPoint JIT + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:BasicObject): + v13:BasicObject = GetLocal l0, EP@3 + v15:BasicObject = Send v13, 0x1000, :each + v16:BasicObject = GetLocal l0, EP@3 CheckInterrupts - Return v7 + Return v15 "); } @@ -5418,15 +5828,21 @@ mod tests { assert_contains_opcode("test", YARVINSN_intern); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject): - v4:StringExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) - v5:Fixnum[123] = Const Value(123) - v7:BasicObject = ObjToString v5 - v9:String = AnyToString v5, str: v7 - v11:StringExact = StringConcat v4, v9 - v13:Symbol = StringIntern v11 + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v10:StringExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) + v11:Fixnum[123] = Const Value(123) + v13:BasicObject = ObjToString v11 + v15:String = AnyToString v11, str: v13 + v17:StringExact = StringConcat v10, v15 + v19:Symbol = StringIntern v17 CheckInterrupts - Return v13 + Return v19 "); } @@ -5437,18 +5853,24 @@ mod tests { // The 2 string literals have the same address because they're deduped. assert_snapshot!(hir_string("test"), @r" fn test@:1: - bb0(v0:BasicObject): - v4:ArrayExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) - v6:ArrayExact = ArrayDup v4 - v7:ArrayExact[VALUE(0x1008)] = Const Value(VALUE(0x1008)) - v9:ArrayExact = ArrayDup v7 - v10:StringExact[VALUE(0x1010)] = Const Value(VALUE(0x1010)) - v12:StringExact = StringCopy v10 - v13:StringExact[VALUE(0x1010)] = Const Value(VALUE(0x1010)) - v15:StringExact = StringCopy v13 - v17:BasicObject = SendWithoutBlock v0, :unknown_method, v6, v9, v12, v15 + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v10:ArrayExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) + v12:ArrayExact = ArrayDup v10 + v13:ArrayExact[VALUE(0x1008)] = Const Value(VALUE(0x1008)) + v15:ArrayExact = ArrayDup v13 + v16:StringExact[VALUE(0x1010)] = Const Value(VALUE(0x1010)) + v18:StringExact = StringCopy v16 + v19:StringExact[VALUE(0x1010)] = Const Value(VALUE(0x1010)) + v21:StringExact = StringCopy v19 + v23:BasicObject = SendWithoutBlock v6, :unknown_method, v12, v15, v18, v21 CheckInterrupts - Return v17 + Return v23 "); } @@ -5459,8 +5881,14 @@ mod tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject, v1:BasicObject): - v6:ArrayExact = ToArray v1 + bb0(v1:BasicObject, v2:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:BasicObject): + EntryPoint JIT + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:BasicObject): + v14:ArrayExact = ToArray v9 SideExit UnhandledCallType(Splat) "); } @@ -5472,10 +5900,16 @@ mod tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject, v1:BasicObject): - v6:BasicObject = Send v0, 0x1000, :foo, v1 + bb0(v1:BasicObject, v2:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:BasicObject): + EntryPoint JIT + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:BasicObject): + v14:BasicObject = Send v8, 0x1000, :foo, v9 CheckInterrupts - Return v6 + Return v14 "); } @@ -5486,8 +5920,14 @@ mod tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject, v1:BasicObject): - v5:Fixnum[1] = Const Value(1) + bb0(v1:BasicObject, v2:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:BasicObject): + EntryPoint JIT + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:BasicObject): + v13:Fixnum[1] = Const Value(1) SideExit UnhandledCallType(Kwarg) "); } @@ -5499,10 +5939,16 @@ mod tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject, v1:BasicObject): - v6:BasicObject = SendWithoutBlock v0, :foo, v1 + bb0(v1:BasicObject, v2:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:BasicObject): + EntryPoint JIT + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:BasicObject): + v14:BasicObject = SendWithoutBlock v8, :foo, v9 CheckInterrupts - Return v6 + Return v14 "); } @@ -5515,10 +5961,16 @@ mod tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject): - v5:BasicObject = InvokeSuper v0, 0x1000 + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v11:BasicObject = InvokeSuper v6, 0x1000 CheckInterrupts - Return v5 + Return v11 "); } @@ -5529,10 +5981,16 @@ mod tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject): - v5:BasicObject = InvokeSuper v0, 0x1000 + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v11:BasicObject = InvokeSuper v6, 0x1000 CheckInterrupts - Return v5 + Return v11 "); } @@ -5543,11 +6001,17 @@ mod tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject): - v4:NilClass = Const Value(nil) - v6:BasicObject = InvokeSuper v0, 0x1000, v4 + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v10:NilClass = Const Value(nil) + v12:BasicObject = InvokeSuper v6, 0x1000, v10 CheckInterrupts - Return v6 + Return v12 "); } @@ -5558,7 +6022,13 @@ mod tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject, v1:BasicObject): + bb0(v1:BasicObject, v2:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:BasicObject): + EntryPoint JIT + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:BasicObject): SideExit UnhandledYARVInsn(invokesuperforward) "); } @@ -5568,10 +6038,16 @@ mod tests { eval("def forwardable(...) = nil"); assert_snapshot!(hir_string("forwardable"), @r" fn forwardable@:1: - bb0(v0:BasicObject, v1:BasicObject): - v5:NilClass = Const Value(nil) + bb0(v1:BasicObject, v2:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:BasicObject): + EntryPoint JIT + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:BasicObject): + v13:NilClass = Const Value(nil) CheckInterrupts - Return v5 + Return v13 "); } @@ -5584,18 +6060,24 @@ mod tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject, v1:BasicObject): - v5:Class[VMFrozenCore] = Const Value(VALUE(0x1000)) - v7:HashExact = NewHash + bb0(v1:BasicObject, v2:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:BasicObject): + EntryPoint JIT + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:BasicObject): + v13:Class[VMFrozenCore] = Const Value(VALUE(0x1000)) + v15:HashExact = NewHash PatchPoint NoEPEscape(test) - v11:BasicObject = SendWithoutBlock v5, :core#hash_merge_kwd, v7, v1 - v12:Class[VMFrozenCore] = Const Value(VALUE(0x1000)) - v13:StaticSymbol[:b] = Const Value(VALUE(0x1008)) - v14:Fixnum[1] = Const Value(1) - v16:BasicObject = SendWithoutBlock v12, :core#hash_merge_ptr, v11, v13, v14 - v18:BasicObject = SendWithoutBlock v0, :foo, v16 + v19:BasicObject = SendWithoutBlock v13, :core#hash_merge_kwd, v15, v9 + v20:Class[VMFrozenCore] = Const Value(VALUE(0x1000)) + v21:StaticSymbol[:b] = Const Value(VALUE(0x1008)) + v22:Fixnum[1] = Const Value(1) + v24:BasicObject = SendWithoutBlock v20, :core#hash_merge_ptr, v19, v21, v22 + v26:BasicObject = SendWithoutBlock v8, :foo, v24 CheckInterrupts - Return v18 + Return v26 "); } @@ -5606,10 +6088,16 @@ mod tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject, v1:ArrayExact): - v6:ArrayExact = ToNewArray v1 - v7:Fixnum[1] = Const Value(1) - ArrayPush v6, v7 + bb0(v1:BasicObject, v2:ArrayExact): + EntryPoint interpreter + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:ArrayExact): + EntryPoint JIT + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:ArrayExact): + v14:ArrayExact = ToNewArray v9 + v15:Fixnum[1] = Const Value(1) + ArrayPush v14, v15 SideExit UnhandledCallType(Splat) "); } @@ -5621,10 +6109,16 @@ mod tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject, v1:BasicObject): - v6:BasicObject = SendForward 0x1000, :foo, v1 + bb0(v1:BasicObject, v2:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:BasicObject): + EntryPoint JIT + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:BasicObject): + v14:BasicObject = SendForward 0x1000, :foo, v9 CheckInterrupts - Return v6 + Return v14 "); } @@ -5635,12 +6129,18 @@ mod tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject, v1:BasicObject, v2:ArrayExact, v3:BasicObject, v4:BasicObject): - v5:NilClass = Const Value(nil) - v10:ArrayExact = ToArray v2 + bb0(v1:BasicObject, v2:BasicObject, v3:ArrayExact, v4:BasicObject, v5:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2, v3, v4, v5) + bb1(v8:BasicObject, v9:BasicObject, v10:ArrayExact, v11:BasicObject, v12:BasicObject): + EntryPoint JIT + Jump bb2(v8, v9, v10, v11, v12) + bb2(v14:BasicObject, v15:BasicObject, v16:ArrayExact, v17:BasicObject, v18:BasicObject): + v19:NilClass = Const Value(nil) + v24:ArrayExact = ToArray v16 PatchPoint NoEPEscape(test) GuardBlockParamProxy l0 - v15:HeapObject[BlockParamProxy] = Const Value(VALUE(0x1000)) + v29:HeapObject[BlockParamProxy] = Const Value(VALUE(0x1000)) SideExit UnhandledYARVInsn(splatkw) "); } @@ -5654,21 +6154,27 @@ mod tests { assert_contains_opcode("test", YARVINSN_opt_new); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject): - v5:BasicObject = GetConstantPath 0x1000 - v6:NilClass = Const Value(nil) - v8:CBool = IsMethodCFunc v5, :new - IfFalse v8, bb1(v0, v6, v5) - v10:HeapObject = ObjectAlloc v5 - v12:BasicObject = SendWithoutBlock v10, :initialize - CheckInterrupts - Jump bb2(v0, v10, v12) - bb1(v16:BasicObject, v17:NilClass, v18:BasicObject): - v21:BasicObject = SendWithoutBlock v18, :new - Jump bb2(v16, v21, v17) - bb2(v23:BasicObject, v24:BasicObject, v25:BasicObject): + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v11:BasicObject = GetConstantPath 0x1000 + v12:NilClass = Const Value(nil) + v14:CBool = IsMethodCFunc v11, :new + IfFalse v14, bb3(v6, v12, v11) + v16:HeapObject = ObjectAlloc v11 + v18:BasicObject = SendWithoutBlock v16, :initialize + CheckInterrupts + Jump bb4(v6, v16, v18) + bb3(v22:BasicObject, v23:NilClass, v24:BasicObject): + v27:BasicObject = SendWithoutBlock v24, :new + Jump bb4(v22, v27, v23) + bb4(v29:BasicObject, v30:BasicObject, v31:BasicObject): CheckInterrupts - Return v24 + Return v30 "); } @@ -5681,11 +6187,17 @@ mod tests { assert_contains_opcode("test", YARVINSN_opt_newarray_send); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject): + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): PatchPoint BOPRedefined(ARRAY_REDEFINED_OP_FLAG, BOP_MAX) - v6:BasicObject = ArrayMax + v12:BasicObject = ArrayMax CheckInterrupts - Return v6 + Return v12 "); } @@ -5697,11 +6209,17 @@ mod tests { assert_contains_opcode("test", YARVINSN_opt_newarray_send); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject, v1:BasicObject, v2:BasicObject): + bb0(v1:BasicObject, v2:BasicObject, v3:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2, v3) + bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): + EntryPoint JIT + Jump bb2(v6, v7, v8) + bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): PatchPoint BOPRedefined(ARRAY_REDEFINED_OP_FLAG, BOP_MAX) - v8:BasicObject = ArrayMax v1, v2 + v18:BasicObject = ArrayMax v11, v12 CheckInterrupts - Return v8 + Return v18 "); } @@ -5718,10 +6236,16 @@ mod tests { assert_contains_opcode("test", YARVINSN_opt_newarray_send); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject, v1:BasicObject, v2:BasicObject): - v3:NilClass = Const Value(nil) - v4:NilClass = Const Value(nil) - v11:BasicObject = SendWithoutBlock v1, :+, v2 + bb0(v1:BasicObject, v2:BasicObject, v3:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2, v3) + bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): + EntryPoint JIT + Jump bb2(v6, v7, v8) + bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): + v13:NilClass = Const Value(nil) + v14:NilClass = Const Value(nil) + v21:BasicObject = SendWithoutBlock v11, :+, v12 SideExit UnknownNewarraySend(MIN) "); } @@ -5739,10 +6263,16 @@ mod tests { assert_contains_opcode("test", YARVINSN_opt_newarray_send); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject, v1:BasicObject, v2:BasicObject): - v3:NilClass = Const Value(nil) - v4:NilClass = Const Value(nil) - v11:BasicObject = SendWithoutBlock v1, :+, v2 + bb0(v1:BasicObject, v2:BasicObject, v3:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2, v3) + bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): + EntryPoint JIT + Jump bb2(v6, v7, v8) + bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): + v13:NilClass = Const Value(nil) + v14:NilClass = Const Value(nil) + v21:BasicObject = SendWithoutBlock v11, :+, v12 SideExit UnknownNewarraySend(HASH) "); } @@ -5760,12 +6290,18 @@ mod tests { assert_contains_opcode("test", YARVINSN_opt_newarray_send); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject, v1:BasicObject, v2:BasicObject): - v3:NilClass = Const Value(nil) - v4:NilClass = Const Value(nil) - v11:BasicObject = SendWithoutBlock v1, :+, v2 - v14:StringExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) - v16:StringExact = StringCopy v14 + bb0(v1:BasicObject, v2:BasicObject, v3:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2, v3) + bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): + EntryPoint JIT + Jump bb2(v6, v7, v8) + bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): + v13:NilClass = Const Value(nil) + v14:NilClass = Const Value(nil) + v21:BasicObject = SendWithoutBlock v11, :+, v12 + v24:StringExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) + v26:StringExact = StringCopy v24 SideExit UnknownNewarraySend(PACK) "); } @@ -5785,10 +6321,16 @@ mod tests { assert_contains_opcode("test", YARVINSN_opt_newarray_send); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject, v1:BasicObject, v2:BasicObject): - v3:NilClass = Const Value(nil) - v4:NilClass = Const Value(nil) - v11:BasicObject = SendWithoutBlock v1, :+, v2 + bb0(v1:BasicObject, v2:BasicObject, v3:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2, v3) + bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): + EntryPoint JIT + Jump bb2(v6, v7, v8) + bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): + v13:NilClass = Const Value(nil) + v14:NilClass = Const Value(nil) + v21:BasicObject = SendWithoutBlock v11, :+, v12 SideExit UnknownNewarraySend(INCLUDE_P) "); } @@ -5801,11 +6343,17 @@ mod tests { assert_contains_opcode("test", YARVINSN_opt_length); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject, v1:BasicObject, v2:BasicObject): - v7:ArrayExact = NewArray v1, v2 - v11:BasicObject = SendWithoutBlock v7, :length + bb0(v1:BasicObject, v2:BasicObject, v3:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2, v3) + bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): + EntryPoint JIT + Jump bb2(v6, v7, v8) + bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): + v17:ArrayExact = NewArray v11, v12 + v21:BasicObject = SendWithoutBlock v17, :length CheckInterrupts - Return v11 + Return v21 "); } @@ -5817,11 +6365,17 @@ mod tests { assert_contains_opcode("test", YARVINSN_opt_size); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject, v1:BasicObject, v2:BasicObject): - v7:ArrayExact = NewArray v1, v2 - v11:BasicObject = SendWithoutBlock v7, :size + bb0(v1:BasicObject, v2:BasicObject, v3:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2, v3) + bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): + EntryPoint JIT + Jump bb2(v6, v7, v8) + bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): + v17:ArrayExact = NewArray v11, v12 + v21:BasicObject = SendWithoutBlock v17, :size CheckInterrupts - Return v11 + Return v21 "); } @@ -5834,11 +6388,17 @@ mod tests { assert_contains_opcode("test", YARVINSN_getinstancevariable); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject): + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): PatchPoint SingleRactorMode - v6:BasicObject = GetIvar v0, :@foo + v12:BasicObject = GetIvar v6, :@foo CheckInterrupts - Return v6 + Return v12 "); } @@ -5851,12 +6411,18 @@ mod tests { assert_contains_opcode("test", YARVINSN_setinstancevariable); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject): - v4:Fixnum[1] = Const Value(1) + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v10:Fixnum[1] = Const Value(1) PatchPoint SingleRactorMode - SetIvar v0, :@foo, v4 + SetIvar v6, :@foo, v10 CheckInterrupts - Return v4 + Return v10 "); } @@ -5869,11 +6435,17 @@ mod tests { assert_contains_opcode("test", YARVINSN_setglobal); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject): - v4:Fixnum[1] = Const Value(1) - SetGlobal :$foo, v4 + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v10:Fixnum[1] = Const Value(1) + SetGlobal :$foo, v10 CheckInterrupts - Return v4 + Return v10 "); } @@ -5886,10 +6458,16 @@ mod tests { assert_contains_opcode("test", YARVINSN_getglobal); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject): - v5:BasicObject = GetGlobal :$foo + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v11:BasicObject = GetGlobal :$foo CheckInterrupts - Return v5 + Return v11 "); } @@ -5901,10 +6479,16 @@ mod tests { assert_contains_opcode("test", YARVINSN_splatarray); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject, v1:BasicObject): - v6:ArrayExact = ToNewArray v1 + bb0(v1:BasicObject, v2:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:BasicObject): + EntryPoint JIT + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:BasicObject): + v14:ArrayExact = ToNewArray v9 CheckInterrupts - Return v6 + Return v14 "); } @@ -5916,13 +6500,19 @@ mod tests { assert_contains_opcode("test", YARVINSN_concattoarray); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject, v1:BasicObject): - v5:Fixnum[1] = Const Value(1) - v7:ArrayExact = NewArray v5 - v9:ArrayExact = ToArray v1 - ArrayExtend v7, v9 + bb0(v1:BasicObject, v2:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:BasicObject): + EntryPoint JIT + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:BasicObject): + v13:Fixnum[1] = Const Value(1) + v15:ArrayExact = NewArray v13 + v17:ArrayExact = ToArray v9 + ArrayExtend v15, v17 CheckInterrupts - Return v7 + Return v15 "); } @@ -5934,12 +6524,18 @@ mod tests { assert_contains_opcode("test", YARVINSN_pushtoarray); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject, v1:BasicObject): - v6:ArrayExact = ToNewArray v1 - v7:Fixnum[1] = Const Value(1) - ArrayPush v6, v7 + bb0(v1:BasicObject, v2:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:BasicObject): + EntryPoint JIT + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:BasicObject): + v14:ArrayExact = ToNewArray v9 + v15:Fixnum[1] = Const Value(1) + ArrayPush v14, v15 CheckInterrupts - Return v6 + Return v14 "); } @@ -5951,16 +6547,22 @@ mod tests { assert_contains_opcode("test", YARVINSN_pushtoarray); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject, v1:BasicObject): - v6:ArrayExact = ToNewArray v1 - v7:Fixnum[1] = Const Value(1) - v8:Fixnum[2] = Const Value(2) - v9:Fixnum[3] = Const Value(3) - ArrayPush v6, v7 - ArrayPush v6, v8 - ArrayPush v6, v9 + bb0(v1:BasicObject, v2:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:BasicObject): + EntryPoint JIT + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:BasicObject): + v14:ArrayExact = ToNewArray v9 + v15:Fixnum[1] = Const Value(1) + v16:Fixnum[2] = Const Value(2) + v17:Fixnum[3] = Const Value(3) + ArrayPush v14, v15 + ArrayPush v14, v16 + ArrayPush v14, v17 CheckInterrupts - Return v6 + Return v14 "); } @@ -5972,12 +6574,18 @@ mod tests { assert_contains_opcode("test", YARVINSN_opt_aset); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject, v1:BasicObject, v2:BasicObject): - v6:NilClass = Const Value(nil) - v7:Fixnum[1] = Const Value(1) - v11:BasicObject = SendWithoutBlock v1, :[]=, v2, v7 + bb0(v1:BasicObject, v2:BasicObject, v3:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2, v3) + bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): + EntryPoint JIT + Jump bb2(v6, v7, v8) + bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): + v16:NilClass = Const Value(nil) + v17:Fixnum[1] = Const Value(1) + v21:BasicObject = SendWithoutBlock v11, :[]=, v12, v17 CheckInterrupts - Return v7 + Return v17 "); } @@ -5989,10 +6597,16 @@ mod tests { assert_contains_opcode("test", YARVINSN_opt_aref); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject, v1:BasicObject, v2:BasicObject): - v9:BasicObject = SendWithoutBlock v1, :[], v2 + bb0(v1:BasicObject, v2:BasicObject, v3:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2, v3) + bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): + EntryPoint JIT + Jump bb2(v6, v7, v8) + bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): + v19:BasicObject = SendWithoutBlock v11, :[], v12 CheckInterrupts - Return v9 + Return v19 "); } @@ -6004,10 +6618,16 @@ mod tests { assert_contains_opcode("test", YARVINSN_opt_empty_p); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject, v1:BasicObject): - v8:BasicObject = SendWithoutBlock v1, :empty? + bb0(v1:BasicObject, v2:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:BasicObject): + EntryPoint JIT + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:BasicObject): + v16:BasicObject = SendWithoutBlock v9, :empty? CheckInterrupts - Return v8 + Return v16 "); } @@ -6019,10 +6639,16 @@ mod tests { assert_contains_opcode("test", YARVINSN_opt_succ); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject, v1:BasicObject): - v8:BasicObject = SendWithoutBlock v1, :succ + bb0(v1:BasicObject, v2:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:BasicObject): + EntryPoint JIT + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:BasicObject): + v16:BasicObject = SendWithoutBlock v9, :succ CheckInterrupts - Return v8 + Return v16 "); } @@ -6034,10 +6660,16 @@ mod tests { assert_contains_opcode("test", YARVINSN_opt_and); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject, v1:BasicObject, v2:BasicObject): - v9:BasicObject = SendWithoutBlock v1, :&, v2 + bb0(v1:BasicObject, v2:BasicObject, v3:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2, v3) + bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): + EntryPoint JIT + Jump bb2(v6, v7, v8) + bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): + v19:BasicObject = SendWithoutBlock v11, :&, v12 CheckInterrupts - Return v9 + Return v19 "); } @@ -6049,10 +6681,16 @@ mod tests { assert_contains_opcode("test", YARVINSN_opt_or); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject, v1:BasicObject, v2:BasicObject): - v9:BasicObject = SendWithoutBlock v1, :|, v2 + bb0(v1:BasicObject, v2:BasicObject, v3:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2, v3) + bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): + EntryPoint JIT + Jump bb2(v6, v7, v8) + bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): + v19:BasicObject = SendWithoutBlock v11, :|, v12 CheckInterrupts - Return v9 + Return v19 "); } @@ -6064,10 +6702,16 @@ mod tests { assert_contains_opcode("test", YARVINSN_opt_not); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject, v1:BasicObject): - v8:BasicObject = SendWithoutBlock v1, :! + bb0(v1:BasicObject, v2:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:BasicObject): + EntryPoint JIT + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:BasicObject): + v16:BasicObject = SendWithoutBlock v9, :! CheckInterrupts - Return v8 + Return v16 "); } @@ -6079,10 +6723,16 @@ mod tests { assert_contains_opcode("test", YARVINSN_opt_regexpmatch2); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject, v1:BasicObject, v2:BasicObject): - v9:BasicObject = SendWithoutBlock v1, :=~, v2 + bb0(v1:BasicObject, v2:BasicObject, v3:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2, v3) + bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): + EntryPoint JIT + Jump bb2(v6, v7, v8) + bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): + v19:BasicObject = SendWithoutBlock v11, :=~, v12 CheckInterrupts - Return v9 + Return v19 "); } @@ -6098,14 +6748,20 @@ mod tests { assert_contains_opcode("test", YARVINSN_putspecialobject); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject): - v4:Class[VMFrozenCore] = Const Value(VALUE(0x1000)) - v5:BasicObject = PutSpecialObject CBase - v6:StaticSymbol[:aliased] = Const Value(VALUE(0x1008)) - v7:StaticSymbol[:__callee__] = Const Value(VALUE(0x1010)) - v9:BasicObject = SendWithoutBlock v4, :core#set_method_alias, v5, v6, v7 + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v10:Class[VMFrozenCore] = Const Value(VALUE(0x1000)) + v11:BasicObject = PutSpecialObject CBase + v12:StaticSymbol[:aliased] = Const Value(VALUE(0x1008)) + v13:StaticSymbol[:__callee__] = Const Value(VALUE(0x1010)) + v15:BasicObject = SendWithoutBlock v10, :core#set_method_alias, v11, v12, v13 CheckInterrupts - Return v9 + Return v15 "); } @@ -6125,41 +6781,53 @@ mod tests { assert_contains_opcode("reverse_odd", YARVINSN_opt_reverse); assert_snapshot!(hir_string("reverse_odd"), @r" fn reverse_odd@:3: - bb0(v0:BasicObject): - v1:NilClass = Const Value(nil) - v2:NilClass = Const Value(nil) - v3:NilClass = Const Value(nil) + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v7:NilClass = Const Value(nil) + v8:NilClass = Const Value(nil) + v9:NilClass = Const Value(nil) PatchPoint SingleRactorMode - v9:BasicObject = GetIvar v0, :@a + v15:BasicObject = GetIvar v6, :@a PatchPoint SingleRactorMode - v12:BasicObject = GetIvar v0, :@b + v18:BasicObject = GetIvar v6, :@b PatchPoint SingleRactorMode - v15:BasicObject = GetIvar v0, :@c + v21:BasicObject = GetIvar v6, :@c PatchPoint NoEPEscape(reverse_odd) - v21:ArrayExact = NewArray v9, v12, v15 + v27:ArrayExact = NewArray v15, v18, v21 CheckInterrupts - Return v21 + Return v27 "); assert_contains_opcode("reverse_even", YARVINSN_opt_reverse); assert_snapshot!(hir_string("reverse_even"), @r" fn reverse_even@:8: - bb0(v0:BasicObject): - v1:NilClass = Const Value(nil) - v2:NilClass = Const Value(nil) - v3:NilClass = Const Value(nil) - v4:NilClass = Const Value(nil) + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v7:NilClass = Const Value(nil) + v8:NilClass = Const Value(nil) + v9:NilClass = Const Value(nil) + v10:NilClass = Const Value(nil) PatchPoint SingleRactorMode - v10:BasicObject = GetIvar v0, :@a + v16:BasicObject = GetIvar v6, :@a PatchPoint SingleRactorMode - v13:BasicObject = GetIvar v0, :@b + v19:BasicObject = GetIvar v6, :@b PatchPoint SingleRactorMode - v16:BasicObject = GetIvar v0, :@c + v22:BasicObject = GetIvar v6, :@c PatchPoint SingleRactorMode - v19:BasicObject = GetIvar v0, :@d + v25:BasicObject = GetIvar v6, :@d PatchPoint NoEPEscape(reverse_even) - v25:ArrayExact = NewArray v10, v13, v16, v19 + v31:ArrayExact = NewArray v16, v19, v22, v25 CheckInterrupts - Return v25 + Return v31 "); } @@ -6171,15 +6839,21 @@ mod tests { assert_contains_opcode("test", YARVINSN_branchnil); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject, v1:BasicObject): + bb0(v1:BasicObject, v2:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:BasicObject): + EntryPoint JIT + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:BasicObject): + CheckInterrupts + v15:CBool = IsNil v9 + IfTrue v15, bb3(v8, v9, v9) + v18:BasicObject = SendWithoutBlock v9, :itself + Jump bb3(v8, v9, v18) + bb3(v20:BasicObject, v21:BasicObject, v22:BasicObject): CheckInterrupts - v7:CBool = IsNil v1 - IfTrue v7, bb1(v0, v1, v1) - v10:BasicObject = SendWithoutBlock v1, :itself - Jump bb1(v0, v1, v10) - bb1(v12:BasicObject, v13:BasicObject, v14:BasicObject): - CheckInterrupts - Return v14 + Return v22 "); } @@ -6188,12 +6862,18 @@ mod tests { assert_contains_opcode("Float", YARVINSN_opt_invokebuiltin_delegate_leave); assert_snapshot!(hir_string("Float"), @r" fn Float@: - bb0(v0:BasicObject, v1:BasicObject, v2:BasicObject, v3:BasicObject): - v8:Float = InvokeBuiltin rb_f_float, v0, v1, v2 - Jump bb1(v0, v1, v2, v3, v8) - bb1(v10:BasicObject, v11:BasicObject, v12:BasicObject, v13:BasicObject, v14:Float): + bb0(v1:BasicObject, v2:BasicObject, v3:BasicObject, v4:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2, v3, v4) + bb1(v7:BasicObject, v8:BasicObject, v9:BasicObject, v10:BasicObject): + EntryPoint JIT + Jump bb2(v7, v8, v9, v10) + bb2(v12:BasicObject, v13:BasicObject, v14:BasicObject, v15:BasicObject): + v20:Float = InvokeBuiltin rb_f_float, v12, v13, v14 + Jump bb3(v12, v13, v14, v15, v20) + bb3(v22:BasicObject, v23:BasicObject, v24:BasicObject, v25:BasicObject, v26:Float): CheckInterrupts - Return v14 + Return v26 "); } @@ -6202,12 +6882,18 @@ mod tests { assert_contains_opcode("class", YARVINSN_opt_invokebuiltin_delegate_leave); assert_snapshot!(hir_string("class"), @r" fn class@: - bb0(v0:BasicObject): - v5:Class = InvokeBuiltin _bi20, v0 - Jump bb1(v0, v5) - bb1(v7:BasicObject, v8:Class): + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v11:Class = InvokeBuiltin _bi20, v6 + Jump bb3(v6, v11) + bb3(v13:BasicObject, v14:Class): CheckInterrupts - Return v8 + Return v14 "); } @@ -6219,24 +6905,30 @@ mod tests { let function = iseq_to_hir(iseq).unwrap(); assert_snapshot!(hir_string_function(&function), @r" fn open@: - bb0(v0:BasicObject, v1:BasicObject, v2:BasicObject, v3:BasicObject, v4:BasicObject): - v5:NilClass = Const Value(nil) - v10:BasicObject = InvokeBuiltin dir_s_open, v0, v1, v2 + bb0(v1:BasicObject, v2:BasicObject, v3:BasicObject, v4:BasicObject, v5:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2, v3, v4, v5) + bb1(v8:BasicObject, v9:BasicObject, v10:BasicObject, v11:BasicObject, v12:BasicObject): + EntryPoint JIT + Jump bb2(v8, v9, v10, v11, v12) + bb2(v14:BasicObject, v15:BasicObject, v16:BasicObject, v17:BasicObject, v18:BasicObject): + v19:NilClass = Const Value(nil) + v24:BasicObject = InvokeBuiltin dir_s_open, v14, v15, v16 PatchPoint NoEPEscape(open) GuardBlockParamProxy l0 - v17:HeapObject[BlockParamProxy] = Const Value(VALUE(0x1000)) + v31:HeapObject[BlockParamProxy] = Const Value(VALUE(0x1000)) CheckInterrupts - v20:CBool[true] = Test v17 - IfFalse v20, bb1(v0, v1, v2, v3, v4, v10) + v34:CBool[true] = Test v31 + IfFalse v34, bb3(v14, v15, v16, v17, v18, v24) PatchPoint NoEPEscape(open) - v27:BasicObject = InvokeBlock, v10 - v31:BasicObject = InvokeBuiltin dir_s_close, v0, v10 + v41:BasicObject = InvokeBlock, v24 + v45:BasicObject = InvokeBuiltin dir_s_close, v14, v24 CheckInterrupts - Return v27 - bb1(v37, v38, v39, v40, v41, v42): + Return v41 + bb3(v51, v52, v53, v54, v55, v56): PatchPoint NoEPEscape(open) CheckInterrupts - Return v42 + Return v56 "); } @@ -6247,12 +6939,18 @@ mod tests { let function = iseq_to_hir(iseq).unwrap(); assert_snapshot!(hir_string_function(&function), @r" fn enable@: - bb0(v0:BasicObject): - v5:BasicObject = InvokeBuiltin gc_enable, v0 - Jump bb1(v0, v5) - bb1(v7:BasicObject, v8:BasicObject): + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v11:BasicObject = InvokeBuiltin gc_enable, v6 + Jump bb3(v6, v11) + bb3(v13:BasicObject, v14:BasicObject): CheckInterrupts - Return v8 + Return v14 "); } @@ -6263,11 +6961,17 @@ mod tests { let function = iseq_to_hir(iseq).unwrap(); assert_snapshot!(hir_string_function(&function), @r" fn start@: - bb0(v0:BasicObject, v1:BasicObject, v2:BasicObject, v3:BasicObject, v4:BasicObject): - v8:FalseClass = Const Value(false) - v10:BasicObject = InvokeBuiltin gc_start_internal, v0, v1, v2, v3, v8 + bb0(v1:BasicObject, v2:BasicObject, v3:BasicObject, v4:BasicObject, v5:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2, v3, v4, v5) + bb1(v8:BasicObject, v9:BasicObject, v10:BasicObject, v11:BasicObject, v12:BasicObject): + EntryPoint JIT + Jump bb2(v8, v9, v10, v11, v12) + bb2(v14:BasicObject, v15:BasicObject, v16:BasicObject, v17:BasicObject, v18:BasicObject): + v22:FalseClass = Const Value(false) + v24:BasicObject = InvokeBuiltin gc_start_internal, v14, v15, v16, v17, v22 CheckInterrupts - Return v10 + Return v24 "); } @@ -6279,21 +6983,27 @@ mod tests { assert_contains_opcode("test", YARVINSN_dupn); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject, v1:BasicObject): - v5:NilClass = Const Value(nil) - v6:Fixnum[0] = Const Value(0) - v7:Fixnum[1] = Const Value(1) - v9:BasicObject = SendWithoutBlock v1, :[], v6, v7 + bb0(v1:BasicObject, v2:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:BasicObject): + EntryPoint JIT + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:BasicObject): + v13:NilClass = Const Value(nil) + v14:Fixnum[0] = Const Value(0) + v15:Fixnum[1] = Const Value(1) + v17:BasicObject = SendWithoutBlock v9, :[], v14, v15 + CheckInterrupts + v20:CBool = Test v17 + IfTrue v20, bb3(v8, v9, v13, v9, v14, v15, v17) + v22:Fixnum[2] = Const Value(2) + v24:BasicObject = SendWithoutBlock v9, :[]=, v14, v15, v22 CheckInterrupts - v12:CBool = Test v9 - IfTrue v12, bb1(v0, v1, v5, v1, v6, v7, v9) - v14:Fixnum[2] = Const Value(2) - v16:BasicObject = SendWithoutBlock v1, :[]=, v6, v7, v14 - CheckInterrupts - Return v14 - bb1(v22:BasicObject, v23:BasicObject, v24:NilClass, v25:BasicObject, v26:Fixnum[0], v27:Fixnum[1], v28:BasicObject): + Return v22 + bb3(v30:BasicObject, v31:BasicObject, v32:NilClass, v33:BasicObject, v34:Fixnum[0], v35:Fixnum[1], v36:BasicObject): CheckInterrupts - Return v28 + Return v36 "); } @@ -6305,14 +7015,20 @@ mod tests { assert_contains_opcode("test", YARVINSN_objtostring); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject): - v4:StringExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) - v5:Fixnum[1] = Const Value(1) - v7:BasicObject = ObjToString v5 - v9:String = AnyToString v5, str: v7 - v11:StringExact = StringConcat v4, v9 + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v10:StringExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) + v11:Fixnum[1] = Const Value(1) + v13:BasicObject = ObjToString v11 + v15:String = AnyToString v11, str: v13 + v17:StringExact = StringConcat v10, v15 CheckInterrupts - Return v11 + Return v17 "); } @@ -6324,19 +7040,25 @@ mod tests { assert_contains_opcode("test", YARVINSN_concatstrings); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject): - v4:Fixnum[1] = Const Value(1) - v6:BasicObject = ObjToString v4 - v8:String = AnyToString v4, str: v6 - v9:Fixnum[2] = Const Value(2) - v11:BasicObject = ObjToString v9 - v13:String = AnyToString v9, str: v11 - v14:Fixnum[3] = Const Value(3) - v16:BasicObject = ObjToString v14 - v18:String = AnyToString v14, str: v16 - v20:StringExact = StringConcat v8, v13, v18 + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v10:Fixnum[1] = Const Value(1) + v12:BasicObject = ObjToString v10 + v14:String = AnyToString v10, str: v12 + v15:Fixnum[2] = Const Value(2) + v17:BasicObject = ObjToString v15 + v19:String = AnyToString v15, str: v17 + v20:Fixnum[3] = Const Value(3) + v22:BasicObject = ObjToString v20 + v24:String = AnyToString v20, str: v22 + v26:StringExact = StringConcat v14, v19, v24 CheckInterrupts - Return v20 + Return v26 "); } @@ -6348,14 +7070,20 @@ mod tests { assert_contains_opcode("test", YARVINSN_concatstrings); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject): - v4:StringExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) - v5:NilClass = Const Value(nil) - v7:BasicObject = ObjToString v5 - v9:String = AnyToString v5, str: v7 - v11:StringExact = StringConcat v4, v9 + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v10:StringExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) + v11:NilClass = Const Value(nil) + v13:BasicObject = ObjToString v11 + v15:String = AnyToString v11, str: v13 + v17:StringExact = StringConcat v10, v15 CheckInterrupts - Return v11 + Return v17 "); } @@ -6367,19 +7095,25 @@ mod tests { assert_contains_opcode("test", YARVINSN_toregexp); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject): - v4:Fixnum[1] = Const Value(1) - v6:BasicObject = ObjToString v4 - v8:String = AnyToString v4, str: v6 - v9:Fixnum[2] = Const Value(2) - v11:BasicObject = ObjToString v9 - v13:String = AnyToString v9, str: v11 - v14:Fixnum[3] = Const Value(3) - v16:BasicObject = ObjToString v14 - v18:String = AnyToString v14, str: v16 - v20:RegexpExact = ToRegexp v8, v13, v18 + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v10:Fixnum[1] = Const Value(1) + v12:BasicObject = ObjToString v10 + v14:String = AnyToString v10, str: v12 + v15:Fixnum[2] = Const Value(2) + v17:BasicObject = ObjToString v15 + v19:String = AnyToString v15, str: v17 + v20:Fixnum[3] = Const Value(3) + v22:BasicObject = ObjToString v20 + v24:String = AnyToString v20, str: v22 + v26:RegexpExact = ToRegexp v14, v19, v24 CheckInterrupts - Return v20 + Return v26 "); } @@ -6391,16 +7125,22 @@ mod tests { assert_contains_opcode("test", YARVINSN_toregexp); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject): - v4:Fixnum[1] = Const Value(1) - v6:BasicObject = ObjToString v4 - v8:String = AnyToString v4, str: v6 - v9:Fixnum[2] = Const Value(2) - v11:BasicObject = ObjToString v9 - v13:String = AnyToString v9, str: v11 - v15:RegexpExact = ToRegexp v8, v13, MULTILINE|IGNORECASE|EXTENDED|NOENCODING + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v10:Fixnum[1] = Const Value(1) + v12:BasicObject = ObjToString v10 + v14:String = AnyToString v10, str: v12 + v15:Fixnum[2] = Const Value(2) + v17:BasicObject = ObjToString v15 + v19:String = AnyToString v15, str: v17 + v21:RegexpExact = ToRegexp v14, v19, MULTILINE|IGNORECASE|EXTENDED|NOENCODING CheckInterrupts - Return v15 + Return v21 "); } @@ -6413,16 +7153,28 @@ mod tests { assert_contains_opcode("throw_return", YARVINSN_throw); assert_snapshot!(hir_string("throw_return"), @r" fn block in @:2: - bb0(v0:BasicObject): - v6:Fixnum[1] = Const Value(1) - Throw TAG_RETURN, v6 + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v12:Fixnum[1] = Const Value(1) + Throw TAG_RETURN, v12 "); assert_contains_opcode("throw_break", YARVINSN_throw); assert_snapshot!(hir_string("throw_break"), @r" fn block in @:3: - bb0(v0:BasicObject): - v6:Fixnum[2] = Const Value(2) - Throw TAG_BREAK, v6 + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v12:Fixnum[2] = Const Value(2) + Throw TAG_BREAK, v12 "); } @@ -6435,10 +7187,16 @@ mod tests { "#); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject): - v5:BasicObject = InvokeBlock + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v11:BasicObject = InvokeBlock CheckInterrupts - Return v5 + Return v11 "); } @@ -6451,10 +7209,16 @@ mod tests { "#); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject, v1:BasicObject, v2:BasicObject): - v7:BasicObject = InvokeBlock, v1, v2 + bb0(v1:BasicObject, v2:BasicObject, v3:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2, v3) + bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): + EntryPoint JIT + Jump bb2(v6, v7, v8) + bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): + v17:BasicObject = InvokeBlock, v11, v12 CheckInterrupts - Return v7 + Return v17 "); } } @@ -6486,16 +7250,28 @@ mod graphviz_tests { node [shape=plaintext]; mode=hier; overlap=false; splines=true; bb0 [label=< - - - - - - - - - - + + + +
bb0(v0:BasicObject, v1:BasicObject, v2:BasicObject) 
PatchPoint NoTracePoint 
PatchPoint NoTracePoint 
PatchPoint BOPRedefined(INTEGER_REDEFINED_OP_FLAG, 29) 
v16:Fixnum = GuardType v1, Fixnum 
v17:Fixnum = GuardType v2, Fixnum 
v18:Fixnum = FixnumOr v16, v17 
PatchPoint NoTracePoint 
CheckInterrupts 
Return v18 
bb0(v1:BasicObject, v2:BasicObject, v3:BasicObject) 
EntryPoint interpreter 
Jump bb2(v1, v2, v3) 
>]; + bb0:v4 -> bb2:params:n; + bb1 [label=< + + + +
bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject) 
EntryPoint JIT 
Jump bb2(v6, v7, v8) 
>]; + bb1:v9 -> bb2:params:n; + bb2 [label=< + + + + + + + + + +
bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject) 
PatchPoint NoTracePoint 
PatchPoint NoTracePoint 
PatchPoint BOPRedefined(INTEGER_REDEFINED_OP_FLAG, 29) 
v26:Fixnum = GuardType v11, Fixnum 
v27:Fixnum = GuardType v12, Fixnum 
v28:Fixnum = FixnumOr v26, v27 
PatchPoint NoTracePoint 
CheckInterrupts 
Return v28 
>]; } "#); @@ -6520,25 +7296,37 @@ mod graphviz_tests { node [shape=plaintext]; mode=hier; overlap=false; splines=true; bb0 [label=< - - - - - - - - - - + + +
bb0(v0:BasicObject, v1:BasicObject) 
PatchPoint NoTracePoint 
CheckInterrupts 
v7:CBool = Test v1 
IfFalse v7, bb1(v0, v1) 
PatchPoint NoTracePoint 
v11:Fixnum[3] = Const Value(3) 
PatchPoint NoTracePoint 
CheckInterrupts 
Return v11 
bb0(v1:BasicObject, v2:BasicObject) 
EntryPoint interpreter 
Jump bb2(v1, v2) 
>]; - bb0:v8 -> bb1:params:n; + bb0:v3 -> bb2:params:n; bb1 [label=< - + + + +
bb1(v17:BasicObject, v18:BasicObject) 
bb1(v5:BasicObject, v6:BasicObject) 
EntryPoint JIT 
Jump bb2(v5, v6) 
>]; + bb1:v7 -> bb2:params:n; + bb2 [label=< + + + + + + + - - - - + + +
bb2(v8:BasicObject, v9:BasicObject) 
PatchPoint NoTracePoint 
CheckInterrupts 
v15:CBool = Test v9 
IfFalse v15, bb3(v8, v9) 
PatchPoint NoTracePoint 
v19:Fixnum[3] = Const Value(3) 
PatchPoint NoTracePoint 
v22:Fixnum[4] = Const Value(4) 
PatchPoint NoTracePoint 
CheckInterrupts 
Return v22 
CheckInterrupts 
Return v19 
>]; + bb2:v16 -> bb3:params:n; + bb3 [label=< + + + + + +
bb3(v25:BasicObject, v26:BasicObject) 
PatchPoint NoTracePoint 
v30:Fixnum[4] = Const Value(4) 
PatchPoint NoTracePoint 
CheckInterrupts 
Return v30 
>]; } "#); @@ -6575,13 +7363,19 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject): - v1:NilClass = Const Value(nil) - v5:TrueClass = Const Value(true) + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v7:NilClass = Const Value(nil) + v11:TrueClass = Const Value(true) CheckInterrupts - v14:Fixnum[3] = Const Value(3) + v20:Fixnum[3] = Const Value(3) CheckInterrupts - Return v14 + Return v20 "); } @@ -6599,13 +7393,19 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject): - v1:NilClass = Const Value(nil) - v5:FalseClass = Const Value(false) + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v7:NilClass = Const Value(nil) + v11:FalseClass = Const Value(false) CheckInterrupts - v25:Fixnum[4] = Const Value(4) + v31:Fixnum[4] = Const Value(4) CheckInterrupts - Return v25 + Return v31 "); } @@ -6618,16 +7418,22 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject): - v4:Fixnum[1] = Const Value(1) - v5:Fixnum[2] = Const Value(2) + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v10:Fixnum[1] = Const Value(1) + v11:Fixnum[2] = Const Value(2) PatchPoint BOPRedefined(INTEGER_REDEFINED_OP_FLAG, BOP_PLUS) - v24:Fixnum[3] = Const Value(3) - v10:Fixnum[3] = Const Value(3) + v30:Fixnum[3] = Const Value(3) + v16:Fixnum[3] = Const Value(3) PatchPoint BOPRedefined(INTEGER_REDEFINED_OP_FLAG, BOP_PLUS) - v25:Fixnum[6] = Const Value(6) + v31:Fixnum[6] = Const Value(6) CheckInterrupts - Return v25 + Return v31 "); } @@ -6640,16 +7446,22 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject): - v4:Fixnum[5] = Const Value(5) - v5:Fixnum[3] = Const Value(3) + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v10:Fixnum[5] = Const Value(5) + v11:Fixnum[3] = Const Value(3) PatchPoint BOPRedefined(INTEGER_REDEFINED_OP_FLAG, BOP_MINUS) - v24:Fixnum[2] = Const Value(2) - v10:Fixnum[1] = Const Value(1) + v30:Fixnum[2] = Const Value(2) + v16:Fixnum[1] = Const Value(1) PatchPoint BOPRedefined(INTEGER_REDEFINED_OP_FLAG, BOP_MINUS) - v25:Fixnum[1] = Const Value(1) + v31:Fixnum[1] = Const Value(1) CheckInterrupts - Return v25 + Return v31 "); } @@ -6662,13 +7474,19 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject): - v4:Fixnum[0] = Const Value(0) - v5:Fixnum[1073741825] = Const Value(1073741825) + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v10:Fixnum[0] = Const Value(0) + v11:Fixnum[1073741825] = Const Value(1073741825) PatchPoint BOPRedefined(INTEGER_REDEFINED_OP_FLAG, BOP_MINUS) - v17:Fixnum[-1073741825] = Const Value(-1073741825) + v23:Fixnum[-1073741825] = Const Value(-1073741825) CheckInterrupts - Return v17 + Return v23 "); } @@ -6681,13 +7499,19 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject): - v4:Fixnum[6] = Const Value(6) - v5:Fixnum[7] = Const Value(7) + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v10:Fixnum[6] = Const Value(6) + v11:Fixnum[7] = Const Value(7) PatchPoint BOPRedefined(INTEGER_REDEFINED_OP_FLAG, BOP_MULT) - v17:Fixnum[42] = Const Value(42) + v23:Fixnum[42] = Const Value(42) CheckInterrupts - Return v17 + Return v23 "); } @@ -6701,19 +7525,25 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject, v1:BasicObject): - v5:Fixnum[0] = Const Value(0) + bb0(v1:BasicObject, v2:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:BasicObject): + EntryPoint JIT + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:BasicObject): + v13:Fixnum[0] = Const Value(0) PatchPoint BOPRedefined(INTEGER_REDEFINED_OP_FLAG, BOP_MULT) - v25:Fixnum = GuardType v1, Fixnum - v32:Fixnum[0] = Const Value(0) - v10:Fixnum[0] = Const Value(0) + v33:Fixnum = GuardType v9, Fixnum + v40:Fixnum[0] = Const Value(0) + v18:Fixnum[0] = Const Value(0) PatchPoint BOPRedefined(INTEGER_REDEFINED_OP_FLAG, BOP_MULT) - v28:Fixnum = GuardType v1, Fixnum - v33:Fixnum[0] = Const Value(0) + v36:Fixnum = GuardType v9, Fixnum + v41:Fixnum[0] = Const Value(0) PatchPoint BOPRedefined(INTEGER_REDEFINED_OP_FLAG, BOP_PLUS) - v34:Fixnum[0] = Const Value(0) + v42:Fixnum[0] = Const Value(0) CheckInterrupts - Return v34 + Return v42 "); } @@ -6730,15 +7560,21 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject): - v4:Fixnum[1] = Const Value(1) - v5:Fixnum[2] = Const Value(2) + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v10:Fixnum[1] = Const Value(1) + v11:Fixnum[2] = Const Value(2) PatchPoint BOPRedefined(INTEGER_REDEFINED_OP_FLAG, BOP_LT) - v34:TrueClass = Const Value(true) + v40:TrueClass = Const Value(true) CheckInterrupts - v16:Fixnum[3] = Const Value(3) + v22:Fixnum[3] = Const Value(3) CheckInterrupts - Return v16 + Return v22 "); } @@ -6755,20 +7591,26 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject): - v4:Fixnum[1] = Const Value(1) - v5:Fixnum[2] = Const Value(2) + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v10:Fixnum[1] = Const Value(1) + v11:Fixnum[2] = Const Value(2) PatchPoint BOPRedefined(INTEGER_REDEFINED_OP_FLAG, BOP_LE) - v46:TrueClass = Const Value(true) + v52:TrueClass = Const Value(true) CheckInterrupts - v14:Fixnum[2] = Const Value(2) - v15:Fixnum[2] = Const Value(2) + v20:Fixnum[2] = Const Value(2) + v21:Fixnum[2] = Const Value(2) PatchPoint BOPRedefined(INTEGER_REDEFINED_OP_FLAG, BOP_LE) - v48:TrueClass = Const Value(true) + v54:TrueClass = Const Value(true) CheckInterrupts - v26:Fixnum[3] = Const Value(3) + v32:Fixnum[3] = Const Value(3) CheckInterrupts - Return v26 + Return v32 "); } @@ -6785,15 +7627,21 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject): - v4:Fixnum[2] = Const Value(2) - v5:Fixnum[1] = Const Value(1) + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v10:Fixnum[2] = Const Value(2) + v11:Fixnum[1] = Const Value(1) PatchPoint BOPRedefined(INTEGER_REDEFINED_OP_FLAG, BOP_GT) - v34:TrueClass = Const Value(true) + v40:TrueClass = Const Value(true) CheckInterrupts - v16:Fixnum[3] = Const Value(3) + v22:Fixnum[3] = Const Value(3) CheckInterrupts - Return v16 + Return v22 "); } @@ -6810,20 +7658,26 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject): - v4:Fixnum[2] = Const Value(2) - v5:Fixnum[1] = Const Value(1) + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v10:Fixnum[2] = Const Value(2) + v11:Fixnum[1] = Const Value(1) PatchPoint BOPRedefined(INTEGER_REDEFINED_OP_FLAG, BOP_GE) - v46:TrueClass = Const Value(true) + v52:TrueClass = Const Value(true) CheckInterrupts - v14:Fixnum[2] = Const Value(2) - v15:Fixnum[2] = Const Value(2) + v20:Fixnum[2] = Const Value(2) + v21:Fixnum[2] = Const Value(2) PatchPoint BOPRedefined(INTEGER_REDEFINED_OP_FLAG, BOP_GE) - v48:TrueClass = Const Value(true) + v54:TrueClass = Const Value(true) CheckInterrupts - v26:Fixnum[3] = Const Value(3) + v32:Fixnum[3] = Const Value(3) CheckInterrupts - Return v26 + Return v32 "); } @@ -6840,15 +7694,21 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject): - v4:Fixnum[1] = Const Value(1) - v5:Fixnum[2] = Const Value(2) + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v10:Fixnum[1] = Const Value(1) + v11:Fixnum[2] = Const Value(2) PatchPoint BOPRedefined(INTEGER_REDEFINED_OP_FLAG, BOP_EQ) - v34:FalseClass = Const Value(false) + v40:FalseClass = Const Value(false) CheckInterrupts - v26:Fixnum[4] = Const Value(4) + v32:Fixnum[4] = Const Value(4) CheckInterrupts - Return v26 + Return v32 "); } @@ -6865,15 +7725,21 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject): - v4:Fixnum[2] = Const Value(2) - v5:Fixnum[2] = Const Value(2) + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v10:Fixnum[2] = Const Value(2) + v11:Fixnum[2] = Const Value(2) PatchPoint BOPRedefined(INTEGER_REDEFINED_OP_FLAG, BOP_EQ) - v34:TrueClass = Const Value(true) + v40:TrueClass = Const Value(true) CheckInterrupts - v16:Fixnum[3] = Const Value(3) + v22:Fixnum[3] = Const Value(3) CheckInterrupts - Return v16 + Return v22 "); } @@ -6890,16 +7756,22 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject): - v4:Fixnum[1] = Const Value(1) - v5:Fixnum[2] = Const Value(2) + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v10:Fixnum[1] = Const Value(1) + v11:Fixnum[2] = Const Value(2) PatchPoint BOPRedefined(INTEGER_REDEFINED_OP_FLAG, BOP_EQ) PatchPoint BOPRedefined(INTEGER_REDEFINED_OP_FLAG, BOP_NEQ) - v35:TrueClass = Const Value(true) + v41:TrueClass = Const Value(true) CheckInterrupts - v16:Fixnum[3] = Const Value(3) + v22:Fixnum[3] = Const Value(3) CheckInterrupts - Return v16 + Return v22 "); } @@ -6916,16 +7788,22 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject): - v4:Fixnum[2] = Const Value(2) - v5:Fixnum[2] = Const Value(2) + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v10:Fixnum[2] = Const Value(2) + v11:Fixnum[2] = Const Value(2) PatchPoint BOPRedefined(INTEGER_REDEFINED_OP_FLAG, BOP_EQ) PatchPoint BOPRedefined(INTEGER_REDEFINED_OP_FLAG, BOP_NEQ) - v35:FalseClass = Const Value(false) + v41:FalseClass = Const Value(false) CheckInterrupts - v26:Fixnum[4] = Const Value(4) + v32:Fixnum[4] = Const Value(4) CheckInterrupts - Return v26 + Return v32 "); } @@ -6939,13 +7817,19 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject, v1:BasicObject): - v5:Fixnum[1] = Const Value(1) + bb0(v1:BasicObject, v2:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:BasicObject): + EntryPoint JIT + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:BasicObject): + v13:Fixnum[1] = Const Value(1) PatchPoint BOPRedefined(INTEGER_REDEFINED_OP_FLAG, BOP_PLUS) - v16:Fixnum = GuardType v1, Fixnum - v17:Fixnum = FixnumAdd v16, v5 + v24:Fixnum = GuardType v9, Fixnum + v25:Fixnum = FixnumAdd v24, v13 CheckInterrupts - Return v17 + Return v25 "); } @@ -6961,35 +7845,65 @@ mod opt_tests { assert_snapshot!(hir_string("rest"), @r" fn rest@:2: - bb0(v0:BasicObject, v1:ArrayExact): + bb0(v1:BasicObject, v2:ArrayExact): + EntryPoint interpreter + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:ArrayExact): + EntryPoint JIT + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:ArrayExact): CheckInterrupts - Return v1 + Return v9 "); // extra hidden param for the set of specified keywords assert_snapshot!(hir_string("kw"), @r" fn kw@:3: - bb0(v0:BasicObject, v1:BasicObject, v2:BasicObject): + bb0(v1:BasicObject, v2:BasicObject, v3:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2, v3) + bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): + EntryPoint JIT + Jump bb2(v6, v7, v8) + bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): CheckInterrupts - Return v1 + Return v11 "); assert_snapshot!(hir_string("kw_rest"), @r" fn kw_rest@:4: - bb0(v0:BasicObject, v1:BasicObject): + bb0(v1:BasicObject, v2:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:BasicObject): + EntryPoint JIT + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:BasicObject): CheckInterrupts - Return v1 + Return v9 "); assert_snapshot!(hir_string("block"), @r" fn block@:6: - bb0(v0:BasicObject, v1:BasicObject): - v5:NilClass = Const Value(nil) + bb0(v1:BasicObject, v2:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:BasicObject): + EntryPoint JIT + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:BasicObject): + v13:NilClass = Const Value(nil) CheckInterrupts - Return v5 + Return v13 "); assert_snapshot!(hir_string("post"), @r" fn post@:5: - bb0(v0:BasicObject, v1:ArrayExact, v2:BasicObject): + bb0(v1:BasicObject, v2:ArrayExact, v3:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2, v3) + bb1(v6:BasicObject, v7:ArrayExact, v8:BasicObject): + EntryPoint JIT + Jump bb2(v6, v7, v8) + bb2(v10:BasicObject, v11:ArrayExact, v12:BasicObject): CheckInterrupts - Return v2 + Return v12 "); } @@ -7005,12 +7919,18 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:5: - bb0(v0:BasicObject): + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): PatchPoint MethodRedefined(Object@0x1000, foo@0x1008, cme:0x1010) - v12:HeapObject[class_exact*:Object@VALUE(0x1000)] = GuardType v0, HeapObject[class_exact*:Object@VALUE(0x1000)] - v13:BasicObject = SendWithoutBlockDirect v12, :foo (0x1038) + v18:HeapObject[class_exact*:Object@VALUE(0x1000)] = GuardType v6, HeapObject[class_exact*:Object@VALUE(0x1000)] + v19:BasicObject = SendWithoutBlockDirect v18, :foo (0x1038) CheckInterrupts - Return v13 + Return v19 "); } @@ -7027,10 +7947,16 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:5: - bb0(v0:BasicObject): - v5:BasicObject = SendWithoutBlock v0, :foo + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v11:BasicObject = SendWithoutBlock v6, :foo CheckInterrupts - Return v5 + Return v11 "); } @@ -7047,12 +7973,18 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:6: - bb0(v0:BasicObject): + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): PatchPoint MethodRedefined(Object@0x1000, foo@0x1008, cme:0x1010) - v12:HeapObject[class_exact*:Object@VALUE(0x1000)] = GuardType v0, HeapObject[class_exact*:Object@VALUE(0x1000)] - v13:BasicObject = SendWithoutBlockDirect v12, :foo (0x1038) + v18:HeapObject[class_exact*:Object@VALUE(0x1000)] = GuardType v6, HeapObject[class_exact*:Object@VALUE(0x1000)] + v19:BasicObject = SendWithoutBlockDirect v18, :foo (0x1038) CheckInterrupts - Return v13 + Return v19 "); } @@ -7066,13 +7998,19 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject): - v4:Fixnum[3] = Const Value(3) + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v10:Fixnum[3] = Const Value(3) PatchPoint MethodRedefined(Object@0x1000, Integer@0x1008, cme:0x1010) - v13:HeapObject[class_exact*:Object@VALUE(0x1000)] = GuardType v0, HeapObject[class_exact*:Object@VALUE(0x1000)] - v14:BasicObject = SendWithoutBlockDirect v13, :Integer (0x1038), v4 + v19:HeapObject[class_exact*:Object@VALUE(0x1000)] = GuardType v6, HeapObject[class_exact*:Object@VALUE(0x1000)] + v20:BasicObject = SendWithoutBlockDirect v19, :Integer (0x1038), v10 CheckInterrupts - Return v14 + Return v20 "); } @@ -7088,14 +8026,20 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:5: - bb0(v0:BasicObject): - v4:Fixnum[1] = Const Value(1) - v5:Fixnum[2] = Const Value(2) + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v10:Fixnum[1] = Const Value(1) + v11:Fixnum[2] = Const Value(2) PatchPoint MethodRedefined(Object@0x1000, foo@0x1008, cme:0x1010) - v14:HeapObject[class_exact*:Object@VALUE(0x1000)] = GuardType v0, HeapObject[class_exact*:Object@VALUE(0x1000)] - v15:BasicObject = SendWithoutBlockDirect v14, :foo (0x1038), v4, v5 + v20:HeapObject[class_exact*:Object@VALUE(0x1000)] = GuardType v6, HeapObject[class_exact*:Object@VALUE(0x1000)] + v21:BasicObject = SendWithoutBlockDirect v20, :foo (0x1038), v10, v11 CheckInterrupts - Return v15 + Return v21 "); } @@ -7114,15 +8058,21 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:7: - bb0(v0:BasicObject): + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): PatchPoint MethodRedefined(Object@0x1000, foo@0x1008, cme:0x1010) - v16:HeapObject[class_exact*:Object@VALUE(0x1000)] = GuardType v0, HeapObject[class_exact*:Object@VALUE(0x1000)] - v17:BasicObject = SendWithoutBlockDirect v16, :foo (0x1038) + v22:HeapObject[class_exact*:Object@VALUE(0x1000)] = GuardType v6, HeapObject[class_exact*:Object@VALUE(0x1000)] + v23:BasicObject = SendWithoutBlockDirect v22, :foo (0x1038) PatchPoint MethodRedefined(Object@0x1000, bar@0x1040, cme:0x1048) - v19:HeapObject[class_exact*:Object@VALUE(0x1000)] = GuardType v0, HeapObject[class_exact*:Object@VALUE(0x1000)] - v20:BasicObject = SendWithoutBlockDirect v19, :bar (0x1038) + v25:HeapObject[class_exact*:Object@VALUE(0x1000)] = GuardType v6, HeapObject[class_exact*:Object@VALUE(0x1000)] + v26:BasicObject = SendWithoutBlockDirect v25, :bar (0x1038) CheckInterrupts - Return v20 + Return v26 "); } @@ -7136,14 +8086,20 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject): - v4:StringExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) - v6:StringExact = StringCopy v4 + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v10:StringExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) + v12:StringExact = StringCopy v10 PatchPoint MethodRedefined(Object@0x1008, puts@0x1010, cme:0x1018) - v16:HeapObject[class_exact*:Object@VALUE(0x1008)] = GuardType v0, HeapObject[class_exact*:Object@VALUE(0x1008)] - v17:BasicObject = CCallVariadic puts@0x1040, v16, v6 + v22:HeapObject[class_exact*:Object@VALUE(0x1008)] = GuardType v6, HeapObject[class_exact*:Object@VALUE(0x1008)] + v23:BasicObject = CCallVariadic puts@0x1040, v22, v12 CheckInterrupts - Return v17 + Return v23 "); } @@ -7160,10 +8116,16 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:7: - bb0(v0:BasicObject, v1:BasicObject, v2:BasicObject): - v9:BasicObject = SendWithoutBlock v1, :+, v2 + bb0(v1:BasicObject, v2:BasicObject, v3:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2, v3) + bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): + EntryPoint JIT + Jump bb2(v6, v7, v8) + bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): + v19:BasicObject = SendWithoutBlock v11, :+, v12 CheckInterrupts - Return v9 + Return v19 "); } @@ -7175,13 +8137,19 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject, v1:BasicObject, v2:BasicObject): + bb0(v1:BasicObject, v2:BasicObject, v3:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2, v3) + bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): + EntryPoint JIT + Jump bb2(v6, v7, v8) + bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): PatchPoint BOPRedefined(INTEGER_REDEFINED_OP_FLAG, BOP_PLUS) - v16:Fixnum = GuardType v1, Fixnum - v17:Fixnum = GuardType v2, Fixnum - v18:Fixnum = FixnumAdd v16, v17 + v26:Fixnum = GuardType v11, Fixnum + v27:Fixnum = GuardType v12, Fixnum + v28:Fixnum = FixnumAdd v26, v27 CheckInterrupts - Return v18 + Return v28 "); } @@ -7193,13 +8161,19 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject, v1:BasicObject): - v5:Fixnum[1] = Const Value(1) + bb0(v1:BasicObject, v2:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:BasicObject): + EntryPoint JIT + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:BasicObject): + v13:Fixnum[1] = Const Value(1) PatchPoint BOPRedefined(INTEGER_REDEFINED_OP_FLAG, BOP_PLUS) - v16:Fixnum = GuardType v1, Fixnum - v17:Fixnum = FixnumAdd v16, v5 + v24:Fixnum = GuardType v9, Fixnum + v25:Fixnum = FixnumAdd v24, v13 CheckInterrupts - Return v17 + Return v25 "); } @@ -7211,13 +8185,19 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject, v1:BasicObject): - v5:Fixnum[1] = Const Value(1) + bb0(v1:BasicObject, v2:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:BasicObject): + EntryPoint JIT + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:BasicObject): + v13:Fixnum[1] = Const Value(1) PatchPoint BOPRedefined(INTEGER_REDEFINED_OP_FLAG, BOP_PLUS) - v16:Fixnum = GuardType v1, Fixnum - v17:Fixnum = FixnumAdd v5, v16 + v24:Fixnum = GuardType v9, Fixnum + v25:Fixnum = FixnumAdd v13, v24 CheckInterrupts - Return v17 + Return v25 "); } @@ -7229,13 +8209,19 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject, v1:BasicObject, v2:BasicObject): + bb0(v1:BasicObject, v2:BasicObject, v3:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2, v3) + bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): + EntryPoint JIT + Jump bb2(v6, v7, v8) + bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): PatchPoint BOPRedefined(INTEGER_REDEFINED_OP_FLAG, BOP_LT) - v16:Fixnum = GuardType v1, Fixnum - v17:Fixnum = GuardType v2, Fixnum - v18:BoolExact = FixnumLt v16, v17 + v26:Fixnum = GuardType v11, Fixnum + v27:Fixnum = GuardType v12, Fixnum + v28:BoolExact = FixnumLt v26, v27 CheckInterrupts - Return v18 + Return v28 "); } @@ -7247,13 +8233,19 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject, v1:BasicObject): - v5:Fixnum[1] = Const Value(1) + bb0(v1:BasicObject, v2:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:BasicObject): + EntryPoint JIT + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:BasicObject): + v13:Fixnum[1] = Const Value(1) PatchPoint BOPRedefined(INTEGER_REDEFINED_OP_FLAG, BOP_LT) - v16:Fixnum = GuardType v1, Fixnum - v17:BoolExact = FixnumLt v16, v5 + v24:Fixnum = GuardType v9, Fixnum + v25:BoolExact = FixnumLt v24, v13 CheckInterrupts - Return v17 + Return v25 "); } @@ -7265,13 +8257,19 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject, v1:BasicObject): - v5:Fixnum[1] = Const Value(1) + bb0(v1:BasicObject, v2:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:BasicObject): + EntryPoint JIT + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:BasicObject): + v13:Fixnum[1] = Const Value(1) PatchPoint BOPRedefined(INTEGER_REDEFINED_OP_FLAG, BOP_LT) - v16:Fixnum = GuardType v1, Fixnum - v17:BoolExact = FixnumLt v5, v16 + v24:Fixnum = GuardType v9, Fixnum + v25:BoolExact = FixnumLt v13, v24 CheckInterrupts - Return v17 + Return v25 "); } @@ -7286,13 +8284,19 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject): - v1:NilClass = Const Value(nil) - v5:Fixnum[2] = Const Value(2) - v8:Fixnum[1] = Const Value(1) - v16:RangeExact = NewRangeFixnum v8 NewRangeInclusive v5 + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v7:NilClass = Const Value(nil) + v11:Fixnum[2] = Const Value(2) + v14:Fixnum[1] = Const Value(1) + v22:RangeExact = NewRangeFixnum v14 NewRangeInclusive v11 CheckInterrupts - Return v16 + Return v22 "); } @@ -7308,13 +8312,19 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject): - v1:NilClass = Const Value(nil) - v5:Fixnum[2] = Const Value(2) - v8:Fixnum[1] = Const Value(1) - v16:RangeExact = NewRangeFixnum v8 NewRangeExclusive v5 + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v7:NilClass = Const Value(nil) + v11:Fixnum[2] = Const Value(2) + v14:Fixnum[1] = Const Value(1) + v22:RangeExact = NewRangeFixnum v14 NewRangeExclusive v11 CheckInterrupts - Return v16 + Return v22 "); } @@ -7328,12 +8338,18 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject, v1:BasicObject): - v5:Fixnum[1] = Const Value(1) - v13:Fixnum = GuardType v1, Fixnum - v14:RangeExact = NewRangeFixnum v5 NewRangeInclusive v13 + bb0(v1:BasicObject, v2:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:BasicObject): + EntryPoint JIT + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:BasicObject): + v13:Fixnum[1] = Const Value(1) + v21:Fixnum = GuardType v9, Fixnum + v22:RangeExact = NewRangeFixnum v13 NewRangeInclusive v21 CheckInterrupts - Return v14 + Return v22 "); } @@ -7347,12 +8363,18 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject, v1:BasicObject): - v5:Fixnum[1] = Const Value(1) - v13:Fixnum = GuardType v1, Fixnum - v14:RangeExact = NewRangeFixnum v5 NewRangeExclusive v13 + bb0(v1:BasicObject, v2:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:BasicObject): + EntryPoint JIT + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:BasicObject): + v13:Fixnum[1] = Const Value(1) + v21:Fixnum = GuardType v9, Fixnum + v22:RangeExact = NewRangeFixnum v13 NewRangeExclusive v21 CheckInterrupts - Return v14 + Return v22 "); } @@ -7366,12 +8388,18 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject, v1:BasicObject): - v5:Fixnum[10] = Const Value(10) - v13:Fixnum = GuardType v1, Fixnum - v14:RangeExact = NewRangeFixnum v13 NewRangeInclusive v5 + bb0(v1:BasicObject, v2:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:BasicObject): + EntryPoint JIT + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:BasicObject): + v13:Fixnum[10] = Const Value(10) + v21:Fixnum = GuardType v9, Fixnum + v22:RangeExact = NewRangeFixnum v21 NewRangeInclusive v13 CheckInterrupts - Return v14 + Return v22 "); } @@ -7385,12 +8413,18 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject, v1:BasicObject): - v5:Fixnum[10] = Const Value(10) - v13:Fixnum = GuardType v1, Fixnum - v14:RangeExact = NewRangeFixnum v13 NewRangeExclusive v5 + bb0(v1:BasicObject, v2:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:BasicObject): + EntryPoint JIT + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:BasicObject): + v13:Fixnum[10] = Const Value(10) + v21:Fixnum = GuardType v9, Fixnum + v22:RangeExact = NewRangeFixnum v21 NewRangeExclusive v13 CheckInterrupts - Return v14 + Return v22 "); } @@ -7405,12 +8439,18 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject): - v1:NilClass = Const Value(nil) - v6:ArrayExact = NewArray - v9:Fixnum[5] = Const Value(5) + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v7:NilClass = Const Value(nil) + v12:ArrayExact = NewArray + v15:Fixnum[5] = Const Value(5) CheckInterrupts - Return v9 + Return v15 "); } @@ -7425,12 +8465,18 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject): - v1:NilClass = Const Value(nil) - v5:RangeExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) - v8:Fixnum[5] = Const Value(5) + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v7:NilClass = Const Value(nil) + v11:RangeExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) + v14:Fixnum[5] = Const Value(5) CheckInterrupts - Return v8 + Return v14 "); } @@ -7445,17 +8491,23 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject): - v1:NilClass = Const Value(nil) + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v7:NilClass = Const Value(nil) PatchPoint BOPRedefined(STRING_REDEFINED_OP_FLAG, BOP_UMINUS) - v7:StringExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) - v8:StringExact[VALUE(0x1008)] = Const Value(VALUE(0x1008)) - v10:StringExact = StringCopy v8 - v12:RangeExact = NewRange v7 NewRangeInclusive v10 + v13:StringExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) + v14:StringExact[VALUE(0x1008)] = Const Value(VALUE(0x1008)) + v16:StringExact = StringCopy v14 + v18:RangeExact = NewRange v13 NewRangeInclusive v16 PatchPoint NoEPEscape(test) - v17:Fixnum[0] = Const Value(0) + v23:Fixnum[0] = Const Value(0) CheckInterrupts - Return v17 + Return v23 "); } @@ -7470,12 +8522,18 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject, v1:BasicObject): - v2:NilClass = Const Value(nil) - v7:ArrayExact = NewArray v1 - v10:Fixnum[5] = Const Value(5) + bb0(v1:BasicObject, v2:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:BasicObject): + EntryPoint JIT + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:BasicObject): + v10:NilClass = Const Value(nil) + v15:ArrayExact = NewArray v9 + v18:Fixnum[5] = Const Value(5) CheckInterrupts - Return v10 + Return v18 "); } @@ -7489,13 +8547,19 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject): - v1:NilClass = Const Value(nil) - v6:HashExact = NewHash + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v7:NilClass = Const Value(nil) + v12:HashExact = NewHash PatchPoint NoEPEscape(test) - v11:Fixnum[5] = Const Value(5) + v17:Fixnum[5] = Const Value(5) CheckInterrupts - Return v11 + Return v17 "); } @@ -7509,15 +8573,21 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject, v1:BasicObject, v2:BasicObject): - v3:NilClass = Const Value(nil) - v7:StaticSymbol[:a] = Const Value(VALUE(0x1000)) - v8:StaticSymbol[:b] = Const Value(VALUE(0x1008)) - v10:HashExact = NewHash v7: v1, v8: v2 + bb0(v1:BasicObject, v2:BasicObject, v3:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2, v3) + bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): + EntryPoint JIT + Jump bb2(v6, v7, v8) + bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): + v13:NilClass = Const Value(nil) + v17:StaticSymbol[:a] = Const Value(VALUE(0x1000)) + v18:StaticSymbol[:b] = Const Value(VALUE(0x1008)) + v20:HashExact = NewHash v17: v11, v18: v12 PatchPoint NoEPEscape(test) - v15:Fixnum[5] = Const Value(5) + v25:Fixnum[5] = Const Value(5) CheckInterrupts - Return v15 + Return v25 "); } @@ -7532,13 +8602,19 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject): - v1:NilClass = Const Value(nil) - v5:ArrayExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) - v7:ArrayExact = ArrayDup v5 - v10:Fixnum[5] = Const Value(5) + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v7:NilClass = Const Value(nil) + v11:ArrayExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) + v13:ArrayExact = ArrayDup v11 + v16:Fixnum[5] = Const Value(5) CheckInterrupts - Return v10 + Return v16 "); } @@ -7552,13 +8628,19 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject): - v1:NilClass = Const Value(nil) - v5:HashExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) - v7:HashExact = HashDup v5 - v10:Fixnum[5] = Const Value(5) + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v7:NilClass = Const Value(nil) + v11:HashExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) + v13:HashExact = HashDup v11 + v16:Fixnum[5] = Const Value(5) CheckInterrupts - Return v10 + Return v16 "); } @@ -7573,11 +8655,17 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject): - v1:NilClass = Const Value(nil) - v7:Fixnum[5] = Const Value(5) + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v7:NilClass = Const Value(nil) + v13:Fixnum[5] = Const Value(5) CheckInterrupts - Return v7 + Return v13 "); } @@ -7592,13 +8680,19 @@ mod opt_tests { "#); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject): - v1:NilClass = Const Value(nil) - v5:StringExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) - v7:StringExact = StringCopy v5 - v10:Fixnum[5] = Const Value(5) + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v7:NilClass = Const Value(nil) + v11:StringExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) + v13:StringExact = StringCopy v11 + v16:Fixnum[5] = Const Value(5) CheckInterrupts - Return v10 + Return v16 "); } @@ -7613,13 +8707,19 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject, v1:BasicObject, v2:BasicObject): + bb0(v1:BasicObject, v2:BasicObject, v3:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2, v3) + bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): + EntryPoint JIT + Jump bb2(v6, v7, v8) + bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): PatchPoint BOPRedefined(INTEGER_REDEFINED_OP_FLAG, BOP_PLUS) - v19:Fixnum = GuardType v1, Fixnum - v20:Fixnum = GuardType v2, Fixnum - v12:Fixnum[5] = Const Value(5) + v29:Fixnum = GuardType v11, Fixnum + v30:Fixnum = GuardType v12, Fixnum + v22:Fixnum[5] = Const Value(5) CheckInterrupts - Return v12 + Return v22 "); } @@ -7634,13 +8734,19 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject, v1:BasicObject, v2:BasicObject): + bb0(v1:BasicObject, v2:BasicObject, v3:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2, v3) + bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): + EntryPoint JIT + Jump bb2(v6, v7, v8) + bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): PatchPoint BOPRedefined(INTEGER_REDEFINED_OP_FLAG, BOP_MINUS) - v19:Fixnum = GuardType v1, Fixnum - v20:Fixnum = GuardType v2, Fixnum - v12:Fixnum[5] = Const Value(5) + v29:Fixnum = GuardType v11, Fixnum + v30:Fixnum = GuardType v12, Fixnum + v22:Fixnum[5] = Const Value(5) CheckInterrupts - Return v12 + Return v22 "); } @@ -7655,13 +8761,19 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject, v1:BasicObject, v2:BasicObject): + bb0(v1:BasicObject, v2:BasicObject, v3:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2, v3) + bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): + EntryPoint JIT + Jump bb2(v6, v7, v8) + bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): PatchPoint BOPRedefined(INTEGER_REDEFINED_OP_FLAG, BOP_MULT) - v19:Fixnum = GuardType v1, Fixnum - v20:Fixnum = GuardType v2, Fixnum - v12:Fixnum[5] = Const Value(5) + v29:Fixnum = GuardType v11, Fixnum + v30:Fixnum = GuardType v12, Fixnum + v22:Fixnum[5] = Const Value(5) CheckInterrupts - Return v12 + Return v22 "); } @@ -7676,14 +8788,20 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject, v1:BasicObject, v2:BasicObject): + bb0(v1:BasicObject, v2:BasicObject, v3:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2, v3) + bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): + EntryPoint JIT + Jump bb2(v6, v7, v8) + bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): PatchPoint BOPRedefined(INTEGER_REDEFINED_OP_FLAG, BOP_DIV) - v19:Fixnum = GuardType v1, Fixnum - v20:Fixnum = GuardType v2, Fixnum - v21:Fixnum = FixnumDiv v19, v20 - v12:Fixnum[5] = Const Value(5) + v29:Fixnum = GuardType v11, Fixnum + v30:Fixnum = GuardType v12, Fixnum + v31:Fixnum = FixnumDiv v29, v30 + v22:Fixnum[5] = Const Value(5) CheckInterrupts - Return v12 + Return v22 "); } @@ -7698,14 +8816,20 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject, v1:BasicObject, v2:BasicObject): + bb0(v1:BasicObject, v2:BasicObject, v3:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2, v3) + bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): + EntryPoint JIT + Jump bb2(v6, v7, v8) + bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): PatchPoint BOPRedefined(INTEGER_REDEFINED_OP_FLAG, BOP_MOD) - v19:Fixnum = GuardType v1, Fixnum - v20:Fixnum = GuardType v2, Fixnum - v21:Fixnum = FixnumMod v19, v20 - v12:Fixnum[5] = Const Value(5) + v29:Fixnum = GuardType v11, Fixnum + v30:Fixnum = GuardType v12, Fixnum + v31:Fixnum = FixnumMod v29, v30 + v22:Fixnum[5] = Const Value(5) CheckInterrupts - Return v12 + Return v22 "); } @@ -7720,13 +8844,19 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject, v1:BasicObject, v2:BasicObject): + bb0(v1:BasicObject, v2:BasicObject, v3:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2, v3) + bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): + EntryPoint JIT + Jump bb2(v6, v7, v8) + bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): PatchPoint BOPRedefined(INTEGER_REDEFINED_OP_FLAG, BOP_LT) - v19:Fixnum = GuardType v1, Fixnum - v20:Fixnum = GuardType v2, Fixnum - v12:Fixnum[5] = Const Value(5) + v29:Fixnum = GuardType v11, Fixnum + v30:Fixnum = GuardType v12, Fixnum + v22:Fixnum[5] = Const Value(5) CheckInterrupts - Return v12 + Return v22 "); } @@ -7741,13 +8871,19 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject, v1:BasicObject, v2:BasicObject): + bb0(v1:BasicObject, v2:BasicObject, v3:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2, v3) + bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): + EntryPoint JIT + Jump bb2(v6, v7, v8) + bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): PatchPoint BOPRedefined(INTEGER_REDEFINED_OP_FLAG, BOP_LE) - v19:Fixnum = GuardType v1, Fixnum - v20:Fixnum = GuardType v2, Fixnum - v12:Fixnum[5] = Const Value(5) + v29:Fixnum = GuardType v11, Fixnum + v30:Fixnum = GuardType v12, Fixnum + v22:Fixnum[5] = Const Value(5) CheckInterrupts - Return v12 + Return v22 "); } @@ -7762,13 +8898,19 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject, v1:BasicObject, v2:BasicObject): + bb0(v1:BasicObject, v2:BasicObject, v3:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2, v3) + bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): + EntryPoint JIT + Jump bb2(v6, v7, v8) + bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): PatchPoint BOPRedefined(INTEGER_REDEFINED_OP_FLAG, BOP_GT) - v19:Fixnum = GuardType v1, Fixnum - v20:Fixnum = GuardType v2, Fixnum - v12:Fixnum[5] = Const Value(5) + v29:Fixnum = GuardType v11, Fixnum + v30:Fixnum = GuardType v12, Fixnum + v22:Fixnum[5] = Const Value(5) CheckInterrupts - Return v12 + Return v22 "); } @@ -7783,13 +8925,19 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject, v1:BasicObject, v2:BasicObject): + bb0(v1:BasicObject, v2:BasicObject, v3:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2, v3) + bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): + EntryPoint JIT + Jump bb2(v6, v7, v8) + bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): PatchPoint BOPRedefined(INTEGER_REDEFINED_OP_FLAG, BOP_GE) - v19:Fixnum = GuardType v1, Fixnum - v20:Fixnum = GuardType v2, Fixnum - v12:Fixnum[5] = Const Value(5) + v29:Fixnum = GuardType v11, Fixnum + v30:Fixnum = GuardType v12, Fixnum + v22:Fixnum[5] = Const Value(5) CheckInterrupts - Return v12 + Return v22 "); } @@ -7804,13 +8952,19 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject, v1:BasicObject, v2:BasicObject): + bb0(v1:BasicObject, v2:BasicObject, v3:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2, v3) + bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): + EntryPoint JIT + Jump bb2(v6, v7, v8) + bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): PatchPoint BOPRedefined(INTEGER_REDEFINED_OP_FLAG, BOP_EQ) - v19:Fixnum = GuardType v1, Fixnum - v20:Fixnum = GuardType v2, Fixnum - v12:Fixnum[5] = Const Value(5) + v29:Fixnum = GuardType v11, Fixnum + v30:Fixnum = GuardType v12, Fixnum + v22:Fixnum[5] = Const Value(5) CheckInterrupts - Return v12 + Return v22 "); } @@ -7825,14 +8979,20 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject, v1:BasicObject, v2:BasicObject): + bb0(v1:BasicObject, v2:BasicObject, v3:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2, v3) + bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): + EntryPoint JIT + Jump bb2(v6, v7, v8) + bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): PatchPoint BOPRedefined(INTEGER_REDEFINED_OP_FLAG, BOP_EQ) PatchPoint BOPRedefined(INTEGER_REDEFINED_OP_FLAG, BOP_NEQ) - v20:Fixnum = GuardType v1, Fixnum - v21:Fixnum = GuardType v2, Fixnum - v12:Fixnum[5] = Const Value(5) + v30:Fixnum = GuardType v11, Fixnum + v31:Fixnum = GuardType v12, Fixnum + v22:Fixnum[5] = Const Value(5) CheckInterrupts - Return v12 + Return v22 "); } @@ -7846,11 +9006,17 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject): - v5:BasicObject = GetConstantPath 0x1000 - v8:Fixnum[5] = Const Value(5) + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v11:BasicObject = GetConstantPath 0x1000 + v14:Fixnum[5] = Const Value(5) CheckInterrupts - Return v8 + Return v14 "); } @@ -7863,12 +9029,18 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject, v1:BasicObject): + bb0(v1:BasicObject, v2:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:BasicObject): + EntryPoint JIT + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:BasicObject): PatchPoint MethodRedefined(Integer@0x1000, itself@0x1008, cme:0x1010) - v13:Fixnum = GuardType v1, Fixnum - v14:BasicObject = CCall itself@0x1038, v13 + v21:Fixnum = GuardType v9, Fixnum + v22:BasicObject = CCall itself@0x1038, v21 CheckInterrupts - Return v14 + Return v22 "); } @@ -7879,12 +9051,18 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject): - v5:ArrayExact = NewArray + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v11:ArrayExact = NewArray PatchPoint MethodRedefined(Array@0x1000, itself@0x1008, cme:0x1010) - v14:BasicObject = CCall itself@0x1038, v5 + v20:BasicObject = CCall itself@0x1038, v11 CheckInterrupts - Return v14 + Return v20 "); } @@ -7898,15 +9076,21 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject): - v1:NilClass = Const Value(nil) - v6:ArrayExact = NewArray + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v7:NilClass = Const Value(nil) + v12:ArrayExact = NewArray PatchPoint MethodRedefined(Array@0x1000, itself@0x1008, cme:0x1010) - v20:BasicObject = CCall itself@0x1038, v6 + v26:BasicObject = CCall itself@0x1038, v12 PatchPoint NoEPEscape(test) - v13:Fixnum[1] = Const Value(1) + v19:Fixnum[1] = Const Value(1) CheckInterrupts - Return v13 + Return v19 "); } @@ -7922,17 +9106,23 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:4: - bb0(v0:BasicObject): - v1:NilClass = Const Value(nil) + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v7:NilClass = Const Value(nil) PatchPoint SingleRactorMode PatchPoint StableConstantNames(0x1000, M) - v21:ModuleExact[VALUE(0x1008)] = Const Value(VALUE(0x1008)) + v27:ModuleExact[VALUE(0x1008)] = Const Value(VALUE(0x1008)) PatchPoint MethodRedefined(Module@0x1010, name@0x1018, cme:0x1020) - v23:StringExact|NilClass = CCall name@0x1048, v21 + v29:StringExact|NilClass = CCall name@0x1048, v27 PatchPoint NoEPEscape(test) - v13:Fixnum[1] = Const Value(1) + v19:Fixnum[1] = Const Value(1) CheckInterrupts - Return v13 + Return v19 "); } @@ -7946,14 +9136,20 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject): - v1:NilClass = Const Value(nil) - v6:ArrayExact = NewArray + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v7:NilClass = Const Value(nil) + v12:ArrayExact = NewArray PatchPoint MethodRedefined(Array@0x1000, length@0x1008, cme:0x1010) - v20:Fixnum = CCall length@0x1038, v6 - v13:Fixnum[5] = Const Value(5) + v26:Fixnum = CCall length@0x1038, v12 + v19:Fixnum[5] = Const Value(5) CheckInterrupts - Return v13 + Return v19 "); } @@ -7966,12 +9162,18 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject): + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): PatchPoint SingleRactorMode PatchPoint StableConstantNames(0x1000, C) - v13:Class[VALUE(0x1008)] = Const Value(VALUE(0x1008)) + v19:Class[VALUE(0x1008)] = Const Value(VALUE(0x1008)) CheckInterrupts - Return v13 + Return v19 "); } @@ -7983,22 +9185,28 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject): + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): PatchPoint SingleRactorMode PatchPoint StableConstantNames(0x1000, String) - v21:Class[VALUE(0x1008)] = Const Value(VALUE(0x1008)) + v27:Class[VALUE(0x1008)] = Const Value(VALUE(0x1008)) PatchPoint SingleRactorMode PatchPoint StableConstantNames(0x1010, Class) - v24:Class[VALUE(0x1018)] = Const Value(VALUE(0x1018)) + v30:Class[VALUE(0x1018)] = Const Value(VALUE(0x1018)) PatchPoint SingleRactorMode PatchPoint StableConstantNames(0x1020, Module) - v27:Class[VALUE(0x1028)] = Const Value(VALUE(0x1028)) + v33:Class[VALUE(0x1028)] = Const Value(VALUE(0x1028)) PatchPoint SingleRactorMode PatchPoint StableConstantNames(0x1030, BasicObject) - v30:Class[VALUE(0x1038)] = Const Value(VALUE(0x1038)) - v13:ArrayExact = NewArray v21, v24, v27, v30 + v36:Class[VALUE(0x1038)] = Const Value(VALUE(0x1038)) + v19:ArrayExact = NewArray v27, v30, v33, v36 CheckInterrupts - Return v13 + Return v19 "); } @@ -8010,16 +9218,22 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject): + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): PatchPoint SingleRactorMode PatchPoint StableConstantNames(0x1000, Enumerable) - v17:ModuleExact[VALUE(0x1008)] = Const Value(VALUE(0x1008)) + v23:ModuleExact[VALUE(0x1008)] = Const Value(VALUE(0x1008)) PatchPoint SingleRactorMode PatchPoint StableConstantNames(0x1010, Kernel) - v20:ModuleExact[VALUE(0x1018)] = Const Value(VALUE(0x1018)) - v9:ArrayExact = NewArray v17, v20 + v26:ModuleExact[VALUE(0x1018)] = Const Value(VALUE(0x1018)) + v15:ArrayExact = NewArray v23, v26 CheckInterrupts - Return v9 + Return v15 "); } @@ -8033,12 +9247,18 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:4: - bb0(v0:BasicObject): + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): PatchPoint SingleRactorMode PatchPoint StableConstantNames(0x1000, MY_MODULE) - v13:HeapObject[VALUE(0x1008)] = Const Value(VALUE(0x1008)) + v19:HeapObject[VALUE(0x1008)] = Const Value(VALUE(0x1008)) CheckInterrupts - Return v13 + Return v19 "); } @@ -8052,14 +9272,20 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject): - v1:NilClass = Const Value(nil) - v6:ArrayExact = NewArray + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v7:NilClass = Const Value(nil) + v12:ArrayExact = NewArray PatchPoint MethodRedefined(Array@0x1000, size@0x1008, cme:0x1010) - v20:Fixnum = CCall size@0x1038, v6 - v13:Fixnum[5] = Const Value(5) + v26:Fixnum = CCall size@0x1038, v12 + v19:Fixnum[5] = Const Value(5) CheckInterrupts - Return v13 + Return v19 "); } @@ -8073,12 +9299,18 @@ mod opt_tests { // Not specialized assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject): - v4:Fixnum[1] = Const Value(1) - v5:Fixnum[0] = Const Value(0) - v7:BasicObject = SendWithoutBlock v4, :itself, v5 + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v10:Fixnum[1] = Const Value(1) + v11:Fixnum[0] = Const Value(0) + v13:BasicObject = SendWithoutBlock v10, :itself, v11 CheckInterrupts - Return v7 + Return v13 "); } @@ -8089,12 +9321,18 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject, v1:BasicObject): - v5:Fixnum[1] = Const Value(1) + bb0(v1:BasicObject, v2:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:BasicObject): + EntryPoint JIT + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:BasicObject): + v13:Fixnum[1] = Const Value(1) PatchPoint MethodRedefined(Integer@0x1000, zero?@0x1008, cme:0x1010) - v14:BasicObject = SendWithoutBlockDirect v5, :zero? (0x1038) + v22:BasicObject = SendWithoutBlockDirect v13, :zero? (0x1038) CheckInterrupts - Return v14 + Return v22 "); } @@ -8108,14 +9346,20 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject, v1:BasicObject): - v2:NilClass = Const Value(nil) - v6:ArrayExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) - v8:ArrayExact = ArrayDup v6 + bb0(v1:BasicObject, v2:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:BasicObject): + EntryPoint JIT + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:BasicObject): + v10:NilClass = Const Value(nil) + v14:ArrayExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) + v16:ArrayExact = ArrayDup v14 PatchPoint MethodRedefined(Array@0x1008, first@0x1010, cme:0x1018) - v19:BasicObject = SendWithoutBlockDirect v8, :first (0x1040) + v27:BasicObject = SendWithoutBlockDirect v16, :first (0x1040) CheckInterrupts - Return v19 + Return v27 "); } @@ -8129,14 +9373,20 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject): + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): PatchPoint SingleRactorMode PatchPoint StableConstantNames(0x1000, M) - v15:ModuleExact[VALUE(0x1008)] = Const Value(VALUE(0x1008)) + v21:ModuleExact[VALUE(0x1008)] = Const Value(VALUE(0x1008)) PatchPoint MethodRedefined(Module@0x1010, class@0x1018, cme:0x1020) - v17:BasicObject = SendWithoutBlockDirect v15, :class (0x1048) + v23:BasicObject = SendWithoutBlockDirect v21, :class (0x1048) CheckInterrupts - Return v17 + Return v23 "); } @@ -8157,12 +9407,18 @@ mod opt_tests { assert_snapshot!(hir_string("test"), @r" fn test@:8: - bb0(v0:BasicObject, v1:BasicObject): + bb0(v1:BasicObject, v2:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:BasicObject): + EntryPoint JIT + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:BasicObject): PatchPoint MethodRedefined(C@0x1000, foo@0x1008, cme:0x1010) - v13:HeapObject[class_exact:C] = GuardType v1, HeapObject[class_exact:C] - v14:BasicObject = SendWithoutBlockDirect v13, :foo (0x1038) + v21:HeapObject[class_exact:C] = GuardType v9, HeapObject[class_exact:C] + v22:BasicObject = SendWithoutBlockDirect v21, :foo (0x1038) CheckInterrupts - Return v14 + Return v22 "); } @@ -8176,11 +9432,17 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject): - v4:Fixnum[1] = Const Value(1) - v6:BasicObject = SendWithoutBlock v0, :foo, v4 + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v10:Fixnum[1] = Const Value(1) + v12:BasicObject = SendWithoutBlock v6, :foo, v10 CheckInterrupts - Return v6 + Return v12 "); } @@ -8194,10 +9456,16 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject): - v5:BasicObject = Send v0, 0x1000, :foo + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v11:BasicObject = Send v6, 0x1000, :foo CheckInterrupts - Return v5 + Return v11 "); } @@ -8215,15 +9483,21 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:4: - bb0(v0:BasicObject): - v1:NilClass = Const Value(nil) - v5:Fixnum[1] = Const Value(1) - SetLocal l0, EP@3, v5 - v10:BasicObject = Send v0, 0x1000, :foo - v11:BasicObject = GetLocal l0, EP@3 - v14:BasicObject = GetLocal l0, EP@3 + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v7:NilClass = Const Value(nil) + v11:Fixnum[1] = Const Value(1) + SetLocal l0, EP@3, v11 + v16:BasicObject = Send v6, 0x1000, :foo + v17:BasicObject = GetLocal l0, EP@3 + v20:BasicObject = GetLocal l0, EP@3 CheckInterrupts - Return v14 + Return v20 "); } @@ -8237,11 +9511,17 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject): - v4:Fixnum[1] = Const Value(1) - v6:BasicObject = SendWithoutBlock v0, :foo, v4 + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v10:Fixnum[1] = Const Value(1) + v12:BasicObject = SendWithoutBlock v6, :foo, v10 CheckInterrupts - Return v6 + Return v12 "); } @@ -8255,8 +9535,14 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject): - v4:Fixnum[1] = Const Value(1) + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v10:Fixnum[1] = Const Value(1) SideExit UnhandledCallType(Kwarg) "); } @@ -8271,8 +9557,14 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject): - v4:Fixnum[1] = Const Value(1) + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v10:Fixnum[1] = Const Value(1) SideExit UnhandledCallType(Kwarg) "); } @@ -8286,13 +9578,19 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject): - v4:StringExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) - v6:StringExact = StringCopy v4 + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v10:StringExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) + v12:StringExact = StringCopy v10 PatchPoint MethodRedefined(String@0x1008, bytesize@0x1010, cme:0x1018) - v15:Fixnum = CCall bytesize@0x1040, v6 + v21:Fixnum = CCall bytesize@0x1040, v12 CheckInterrupts - Return v15 + Return v21 "); } @@ -8303,10 +9601,16 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject): - v5:BasicObject = GetConstantPath 0x1000 + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v11:BasicObject = GetConstantPath 0x1000 CheckInterrupts - Return v5 + Return v11 "); } @@ -8319,10 +9623,16 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject): - v5:BasicObject = GetConstantPath 0x1000 + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v11:BasicObject = GetConstantPath 0x1000 CheckInterrupts - Return v5 + Return v11 "); } @@ -8334,12 +9644,18 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject): + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): PatchPoint SingleRactorMode PatchPoint StableConstantNames(0x1000, Kernel) - v13:ModuleExact[VALUE(0x1008)] = Const Value(VALUE(0x1008)) + v19:ModuleExact[VALUE(0x1008)] = Const Value(VALUE(0x1008)) CheckInterrupts - Return v13 + Return v19 "); } @@ -8357,12 +9673,18 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:8: - bb0(v0:BasicObject): + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): PatchPoint SingleRactorMode PatchPoint StableConstantNames(0x1000, Foo::Bar::C) - v13:Class[VALUE(0x1008)] = Const Value(VALUE(0x1008)) + v19:Class[VALUE(0x1008)] = Const Value(VALUE(0x1008)) CheckInterrupts - Return v13 + Return v19 "); } @@ -8375,18 +9697,24 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject): + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): PatchPoint SingleRactorMode PatchPoint StableConstantNames(0x1000, C) - v34:Class[VALUE(0x1008)] = Const Value(VALUE(0x1008)) - v6:NilClass = Const Value(nil) + v40:Class[VALUE(0x1008)] = Const Value(VALUE(0x1008)) + v12:NilClass = Const Value(nil) PatchPoint MethodRedefined(C@0x1008, new@0x1010, cme:0x1018) - v37:HeapObject[class_exact:C] = ObjectAllocClass C:VALUE(0x1008) + v43:HeapObject[class_exact:C] = ObjectAllocClass C:VALUE(0x1008) PatchPoint MethodRedefined(C@0x1008, initialize@0x1040, cme:0x1048) - v39:NilClass = CCall initialize@0x1070, v37 + v45:NilClass = CCall initialize@0x1070, v43 CheckInterrupts CheckInterrupts - Return v37 + Return v43 "); } @@ -8403,19 +9731,25 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:7: - bb0(v0:BasicObject): + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): PatchPoint SingleRactorMode PatchPoint StableConstantNames(0x1000, C) - v36:Class[VALUE(0x1008)] = Const Value(VALUE(0x1008)) - v6:NilClass = Const Value(nil) - v7:Fixnum[1] = Const Value(1) + v42:Class[VALUE(0x1008)] = Const Value(VALUE(0x1008)) + v12:NilClass = Const Value(nil) + v13:Fixnum[1] = Const Value(1) PatchPoint MethodRedefined(C@0x1008, new@0x1010, cme:0x1018) - v39:HeapObject[class_exact:C] = ObjectAllocClass C:VALUE(0x1008) + v45:HeapObject[class_exact:C] = ObjectAllocClass C:VALUE(0x1008) PatchPoint MethodRedefined(C@0x1008, initialize@0x1040, cme:0x1048) - v41:BasicObject = SendWithoutBlockDirect v39, :initialize (0x1070), v7 + v47:BasicObject = SendWithoutBlockDirect v45, :initialize (0x1070), v13 CheckInterrupts CheckInterrupts - Return v39 + Return v45 "); } @@ -8427,18 +9761,24 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject): + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): PatchPoint SingleRactorMode PatchPoint StableConstantNames(0x1000, Object) - v34:Class[VALUE(0x1008)] = Const Value(VALUE(0x1008)) - v6:NilClass = Const Value(nil) + v40:Class[VALUE(0x1008)] = Const Value(VALUE(0x1008)) + v12:NilClass = Const Value(nil) PatchPoint MethodRedefined(Object@0x1008, new@0x1010, cme:0x1018) - v37:ObjectExact = ObjectAllocClass Object:VALUE(0x1008) + v43:ObjectExact = ObjectAllocClass Object:VALUE(0x1008) PatchPoint MethodRedefined(Object@0x1008, initialize@0x1040, cme:0x1048) - v39:NilClass = CCall initialize@0x1070, v37 + v45:NilClass = CCall initialize@0x1070, v43 CheckInterrupts CheckInterrupts - Return v37 + Return v43 "); } @@ -8450,18 +9790,24 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject): + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): PatchPoint SingleRactorMode PatchPoint StableConstantNames(0x1000, BasicObject) - v34:Class[VALUE(0x1008)] = Const Value(VALUE(0x1008)) - v6:NilClass = Const Value(nil) + v40:Class[VALUE(0x1008)] = Const Value(VALUE(0x1008)) + v12:NilClass = Const Value(nil) PatchPoint MethodRedefined(BasicObject@0x1008, new@0x1010, cme:0x1018) - v37:BasicObjectExact = ObjectAllocClass BasicObject:VALUE(0x1008) + v43:BasicObjectExact = ObjectAllocClass BasicObject:VALUE(0x1008) PatchPoint MethodRedefined(BasicObject@0x1008, initialize@0x1040, cme:0x1048) - v39:NilClass = CCall initialize@0x1070, v37 + v45:NilClass = CCall initialize@0x1070, v43 CheckInterrupts CheckInterrupts - Return v37 + Return v43 "); } @@ -8473,17 +9819,23 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject): + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): PatchPoint SingleRactorMode PatchPoint StableConstantNames(0x1000, Hash) - v34:Class[VALUE(0x1008)] = Const Value(VALUE(0x1008)) - v6:NilClass = Const Value(nil) + v40:Class[VALUE(0x1008)] = Const Value(VALUE(0x1008)) + v12:NilClass = Const Value(nil) PatchPoint MethodRedefined(Hash@0x1008, new@0x1010, cme:0x1018) - v37:HashExact = ObjectAllocClass Hash:VALUE(0x1008) - v12:BasicObject = SendWithoutBlock v37, :initialize + v43:HashExact = ObjectAllocClass Hash:VALUE(0x1008) + v18:BasicObject = SendWithoutBlock v43, :initialize CheckInterrupts CheckInterrupts - Return v37 + Return v43 "); assert_snapshot!(inspect("test"), @"{}"); } @@ -8496,17 +9848,23 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject): + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): PatchPoint SingleRactorMode PatchPoint StableConstantNames(0x1000, Array) - v36:Class[VALUE(0x1008)] = Const Value(VALUE(0x1008)) - v6:NilClass = Const Value(nil) - v7:Fixnum[1] = Const Value(1) + v42:Class[VALUE(0x1008)] = Const Value(VALUE(0x1008)) + v12:NilClass = Const Value(nil) + v13:Fixnum[1] = Const Value(1) PatchPoint MethodRedefined(Array@0x1008, new@0x1010, cme:0x1018) PatchPoint MethodRedefined(Class@0x1040, new@0x1010, cme:0x1018) - v45:BasicObject = CCallVariadic new@0x1048, v36, v7 + v51:BasicObject = CCallVariadic new@0x1048, v42, v13 CheckInterrupts - Return v45 + Return v51 "); } @@ -8518,19 +9876,25 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject): + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): PatchPoint SingleRactorMode PatchPoint StableConstantNames(0x1000, Set) - v34:Class[VALUE(0x1008)] = Const Value(VALUE(0x1008)) - v6:NilClass = Const Value(nil) + v40:Class[VALUE(0x1008)] = Const Value(VALUE(0x1008)) + v12:NilClass = Const Value(nil) PatchPoint MethodRedefined(Set@0x1008, new@0x1010, cme:0x1018) - v10:HeapObject = ObjectAlloc v34 + v16:HeapObject = ObjectAlloc v40 PatchPoint MethodRedefined(Set@0x1008, initialize@0x1040, cme:0x1048) - v39:SetExact = GuardType v10, SetExact - v40:BasicObject = CCallVariadic initialize@0x1070, v39 + v45:SetExact = GuardType v16, SetExact + v46:BasicObject = CCallVariadic initialize@0x1070, v45 CheckInterrupts CheckInterrupts - Return v10 + Return v16 "); } @@ -8542,16 +9906,22 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject): + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): PatchPoint SingleRactorMode PatchPoint StableConstantNames(0x1000, String) - v34:Class[VALUE(0x1008)] = Const Value(VALUE(0x1008)) - v6:NilClass = Const Value(nil) + v40:Class[VALUE(0x1008)] = Const Value(VALUE(0x1008)) + v12:NilClass = Const Value(nil) PatchPoint MethodRedefined(String@0x1008, new@0x1010, cme:0x1018) PatchPoint MethodRedefined(Class@0x1040, new@0x1010, cme:0x1018) - v43:BasicObject = CCallVariadic new@0x1048, v34 + v49:BasicObject = CCallVariadic new@0x1048, v40 CheckInterrupts - Return v43 + Return v49 "); } @@ -8563,20 +9933,26 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject): + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): PatchPoint SingleRactorMode PatchPoint StableConstantNames(0x1000, Regexp) - v38:Class[VALUE(0x1008)] = Const Value(VALUE(0x1008)) - v6:NilClass = Const Value(nil) - v7:StringExact[VALUE(0x1010)] = Const Value(VALUE(0x1010)) - v9:StringExact = StringCopy v7 + v44:Class[VALUE(0x1008)] = Const Value(VALUE(0x1008)) + v12:NilClass = Const Value(nil) + v13:StringExact[VALUE(0x1010)] = Const Value(VALUE(0x1010)) + v15:StringExact = StringCopy v13 PatchPoint MethodRedefined(Regexp@0x1008, new@0x1018, cme:0x1020) - v41:RegexpExact = ObjectAllocClass Regexp:VALUE(0x1008) + v47:RegexpExact = ObjectAllocClass Regexp:VALUE(0x1008) PatchPoint MethodRedefined(Regexp@0x1008, initialize@0x1048, cme:0x1050) - v44:BasicObject = CCallVariadic initialize@0x1078, v41, v9 + v50:BasicObject = CCallVariadic initialize@0x1078, v47, v15 CheckInterrupts CheckInterrupts - Return v41 + Return v47 "); } @@ -8587,12 +9963,18 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject, v1:BasicObject, v2:BasicObject): - v7:ArrayExact = NewArray v1, v2 + bb0(v1:BasicObject, v2:BasicObject, v3:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2, v3) + bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): + EntryPoint JIT + Jump bb2(v6, v7, v8) + bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): + v17:ArrayExact = NewArray v11, v12 PatchPoint MethodRedefined(Array@0x1000, length@0x1008, cme:0x1010) - v18:Fixnum = CCall length@0x1038, v7 + v28:Fixnum = CCall length@0x1038, v17 CheckInterrupts - Return v18 + Return v28 "); } @@ -8603,12 +9985,18 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject, v1:BasicObject, v2:BasicObject): - v7:ArrayExact = NewArray v1, v2 + bb0(v1:BasicObject, v2:BasicObject, v3:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2, v3) + bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): + EntryPoint JIT + Jump bb2(v6, v7, v8) + bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): + v17:ArrayExact = NewArray v11, v12 PatchPoint MethodRedefined(Array@0x1000, size@0x1008, cme:0x1010) - v18:Fixnum = CCall size@0x1038, v7 + v28:Fixnum = CCall size@0x1038, v17 CheckInterrupts - Return v18 + Return v28 "); } @@ -8619,12 +10007,18 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject, v1:BasicObject): + bb0(v1:BasicObject, v2:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:BasicObject): + EntryPoint JIT + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:BasicObject): GuardBlockParamProxy l0 - v7:HeapObject[BlockParamProxy] = Const Value(VALUE(0x1000)) - v9:BasicObject = Send v0, 0x1008, :tap, v7 + v15:HeapObject[BlockParamProxy] = Const Value(VALUE(0x1000)) + v17:BasicObject = Send v8, 0x1008, :tap, v15 CheckInterrupts - Return v9 + Return v17 "); } @@ -8635,11 +10029,17 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject): + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): PatchPoint SingleRactorMode - v6:BasicObject = GetIvar v0, :@foo + v12:BasicObject = GetIvar v6, :@foo CheckInterrupts - Return v6 + Return v12 "); } @@ -8650,12 +10050,18 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject): - v4:Fixnum[1] = Const Value(1) + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v10:Fixnum[1] = Const Value(1) PatchPoint SingleRactorMode - SetIvar v0, :@foo, v4 + SetIvar v6, :@foo, v10 CheckInterrupts - Return v4 + Return v10 "); } @@ -8666,11 +10072,17 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject): + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): PatchPoint BOPRedefined(HASH_REDEFINED_OP_FLAG, BOP_FREEZE) - v6:HashExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) + v12:HashExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) CheckInterrupts - Return v6 + Return v12 "); } @@ -8684,7 +10096,13 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:5: - bb0(v0:BasicObject): + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): SideExit PatchPoint(BOPRedefined(HASH_REDEFINED_OP_FLAG, BOP_FREEZE)) "); } @@ -8696,12 +10114,18 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject): + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): PatchPoint BOPRedefined(HASH_REDEFINED_OP_FLAG, BOP_FREEZE) - v6:HashExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) + v12:HashExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) PatchPoint BOPRedefined(HASH_REDEFINED_OP_FLAG, BOP_FREEZE) CheckInterrupts - Return v6 + Return v12 "); } @@ -8712,12 +10136,18 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject): - v5:HashExact = NewHash - v7:BasicObject = SendWithoutBlock v5, :dup - v9:BasicObject = SendWithoutBlock v7, :freeze + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v11:HashExact = NewHash + v13:BasicObject = SendWithoutBlock v11, :dup + v15:BasicObject = SendWithoutBlock v13, :freeze CheckInterrupts - Return v9 + Return v15 "); } @@ -8728,12 +10158,18 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject): - v5:HashExact = NewHash - v6:NilClass = Const Value(nil) - v8:BasicObject = SendWithoutBlock v5, :freeze, v6 + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v11:HashExact = NewHash + v12:NilClass = Const Value(nil) + v14:BasicObject = SendWithoutBlock v11, :freeze, v12 CheckInterrupts - Return v8 + Return v14 "); } @@ -8744,11 +10180,17 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject): + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): PatchPoint BOPRedefined(ARRAY_REDEFINED_OP_FLAG, BOP_FREEZE) - v6:ArrayExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) + v12:ArrayExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) CheckInterrupts - Return v6 + Return v12 "); } @@ -8759,12 +10201,18 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject): + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): PatchPoint BOPRedefined(ARRAY_REDEFINED_OP_FLAG, BOP_FREEZE) - v6:ArrayExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) + v12:ArrayExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) PatchPoint BOPRedefined(ARRAY_REDEFINED_OP_FLAG, BOP_FREEZE) CheckInterrupts - Return v6 + Return v12 "); } @@ -8775,12 +10223,18 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject): - v5:ArrayExact = NewArray - v7:BasicObject = SendWithoutBlock v5, :dup - v9:BasicObject = SendWithoutBlock v7, :freeze + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v11:ArrayExact = NewArray + v13:BasicObject = SendWithoutBlock v11, :dup + v15:BasicObject = SendWithoutBlock v13, :freeze CheckInterrupts - Return v9 + Return v15 "); } @@ -8791,12 +10245,18 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject): - v5:ArrayExact = NewArray - v6:NilClass = Const Value(nil) - v8:BasicObject = SendWithoutBlock v5, :freeze, v6 + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v11:ArrayExact = NewArray + v12:NilClass = Const Value(nil) + v14:BasicObject = SendWithoutBlock v11, :freeze, v12 CheckInterrupts - Return v8 + Return v14 "); } @@ -8807,11 +10267,17 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject): + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): PatchPoint BOPRedefined(STRING_REDEFINED_OP_FLAG, BOP_FREEZE) - v6:StringExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) + v12:StringExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) CheckInterrupts - Return v6 + Return v12 "); } @@ -8822,12 +10288,18 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject): + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): PatchPoint BOPRedefined(STRING_REDEFINED_OP_FLAG, BOP_FREEZE) - v6:StringExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) + v12:StringExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) PatchPoint BOPRedefined(STRING_REDEFINED_OP_FLAG, BOP_FREEZE) CheckInterrupts - Return v6 + Return v12 "); } @@ -8838,13 +10310,19 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject): - v4:StringExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) - v6:StringExact = StringCopy v4 - v8:BasicObject = SendWithoutBlock v6, :dup - v10:BasicObject = SendWithoutBlock v8, :freeze + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v10:StringExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) + v12:StringExact = StringCopy v10 + v14:BasicObject = SendWithoutBlock v12, :dup + v16:BasicObject = SendWithoutBlock v14, :freeze CheckInterrupts - Return v10 + Return v16 "); } @@ -8855,13 +10333,19 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject): - v4:StringExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) - v6:StringExact = StringCopy v4 - v7:NilClass = Const Value(nil) - v9:BasicObject = SendWithoutBlock v6, :freeze, v7 + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v10:StringExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) + v12:StringExact = StringCopy v10 + v13:NilClass = Const Value(nil) + v15:BasicObject = SendWithoutBlock v12, :freeze, v13 CheckInterrupts - Return v9 + Return v15 "); } @@ -8872,11 +10356,17 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject): + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): PatchPoint BOPRedefined(STRING_REDEFINED_OP_FLAG, BOP_UMINUS) - v6:StringExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) + v12:StringExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) CheckInterrupts - Return v6 + Return v12 "); } @@ -8887,12 +10377,18 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject): + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): PatchPoint BOPRedefined(STRING_REDEFINED_OP_FLAG, BOP_FREEZE) - v6:StringExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) + v12:StringExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) PatchPoint BOPRedefined(STRING_REDEFINED_OP_FLAG, BOP_UMINUS) CheckInterrupts - Return v6 + Return v12 "); } @@ -8903,13 +10399,19 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject): - v4:StringExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) - v6:StringExact = StringCopy v4 - v8:BasicObject = SendWithoutBlock v6, :dup - v10:BasicObject = SendWithoutBlock v8, :-@ + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v10:StringExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) + v12:StringExact = StringCopy v10 + v14:BasicObject = SendWithoutBlock v12, :dup + v16:BasicObject = SendWithoutBlock v14, :-@ CheckInterrupts - Return v10 + Return v16 "); } @@ -8920,13 +10422,19 @@ mod opt_tests { "##); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject): - v4:StringExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) - v7:StringExact[VALUE(0x1008)] = Const Value(VALUE(0x1008)) - v9:StringExact = StringCopy v7 - v15:StringExact = StringConcat v4, v9 + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v10:StringExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) + v13:StringExact[VALUE(0x1008)] = Const Value(VALUE(0x1008)) + v15:StringExact = StringCopy v13 + v21:StringExact = StringConcat v10, v15 CheckInterrupts - Return v15 + Return v21 "); } @@ -8937,14 +10445,20 @@ mod opt_tests { "##); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject): - v4:StringExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) - v5:Fixnum[1] = Const Value(1) - v7:BasicObject = ObjToString v5 - v9:String = AnyToString v5, str: v7 - v11:StringExact = StringConcat v4, v9 + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v10:StringExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) + v11:Fixnum[1] = Const Value(1) + v13:BasicObject = ObjToString v11 + v15:String = AnyToString v11, str: v13 + v17:StringExact = StringConcat v10, v15 CheckInterrupts - Return v11 + Return v17 "); } @@ -8959,12 +10473,18 @@ mod opt_tests { assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject, v1:BasicObject): - v5:StringExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) - v17:String = GuardType v1, String - v11:StringExact = StringConcat v5, v17 + bb0(v1:BasicObject, v2:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:BasicObject): + EntryPoint JIT + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:BasicObject): + v13:StringExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) + v25:String = GuardType v9, String + v19:StringExact = StringConcat v13, v25 CheckInterrupts - Return v11 + Return v19 "); } @@ -8982,12 +10502,18 @@ mod opt_tests { assert_snapshot!(hir_string("test"), @r" fn test@:5: - bb0(v0:BasicObject, v1:BasicObject): - v5:StringExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) - v17:String = GuardType v1, String - v11:StringExact = StringConcat v5, v17 + bb0(v1:BasicObject, v2:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:BasicObject): + EntryPoint JIT + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:BasicObject): + v13:StringExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) + v25:String = GuardType v9, String + v19:StringExact = StringConcat v13, v25 CheckInterrupts - Return v11 + Return v19 "); } @@ -9002,14 +10528,20 @@ mod opt_tests { assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject, v1:BasicObject): - v5:StringExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) - v17:BasicObject = GuardTypeNot v1, String - v18:BasicObject = SendWithoutBlock v1, :to_s - v9:String = AnyToString v1, str: v18 - v11:StringExact = StringConcat v5, v9 + bb0(v1:BasicObject, v2:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:BasicObject): + EntryPoint JIT + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:BasicObject): + v13:StringExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) + v25:BasicObject = GuardTypeNot v9, String + v26:BasicObject = SendWithoutBlock v9, :to_s + v17:String = AnyToString v9, str: v26 + v19:StringExact = StringConcat v13, v17 CheckInterrupts - Return v11 + Return v19 "); } @@ -9024,12 +10556,18 @@ mod opt_tests { assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject): - v1:NilClass = Const Value(nil) - v5:NilClass = Const Value(nil) + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v7:NilClass = Const Value(nil) + v11:NilClass = Const Value(nil) CheckInterrupts CheckInterrupts - Return v5 + Return v11 "); } @@ -9044,14 +10582,20 @@ mod opt_tests { assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject): - v1:NilClass = Const Value(nil) - v5:Fixnum[1] = Const Value(1) + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v7:NilClass = Const Value(nil) + v11:Fixnum[1] = Const Value(1) CheckInterrupts PatchPoint MethodRedefined(Integer@0x1000, itself@0x1008, cme:0x1010) - v25:BasicObject = CCall itself@0x1038, v5 + v31:BasicObject = CCall itself@0x1038, v11 CheckInterrupts - Return v25 + Return v31 "); } @@ -9062,14 +10606,20 @@ mod opt_tests { "##); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject): + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): PatchPoint BOPRedefined(ARRAY_REDEFINED_OP_FLAG, BOP_FREEZE) - v6:ArrayExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) - v7:Fixnum[1] = Const Value(1) + v12:ArrayExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) + v13:Fixnum[1] = Const Value(1) PatchPoint BOPRedefined(ARRAY_REDEFINED_OP_FLAG, BOP_AREF) - v18:Fixnum[5] = Const Value(5) + v24:Fixnum[5] = Const Value(5) CheckInterrupts - Return v18 + Return v24 "); } @@ -9080,14 +10630,20 @@ mod opt_tests { "##); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject): + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): PatchPoint BOPRedefined(ARRAY_REDEFINED_OP_FLAG, BOP_FREEZE) - v6:ArrayExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) - v7:Fixnum[-3] = Const Value(-3) + v12:ArrayExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) + v13:Fixnum[-3] = Const Value(-3) PatchPoint BOPRedefined(ARRAY_REDEFINED_OP_FLAG, BOP_AREF) - v18:Fixnum[4] = Const Value(4) + v24:Fixnum[4] = Const Value(4) CheckInterrupts - Return v18 + Return v24 "); } @@ -9098,14 +10654,20 @@ mod opt_tests { "##); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject): + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): PatchPoint BOPRedefined(ARRAY_REDEFINED_OP_FLAG, BOP_FREEZE) - v6:ArrayExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) - v7:Fixnum[-10] = Const Value(-10) + v12:ArrayExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) + v13:Fixnum[-10] = Const Value(-10) PatchPoint BOPRedefined(ARRAY_REDEFINED_OP_FLAG, BOP_AREF) - v18:NilClass = Const Value(nil) + v24:NilClass = Const Value(nil) CheckInterrupts - Return v18 + Return v24 "); } @@ -9116,14 +10678,20 @@ mod opt_tests { "##); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject): + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): PatchPoint BOPRedefined(ARRAY_REDEFINED_OP_FLAG, BOP_FREEZE) - v6:ArrayExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) - v7:Fixnum[10] = Const Value(10) + v12:ArrayExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) + v13:Fixnum[10] = Const Value(10) PatchPoint BOPRedefined(ARRAY_REDEFINED_OP_FLAG, BOP_AREF) - v18:NilClass = Const Value(nil) + v24:NilClass = Const Value(nil) CheckInterrupts - Return v18 + Return v24 "); } @@ -9137,13 +10705,19 @@ mod opt_tests { "##); assert_snapshot!(hir_string("test"), @r" fn test@:5: - bb0(v0:BasicObject): + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): PatchPoint BOPRedefined(ARRAY_REDEFINED_OP_FLAG, BOP_FREEZE) - v6:ArrayExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) - v7:Fixnum[10] = Const Value(10) - v11:BasicObject = SendWithoutBlock v6, :[], v7 + v12:ArrayExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) + v13:Fixnum[10] = Const Value(10) + v17:BasicObject = SendWithoutBlock v12, :[], v13 CheckInterrupts - Return v11 + Return v17 "); } @@ -9157,13 +10731,19 @@ mod opt_tests { "##); assert_snapshot!(hir_string("test"), @r" fn test@:5: - bb0(v0:BasicObject): - v4:ArrayExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) - v6:ArrayExact = ArrayDup v4 + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v10:ArrayExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) + v12:ArrayExact = ArrayDup v10 PatchPoint MethodRedefined(Array@0x1008, max@0x1010, cme:0x1018) - v15:BasicObject = SendWithoutBlockDirect v6, :max (0x1040) + v21:BasicObject = SendWithoutBlockDirect v12, :max (0x1040) CheckInterrupts - Return v15 + Return v21 "); } @@ -9179,12 +10759,18 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:4: - bb0(v0:BasicObject): + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): PatchPoint SingleRactorMode PatchPoint StableConstantNames(0x1000, MY_SET) - v13:SetExact[VALUE(0x1008)] = Const Value(VALUE(0x1008)) + v19:SetExact[VALUE(0x1008)] = Const Value(VALUE(0x1008)) CheckInterrupts - Return v13 + Return v19 "); } @@ -9195,10 +10781,16 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject): - v4:RegexpExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v10:RegexpExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) CheckInterrupts - Return v4 + Return v10 "); } @@ -9209,12 +10801,18 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject): - v4:NilClass = Const Value(nil) + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v10:NilClass = Const Value(nil) PatchPoint MethodRedefined(NilClass@0x1000, nil?@0x1008, cme:0x1010) - v15:TrueClass = CCall nil?@0x1038, v4 + v21:TrueClass = CCall nil?@0x1038, v10 CheckInterrupts - Return v15 + Return v21 "); } @@ -9228,12 +10826,18 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject): - v4:NilClass = Const Value(nil) + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v10:NilClass = Const Value(nil) PatchPoint MethodRedefined(NilClass@0x1000, nil?@0x1008, cme:0x1010) - v11:Fixnum[1] = Const Value(1) + v17:Fixnum[1] = Const Value(1) CheckInterrupts - Return v11 + Return v17 "); } @@ -9244,12 +10848,18 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject): - v4:Fixnum[1] = Const Value(1) + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v10:Fixnum[1] = Const Value(1) PatchPoint MethodRedefined(Integer@0x1000, nil?@0x1008, cme:0x1010) - v15:FalseClass = CCall nil?@0x1038, v4 + v21:FalseClass = CCall nil?@0x1038, v10 CheckInterrupts - Return v15 + Return v21 "); } @@ -9263,12 +10873,18 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject): - v4:Fixnum[1] = Const Value(1) + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): + v10:Fixnum[1] = Const Value(1) PatchPoint MethodRedefined(Integer@0x1000, nil?@0x1008, cme:0x1010) - v11:Fixnum[2] = Const Value(2) + v17:Fixnum[2] = Const Value(2) CheckInterrupts - Return v11 + Return v17 "); } @@ -9281,12 +10897,18 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject, v1:BasicObject): + bb0(v1:BasicObject, v2:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:BasicObject): + EntryPoint JIT + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:BasicObject): PatchPoint MethodRedefined(NilClass@0x1000, nil?@0x1008, cme:0x1010) - v15:NilClass = GuardType v1, NilClass - v16:TrueClass = CCall nil?@0x1038, v15 + v23:NilClass = GuardType v9, NilClass + v24:TrueClass = CCall nil?@0x1038, v23 CheckInterrupts - Return v16 + Return v24 "); } @@ -9299,12 +10921,18 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject, v1:BasicObject): + bb0(v1:BasicObject, v2:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:BasicObject): + EntryPoint JIT + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:BasicObject): PatchPoint MethodRedefined(FalseClass@0x1000, nil?@0x1008, cme:0x1010) - v15:FalseClass = GuardType v1, FalseClass - v16:FalseClass = CCall nil?@0x1038, v15 + v23:FalseClass = GuardType v9, FalseClass + v24:FalseClass = CCall nil?@0x1038, v23 CheckInterrupts - Return v16 + Return v24 "); } @@ -9317,12 +10945,18 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject, v1:BasicObject): + bb0(v1:BasicObject, v2:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:BasicObject): + EntryPoint JIT + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:BasicObject): PatchPoint MethodRedefined(TrueClass@0x1000, nil?@0x1008, cme:0x1010) - v15:TrueClass = GuardType v1, TrueClass - v16:FalseClass = CCall nil?@0x1038, v15 + v23:TrueClass = GuardType v9, TrueClass + v24:FalseClass = CCall nil?@0x1038, v23 CheckInterrupts - Return v16 + Return v24 "); } @@ -9335,12 +10969,18 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject, v1:BasicObject): + bb0(v1:BasicObject, v2:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:BasicObject): + EntryPoint JIT + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:BasicObject): PatchPoint MethodRedefined(Symbol@0x1000, nil?@0x1008, cme:0x1010) - v15:StaticSymbol = GuardType v1, StaticSymbol - v16:FalseClass = CCall nil?@0x1038, v15 + v23:StaticSymbol = GuardType v9, StaticSymbol + v24:FalseClass = CCall nil?@0x1038, v23 CheckInterrupts - Return v16 + Return v24 "); } @@ -9353,12 +10993,18 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject, v1:BasicObject): + bb0(v1:BasicObject, v2:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:BasicObject): + EntryPoint JIT + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:BasicObject): PatchPoint MethodRedefined(Integer@0x1000, nil?@0x1008, cme:0x1010) - v15:Fixnum = GuardType v1, Fixnum - v16:FalseClass = CCall nil?@0x1038, v15 + v23:Fixnum = GuardType v9, Fixnum + v24:FalseClass = CCall nil?@0x1038, v23 CheckInterrupts - Return v16 + Return v24 "); } @@ -9371,12 +11017,18 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject, v1:BasicObject): + bb0(v1:BasicObject, v2:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:BasicObject): + EntryPoint JIT + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:BasicObject): PatchPoint MethodRedefined(Float@0x1000, nil?@0x1008, cme:0x1010) - v15:Flonum = GuardType v1, Flonum - v16:FalseClass = CCall nil?@0x1038, v15 + v23:Flonum = GuardType v9, Flonum + v24:FalseClass = CCall nil?@0x1038, v23 CheckInterrupts - Return v16 + Return v24 "); } @@ -9389,12 +11041,18 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject, v1:BasicObject): + bb0(v1:BasicObject, v2:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:BasicObject): + EntryPoint JIT + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:BasicObject): PatchPoint MethodRedefined(String@0x1000, nil?@0x1008, cme:0x1010) - v15:StringExact = GuardType v1, StringExact - v16:FalseClass = CCall nil?@0x1038, v15 + v23:StringExact = GuardType v9, StringExact + v24:FalseClass = CCall nil?@0x1038, v23 CheckInterrupts - Return v16 + Return v24 "); } @@ -9407,12 +11065,18 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject, v1:BasicObject): + bb0(v1:BasicObject, v2:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:BasicObject): + EntryPoint JIT + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:BasicObject): PatchPoint MethodRedefined(Array@0x1000, !@0x1008, cme:0x1010) - v15:ArrayExact = GuardType v1, ArrayExact - v16:BoolExact = CCall !@0x1038, v15 + v23:ArrayExact = GuardType v9, ArrayExact + v24:BoolExact = CCall !@0x1038, v23 CheckInterrupts - Return v16 + Return v24 "); } @@ -9425,12 +11089,18 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject, v1:BasicObject): + bb0(v1:BasicObject, v2:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:BasicObject): + EntryPoint JIT + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:BasicObject): PatchPoint MethodRedefined(Array@0x1000, empty?@0x1008, cme:0x1010) - v15:ArrayExact = GuardType v1, ArrayExact - v16:BoolExact = CCall empty?@0x1038, v15 + v23:ArrayExact = GuardType v9, ArrayExact + v24:BoolExact = CCall empty?@0x1038, v23 CheckInterrupts - Return v16 + Return v24 "); } @@ -9443,12 +11113,18 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject, v1:BasicObject): + bb0(v1:BasicObject, v2:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:BasicObject): + EntryPoint JIT + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:BasicObject): PatchPoint MethodRedefined(Hash@0x1000, empty?@0x1008, cme:0x1010) - v15:HashExact = GuardType v1, HashExact - v16:BoolExact = CCall empty?@0x1038, v15 + v23:HashExact = GuardType v9, HashExact + v24:BoolExact = CCall empty?@0x1038, v23 CheckInterrupts - Return v16 + Return v24 "); } @@ -9462,12 +11138,18 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject, v1:BasicObject, v2:BasicObject): + bb0(v1:BasicObject, v2:BasicObject, v3:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2, v3) + bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): + EntryPoint JIT + Jump bb2(v6, v7, v8) + bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): PatchPoint MethodRedefined(C@0x1000, ==@0x1008, cme:0x1010) - v16:HeapObject[class_exact:C] = GuardType v1, HeapObject[class_exact:C] - v17:BoolExact = CCall ==@0x1038, v16, v2 + v26:HeapObject[class_exact:C] = GuardType v11, HeapObject[class_exact:C] + v27:BoolExact = CCall ==@0x1038, v26, v12 CheckInterrupts - Return v17 + Return v27 "); } @@ -9480,13 +11162,19 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject, v1:BasicObject, v2:BasicObject): + bb0(v1:BasicObject, v2:BasicObject, v3:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2, v3) + bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): + EntryPoint JIT + Jump bb2(v6, v7, v8) + bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): PatchPoint BOPRedefined(INTEGER_REDEFINED_OP_FLAG, 28) - v16:Fixnum = GuardType v1, Fixnum - v17:Fixnum = GuardType v2, Fixnum - v18:Fixnum = FixnumAnd v16, v17 + v26:Fixnum = GuardType v11, Fixnum + v27:Fixnum = GuardType v12, Fixnum + v28:Fixnum = FixnumAnd v26, v27 CheckInterrupts - Return v18 + Return v28 "); } @@ -9499,13 +11187,19 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:2: - bb0(v0:BasicObject, v1:BasicObject, v2:BasicObject): + bb0(v1:BasicObject, v2:BasicObject, v3:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2, v3) + bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): + EntryPoint JIT + Jump bb2(v6, v7, v8) + bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): PatchPoint BOPRedefined(INTEGER_REDEFINED_OP_FLAG, 29) - v16:Fixnum = GuardType v1, Fixnum - v17:Fixnum = GuardType v2, Fixnum - v18:Fixnum = FixnumOr v16, v17 + v26:Fixnum = GuardType v11, Fixnum + v27:Fixnum = GuardType v12, Fixnum + v28:Fixnum = FixnumOr v26, v27 CheckInterrupts - Return v18 + Return v28 "); } @@ -9520,12 +11214,18 @@ mod opt_tests { assert_snapshot!(hir_string("test"), @r" fn test@:3: - bb0(v0:BasicObject): + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): PatchPoint MethodRedefined(Object@0x1000, foo@0x1008, cme:0x1010) - v12:HeapObject[class_exact*:Object@VALUE(0x1000)] = GuardType v0, HeapObject[class_exact*:Object@VALUE(0x1000)] - v13:BasicObject = SendWithoutBlockDirect v12, :foo (0x1038) + v18:HeapObject[class_exact*:Object@VALUE(0x1000)] = GuardType v6, HeapObject[class_exact*:Object@VALUE(0x1000)] + v19:BasicObject = SendWithoutBlockDirect v18, :foo (0x1038) CheckInterrupts - Return v13 + Return v19 "); } @@ -9546,13 +11246,19 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:10: - bb0(v0:BasicObject, v1:BasicObject): + bb0(v1:BasicObject, v2:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:BasicObject): + EntryPoint JIT + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:BasicObject): PatchPoint MethodRedefined(C@0x1000, foo@0x1008, cme:0x1010) - v13:HeapObject[class_exact:C] = GuardType v1, HeapObject[class_exact:C] - v16:HeapObject[class_exact:C] = GuardShape v13, 0x1038 - v17:BasicObject = LoadIvarEmbedded v16, :@foo@0x1039 + v21:HeapObject[class_exact:C] = GuardType v9, HeapObject[class_exact:C] + v24:HeapObject[class_exact:C] = GuardShape v21, 0x1038 + v25:BasicObject = LoadIvarEmbedded v24, :@foo@0x1039 CheckInterrupts - Return v17 + Return v25 "); } @@ -9573,13 +11279,19 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:10: - bb0(v0:BasicObject, v1:BasicObject): + bb0(v1:BasicObject, v2:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:BasicObject): + EntryPoint JIT + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:BasicObject): PatchPoint MethodRedefined(C@0x1000, foo@0x1008, cme:0x1010) - v13:HeapObject[class_exact:C] = GuardType v1, HeapObject[class_exact:C] - v16:HeapObject[class_exact:C] = GuardShape v13, 0x1038 - v17:BasicObject = LoadIvarEmbedded v16, :@foo@0x1039 + v21:HeapObject[class_exact:C] = GuardType v9, HeapObject[class_exact:C] + v24:HeapObject[class_exact:C] = GuardShape v21, 0x1038 + v25:BasicObject = LoadIvarEmbedded v24, :@foo@0x1039 CheckInterrupts - Return v17 + Return v25 "); } @@ -9611,10 +11323,16 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:20: - bb0(v0:BasicObject, v1:BasicObject): - v6:BasicObject = SendWithoutBlock v1, :foo + bb0(v1:BasicObject, v2:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:BasicObject): + EntryPoint JIT + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:BasicObject): + v14:BasicObject = SendWithoutBlock v9, :foo CheckInterrupts - Return v6 + Return v14 "); } @@ -9632,15 +11350,21 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:7: - bb0(v0:BasicObject): + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): PatchPoint SingleRactorMode PatchPoint StableConstantNames(0x1000, O) - v15:HeapObject[VALUE(0x1008)] = Const Value(VALUE(0x1008)) + v21:HeapObject[VALUE(0x1008)] = Const Value(VALUE(0x1008)) PatchPoint MethodRedefined(C@0x1010, foo@0x1018, cme:0x1020) - v19:HeapObject[VALUE(0x1008)] = GuardShape v15, 0x1048 - v20:NilClass = Const Value(nil) + v25:HeapObject[VALUE(0x1008)] = GuardShape v21, 0x1048 + v26:NilClass = Const Value(nil) CheckInterrupts - Return v20 + Return v26 "); } @@ -9658,15 +11382,21 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:7: - bb0(v0:BasicObject): + bb0(v1:BasicObject): + EntryPoint interpreter + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT + Jump bb2(v4) + bb2(v6:BasicObject): PatchPoint SingleRactorMode PatchPoint StableConstantNames(0x1000, O) - v15:HeapObject[VALUE(0x1008)] = Const Value(VALUE(0x1008)) + v21:HeapObject[VALUE(0x1008)] = Const Value(VALUE(0x1008)) PatchPoint MethodRedefined(C@0x1010, foo@0x1018, cme:0x1020) - v19:HeapObject[VALUE(0x1008)] = GuardShape v15, 0x1048 - v20:NilClass = Const Value(nil) + v25:HeapObject[VALUE(0x1008)] = GuardShape v21, 0x1048 + v26:NilClass = Const Value(nil) CheckInterrupts - Return v20 + Return v26 "); } @@ -9683,13 +11413,19 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:6: - bb0(v0:BasicObject, v1:BasicObject): + bb0(v1:BasicObject, v2:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:BasicObject): + EntryPoint JIT + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:BasicObject): PatchPoint MethodRedefined(C@0x1000, foo@0x1008, cme:0x1010) - v13:HeapObject[class_exact:C] = GuardType v1, HeapObject[class_exact:C] - v16:HeapObject[class_exact:C] = GuardShape v13, 0x1038 - v17:NilClass = Const Value(nil) + v21:HeapObject[class_exact:C] = GuardType v9, HeapObject[class_exact:C] + v24:HeapObject[class_exact:C] = GuardShape v21, 0x1038 + v25:NilClass = Const Value(nil) CheckInterrupts - Return v17 + Return v25 "); } @@ -9706,13 +11442,19 @@ mod opt_tests { "); assert_snapshot!(hir_string("test"), @r" fn test@:6: - bb0(v0:BasicObject, v1:BasicObject): + bb0(v1:BasicObject, v2:BasicObject): + EntryPoint interpreter + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:BasicObject): + EntryPoint JIT + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:BasicObject): PatchPoint MethodRedefined(C@0x1000, foo@0x1008, cme:0x1010) - v13:HeapObject[class_exact:C] = GuardType v1, HeapObject[class_exact:C] - v16:HeapObject[class_exact:C] = GuardShape v13, 0x1038 - v17:NilClass = Const Value(nil) + v21:HeapObject[class_exact:C] = GuardType v9, HeapObject[class_exact:C] + v24:HeapObject[class_exact:C] = GuardShape v21, 0x1038 + v25:NilClass = Const Value(nil) CheckInterrupts - Return v17 + Return v25 "); } } diff --git a/zjit/src/hir_type/mod.rs b/zjit/src/hir_type/mod.rs index 5478653a235b3d..24bee1c0568e9a 100644 --- a/zjit/src/hir_type/mod.rs +++ b/zjit/src/hir_type/mod.rs @@ -8,7 +8,7 @@ use crate::cruby::get_class_name; use crate::cruby::ruby_sym_to_rust_string; use crate::cruby::rb_mRubyVMFrozenCore; use crate::cruby::rb_obj_class; -use crate::hir::PtrPrintMap; +use crate::hir::{Const, PtrPrintMap}; use crate::profile::ProfiledType; #[derive(Copy, Clone, Debug, PartialEq)] @@ -95,6 +95,7 @@ fn write_spec(f: &mut std::fmt::Formatter, printer: &TypePrinter) -> std::fmt::R Specialization::Int(val) if ty.is_subtype(types::CUInt16) => write!(f, "[{}]", val >> 48), Specialization::Int(val) if ty.is_subtype(types::CUInt32) => write!(f, "[{}]", val >> 32), Specialization::Int(val) if ty.is_subtype(types::CUInt64) => write!(f, "[{}]", val), + Specialization::Int(val) if ty.is_subtype(types::CPtr) => write!(f, "[{}]", Const::CPtr(val as *mut u8).print(printer.ptr_map)), Specialization::Int(val) => write!(f, "[{val}]"), Specialization::Double(val) => write!(f, "[{val}]"), } @@ -281,6 +282,10 @@ impl Type { Type { bits: ty.bits, spec: Specialization::Int(val as u64) } } + pub fn from_cptr(val: *mut u8) -> Type { + Type { bits: bits::CPtr, spec: Specialization::Int(val as u64) } + } + /// Create a `Type` (a `CDouble` with double specialization) from a f64. pub fn from_double(val: f64) -> Type { Type { bits: bits::CDouble, spec: Specialization::Double(val) } diff --git a/zjit/src/stats.rs b/zjit/src/stats.rs index 4f38e4a131abf8..3d9ce07c36cf20 100644 --- a/zjit/src/stats.rs +++ b/zjit/src/stats.rs @@ -246,6 +246,7 @@ pub fn exit_counter_ptr(reason: crate::hir::SideExitReason) -> *mut u64 { StackOverflow => exit_stackoverflow, BlockParamProxyModified => exit_block_param_proxy_modified, BlockParamProxyNotIseqOrIfunc => exit_block_param_proxy_not_iseq_or_ifunc, + OptionalArgumentsSupplied => exit_optional_arguments, }; counter_ptr(counter) } From 5e817f98af9024f34a3491c0aa6526d1191f8c11 Mon Sep 17 00:00:00 2001 From: Takashi Kokubun Date: Wed, 24 Sep 2025 15:48:56 -0700 Subject: [PATCH 4/4] ZJIT: Prefer *const u8 for consts (#14652) --- zjit/src/codegen.rs | 4 ++-- zjit/src/hir.rs | 4 ++-- zjit/src/hir_type/mod.rs | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/zjit/src/codegen.rs b/zjit/src/codegen.rs index 5e53c829f0b6eb..682b7ea61d21bc 100644 --- a/zjit/src/codegen.rs +++ b/zjit/src/codegen.rs @@ -965,8 +965,8 @@ fn gen_const_value(val: VALUE) -> lir::Opnd { } /// Compile Const::CPtr -fn gen_const_cptr(val: *mut u8) -> lir::Opnd { - Opnd::UImm(val as u64) +fn gen_const_cptr(val: *const u8) -> lir::Opnd { + Opnd::const_ptr(val) } /// Compile a basic block argument diff --git a/zjit/src/hir.rs b/zjit/src/hir.rs index d040e4e7a30182..a23d117d7d27c5 100644 --- a/zjit/src/hir.rs +++ b/zjit/src/hir.rs @@ -270,7 +270,7 @@ pub enum Const { CUInt16(u16), CUInt32(u32), CUInt64(u64), - CPtr(*mut u8), + CPtr(*const u8), CDouble(f64), } @@ -4139,7 +4139,7 @@ fn compile_entry_block(entry_block: BlockId, first_block: BlockId, fun: &mut Fun let opt_num = unsafe { get_iseq_body_param_opt_num(iseq) }; if !jit_entry && opt_num > 0 { let pc = fun.push_insn(entry_block, Insn::LoadPC); - let no_opts_pc = fun.push_insn(entry_block, Insn::Const { val: Const::CPtr(unsafe { rb_iseq_pc_at_idx(iseq, 0) } as *mut u8) }); + let no_opts_pc = fun.push_insn(entry_block, Insn::Const { val: Const::CPtr(unsafe { rb_iseq_pc_at_idx(iseq, 0) } as *const u8) }); let test_id = fun.push_insn(entry_block, Insn::IsBitEqual { left: pc, right: no_opts_pc }); // Jump to the first_block if no optional arguments are supplied diff --git a/zjit/src/hir_type/mod.rs b/zjit/src/hir_type/mod.rs index 24bee1c0568e9a..3e690c79d0c04f 100644 --- a/zjit/src/hir_type/mod.rs +++ b/zjit/src/hir_type/mod.rs @@ -95,7 +95,7 @@ fn write_spec(f: &mut std::fmt::Formatter, printer: &TypePrinter) -> std::fmt::R Specialization::Int(val) if ty.is_subtype(types::CUInt16) => write!(f, "[{}]", val >> 48), Specialization::Int(val) if ty.is_subtype(types::CUInt32) => write!(f, "[{}]", val >> 32), Specialization::Int(val) if ty.is_subtype(types::CUInt64) => write!(f, "[{}]", val), - Specialization::Int(val) if ty.is_subtype(types::CPtr) => write!(f, "[{}]", Const::CPtr(val as *mut u8).print(printer.ptr_map)), + Specialization::Int(val) if ty.is_subtype(types::CPtr) => write!(f, "[{}]", Const::CPtr(val as *const u8).print(printer.ptr_map)), Specialization::Int(val) => write!(f, "[{val}]"), Specialization::Double(val) => write!(f, "[{val}]"), } @@ -282,7 +282,7 @@ impl Type { Type { bits: ty.bits, spec: Specialization::Int(val as u64) } } - pub fn from_cptr(val: *mut u8) -> Type { + pub fn from_cptr(val: *const u8) -> Type { Type { bits: bits::CPtr, spec: Specialization::Int(val as u64) } }