diff options
| author | Stan Lo <stan.lo@shopify.com> | 2025-07-07 21:37:02 +0100 |
|---|---|---|
| committer | Max Bernstein <tekknolagi@gmail.com> | 2025-07-08 12:28:03 -0400 |
| commit | af892c1be359900ef5f6be0724cbbec69f3650f0 (patch) | |
| tree | 1aff20d602bf57c5b77aac4a528cc0edfee63015 | |
| parent | 6c20082852a2f69a11d950b98ff179b2b737ed67 (diff) | |
ZJIT: More accurately model Class types
| -rw-r--r-- | zjit/src/hir.rs | 22 | ||||
| -rw-r--r-- | zjit/src/hir_type/gen_hir_type.rb | 4 | ||||
| -rw-r--r-- | zjit/src/hir_type/hir_type.inc.rs | 78 | ||||
| -rw-r--r-- | zjit/src/hir_type/mod.rs | 4 |
4 files changed, 51 insertions, 57 deletions
diff --git a/zjit/src/hir.rs b/zjit/src/hir.rs index 20ffe17683..3af2a6abf7 100644 --- a/zjit/src/hir.rs +++ b/zjit/src/hir.rs @@ -4196,10 +4196,10 @@ mod tests { assert_method_hir("test", expect![[r#" fn test: bb0(v0:BasicObject, v1:BasicObject): - v3:ClassExact[VMFrozenCore] = Const Value(VALUE(0x1000)) + v3:Class[VMFrozenCore] = Const Value(VALUE(0x1000)) v5:HashExact = NewHash v7:BasicObject = SendWithoutBlock v3, :core#hash_merge_kwd, v5, v1 - v8:ClassExact[VMFrozenCore] = Const Value(VALUE(0x1000)) + v8:Class[VMFrozenCore] = Const Value(VALUE(0x1000)) v9:StaticSymbol[:b] = Const Value(VALUE(0x1008)) v10:Fixnum[1] = Const Value(1) v12:BasicObject = SendWithoutBlock v8, :core#hash_merge_ptr, v7, v9, v10 @@ -4648,7 +4648,7 @@ mod tests { assert_method_hir_with_opcode("test", YARVINSN_putspecialobject, expect![[r#" fn test: bb0(v0:BasicObject): - v2:ClassExact[VMFrozenCore] = Const Value(VALUE(0x1000)) + v2:Class[VMFrozenCore] = Const Value(VALUE(0x1000)) v3:BasicObject = PutSpecialObject CBase v4:StaticSymbol[:aliased] = Const Value(VALUE(0x1008)) v5:StaticSymbol[:__callee__] = Const Value(VALUE(0x1010)) @@ -5889,7 +5889,7 @@ mod opt_tests { bb0(v0:BasicObject): PatchPoint SingleRactorMode PatchPoint StableConstantNames(0x1000, C) - v7:ClassExact[VALUE(0x1008)] = Const Value(VALUE(0x1008)) + v7:Class[VALUE(0x1008)] = Const Value(VALUE(0x1008)) Return v7 "#]]); } @@ -5905,16 +5905,16 @@ mod opt_tests { bb0(v0:BasicObject): PatchPoint SingleRactorMode PatchPoint StableConstantNames(0x1000, String) - v15:ClassExact[VALUE(0x1008)] = Const Value(VALUE(0x1008)) + v15:Class[VALUE(0x1008)] = Const Value(VALUE(0x1008)) PatchPoint SingleRactorMode PatchPoint StableConstantNames(0x1010, Class) - v18:ClassExact[VALUE(0x1018)] = Const Value(VALUE(0x1018)) + v18:Class[VALUE(0x1018)] = Const Value(VALUE(0x1018)) PatchPoint SingleRactorMode PatchPoint StableConstantNames(0x1020, Module) - v21:ClassExact[VALUE(0x1028)] = Const Value(VALUE(0x1028)) + v21:Class[VALUE(0x1028)] = Const Value(VALUE(0x1028)) PatchPoint SingleRactorMode PatchPoint StableConstantNames(0x1030, BasicObject) - v24:ClassExact[VALUE(0x1038)] = Const Value(VALUE(0x1038)) + v24:Class[VALUE(0x1038)] = Const Value(VALUE(0x1038)) v11:ArrayExact = NewArray v15, v18, v21, v24 Return v11 "#]]); @@ -6107,7 +6107,7 @@ mod opt_tests { bb0(v0:BasicObject): PatchPoint SingleRactorMode PatchPoint StableConstantNames(0x1000, Foo::Bar::C) - v7:ClassExact[VALUE(0x1008)] = Const Value(VALUE(0x1008)) + v7:Class[VALUE(0x1008)] = Const Value(VALUE(0x1008)) Return v7 "#]]); } @@ -6124,7 +6124,7 @@ mod opt_tests { bb0(v0:BasicObject): PatchPoint SingleRactorMode PatchPoint StableConstantNames(0x1000, C) - v20:ClassExact[VALUE(0x1008)] = Const Value(VALUE(0x1008)) + v20:Class[VALUE(0x1008)] = Const Value(VALUE(0x1008)) v4:NilClassExact = Const Value(nil) v11:BasicObject = SendWithoutBlock v20, :new Return v11 @@ -6147,7 +6147,7 @@ mod opt_tests { bb0(v0:BasicObject): PatchPoint SingleRactorMode PatchPoint StableConstantNames(0x1000, C) - v22:ClassExact[VALUE(0x1008)] = Const Value(VALUE(0x1008)) + v22:Class[VALUE(0x1008)] = Const Value(VALUE(0x1008)) v4:NilClassExact = Const Value(nil) v5:Fixnum[1] = Const Value(1) v13:BasicObject = SendWithoutBlock v22, :new, v5 diff --git a/zjit/src/hir_type/gen_hir_type.rb b/zjit/src/hir_type/gen_hir_type.rb index bbd0e1ed32..660ac342cf 100644 --- a/zjit/src/hir_type/gen_hir_type.rb +++ b/zjit/src/hir_type/gen_hir_type.rb @@ -74,8 +74,8 @@ base_type "Hash" base_type "Range" base_type "Set" base_type "Regexp" -base_type "Class" -base_type "Module" +module_class, _ = base_type "Module" +module_class.subtype "Class" (integer, integer_exact) = base_type "Integer" # CRuby partitions Integer into immediate and non-immediate variants. diff --git a/zjit/src/hir_type/hir_type.inc.rs b/zjit/src/hir_type/hir_type.inc.rs index 2c6fb48ea5..21ef8c8bdd 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 = FalseClassExact | TrueClassExact; - pub const BuiltinExact: u64 = ArrayExact | BasicObjectExact | ClassExact | FalseClassExact | FloatExact | HashExact | IntegerExact | ModuleExact | NilClassExact | ObjectExact | RangeExact | RegexpExact | SetExact | StringExact | SymbolExact | TrueClassExact; + pub const BuiltinExact: u64 = ArrayExact | BasicObjectExact | FalseClassExact | FloatExact | HashExact | IntegerExact | ModuleExact | NilClassExact | ObjectExact | RangeExact | RegexpExact | SetExact | StringExact | SymbolExact | TrueClassExact; pub const CBool: u64 = 1u64 << 5; pub const CDouble: u64 = 1u64 << 6; pub const CInt: u64 = CSigned | CUnsigned; @@ -27,59 +27,57 @@ mod bits { pub const CUnsigned: u64 = CUInt16 | CUInt32 | CUInt64 | CUInt8; pub const CValue: u64 = CBool | CDouble | CInt | CNull | CPtr; pub const CallableMethodEntry: u64 = 1u64 << 17; - pub const Class: u64 = ClassExact | ClassSubclass; - pub const ClassExact: u64 = 1u64 << 18; - pub const ClassSubclass: u64 = 1u64 << 19; - pub const DynamicSymbol: u64 = 1u64 << 20; + pub const Class: u64 = 1u64 << 18; + pub const DynamicSymbol: u64 = 1u64 << 19; pub const Empty: u64 = 0u64; pub const FalseClass: u64 = FalseClassExact | FalseClassSubclass; - pub const FalseClassExact: u64 = 1u64 << 21; - pub const FalseClassSubclass: u64 = 1u64 << 22; - pub const Fixnum: u64 = 1u64 << 23; + pub const FalseClassExact: u64 = 1u64 << 20; + pub const FalseClassSubclass: u64 = 1u64 << 21; + pub const Fixnum: u64 = 1u64 << 22; pub const Float: u64 = FloatExact | FloatSubclass; pub const FloatExact: u64 = Flonum | HeapFloat; - pub const FloatSubclass: u64 = 1u64 << 24; - pub const Flonum: u64 = 1u64 << 25; + pub const FloatSubclass: u64 = 1u64 << 23; + pub const Flonum: u64 = 1u64 << 24; pub const Hash: u64 = HashExact | HashSubclass; - pub const HashExact: u64 = 1u64 << 26; - pub const HashSubclass: u64 = 1u64 << 27; - pub const HeapFloat: u64 = 1u64 << 28; + pub const HashExact: u64 = 1u64 << 25; + pub const HashSubclass: u64 = 1u64 << 26; + pub const HeapFloat: u64 = 1u64 << 27; pub const Immediate: u64 = FalseClassExact | Fixnum | Flonum | NilClassExact | StaticSymbol | TrueClassExact | Undef; pub const Integer: u64 = IntegerExact | IntegerSubclass; pub const IntegerExact: u64 = Bignum | Fixnum; - pub const IntegerSubclass: u64 = 1u64 << 29; - pub const Module: u64 = ModuleExact | ModuleSubclass; - pub const ModuleExact: u64 = 1u64 << 30; - pub const ModuleSubclass: u64 = 1u64 << 31; + pub const IntegerSubclass: u64 = 1u64 << 28; + pub const Module: u64 = Class | ModuleExact | ModuleSubclass; + pub const ModuleExact: u64 = 1u64 << 29; + pub const ModuleSubclass: u64 = 1u64 << 30; pub const NilClass: u64 = NilClassExact | NilClassSubclass; - pub const NilClassExact: u64 = 1u64 << 32; - pub const NilClassSubclass: u64 = 1u64 << 33; - pub const Object: u64 = Array | Class | FalseClass | Float | Hash | Integer | Module | NilClass | ObjectExact | ObjectSubclass | Range | Regexp | Set | String | Symbol | TrueClass; - pub const ObjectExact: u64 = 1u64 << 34; - pub const ObjectSubclass: u64 = 1u64 << 35; + pub const NilClassExact: u64 = 1u64 << 31; + pub const NilClassSubclass: u64 = 1u64 << 32; + pub const Object: u64 = Array | FalseClass | Float | Hash | Integer | Module | NilClass | ObjectExact | ObjectSubclass | Range | Regexp | Set | String | Symbol | TrueClass; + pub const ObjectExact: u64 = 1u64 << 33; + pub const ObjectSubclass: u64 = 1u64 << 34; pub const Range: u64 = RangeExact | RangeSubclass; - pub const RangeExact: u64 = 1u64 << 36; - pub const RangeSubclass: u64 = 1u64 << 37; + pub const RangeExact: u64 = 1u64 << 35; + pub const RangeSubclass: u64 = 1u64 << 36; pub const Regexp: u64 = RegexpExact | RegexpSubclass; - pub const RegexpExact: u64 = 1u64 << 38; - pub const RegexpSubclass: u64 = 1u64 << 39; + pub const RegexpExact: u64 = 1u64 << 37; + pub const RegexpSubclass: u64 = 1u64 << 38; pub const RubyValue: u64 = BasicObject | CallableMethodEntry | Undef; pub const Set: u64 = SetExact | SetSubclass; - pub const SetExact: u64 = 1u64 << 40; - pub const SetSubclass: u64 = 1u64 << 41; - pub const StaticSymbol: u64 = 1u64 << 42; + pub const SetExact: u64 = 1u64 << 39; + pub const SetSubclass: u64 = 1u64 << 40; + pub const StaticSymbol: u64 = 1u64 << 41; pub const String: u64 = StringExact | StringSubclass; - pub const StringExact: u64 = 1u64 << 43; - pub const StringSubclass: u64 = 1u64 << 44; - pub const Subclass: u64 = ArraySubclass | BasicObjectSubclass | ClassSubclass | FalseClassSubclass | FloatSubclass | HashSubclass | IntegerSubclass | ModuleSubclass | NilClassSubclass | ObjectSubclass | RangeSubclass | RegexpSubclass | SetSubclass | StringSubclass | SymbolSubclass | TrueClassSubclass; + pub const StringExact: u64 = 1u64 << 42; + pub const StringSubclass: u64 = 1u64 << 43; + pub const Subclass: u64 = ArraySubclass | BasicObjectSubclass | FalseClassSubclass | FloatSubclass | HashSubclass | IntegerSubclass | ModuleSubclass | NilClassSubclass | ObjectSubclass | RangeSubclass | RegexpSubclass | SetSubclass | StringSubclass | SymbolSubclass | TrueClassSubclass; pub const Symbol: u64 = SymbolExact | SymbolSubclass; pub const SymbolExact: u64 = DynamicSymbol | StaticSymbol; - pub const SymbolSubclass: u64 = 1u64 << 45; + pub const SymbolSubclass: u64 = 1u64 << 44; pub const TrueClass: u64 = TrueClassExact | TrueClassSubclass; - pub const TrueClassExact: u64 = 1u64 << 46; - pub const TrueClassSubclass: u64 = 1u64 << 47; - pub const Undef: u64 = 1u64 << 48; - pub const AllBitPatterns: [(&'static str, u64); 79] = [ + pub const TrueClassExact: u64 = 1u64 << 45; + pub const TrueClassSubclass: u64 = 1u64 << 46; + pub const Undef: u64 = 1u64 << 47; + pub const AllBitPatterns: [(&'static str, u64); 77] = [ ("Any", Any), ("RubyValue", RubyValue), ("Immediate", Immediate), @@ -133,8 +131,6 @@ mod bits { ("FalseClassExact", FalseClassExact), ("DynamicSymbol", DynamicSymbol), ("Class", Class), - ("ClassSubclass", ClassSubclass), - ("ClassExact", ClassExact), ("CallableMethodEntry", CallableMethodEntry), ("CValue", CValue), ("CInt", CInt), @@ -160,7 +156,7 @@ mod bits { ("ArrayExact", ArrayExact), ("Empty", Empty), ]; - pub const NumTypeBits: u64 = 49; + pub const NumTypeBits: u64 = 48; } pub mod types { use super::*; @@ -192,8 +188,6 @@ pub mod types { pub const CValue: Type = Type::from_bits(bits::CValue); pub const CallableMethodEntry: Type = Type::from_bits(bits::CallableMethodEntry); pub const Class: Type = Type::from_bits(bits::Class); - pub const ClassExact: Type = Type::from_bits(bits::ClassExact); - pub const ClassSubclass: Type = Type::from_bits(bits::ClassSubclass); pub const DynamicSymbol: Type = Type::from_bits(bits::DynamicSymbol); pub const Empty: Type = Type::from_bits(bits::Empty); pub const FalseClass: Type = Type::from_bits(bits::FalseClass); diff --git a/zjit/src/hir_type/mod.rs b/zjit/src/hir_type/mod.rs index 907582c251..f0e701612d 100644 --- a/zjit/src/hir_type/mod.rs +++ b/zjit/src/hir_type/mod.rs @@ -214,7 +214,7 @@ impl Type { Type { bits: bits::ModuleExact, spec: Specialization::Object(val) } } else if val.builtin_type() == RUBY_T_CLASS { - Type { bits: bits::ClassExact, spec: Specialization::Object(val) } + Type { bits: bits::Class, spec: Specialization::Object(val) } } else if val.class_of() == unsafe { rb_cRegexp } { Type { bits: bits::RegexpExact, spec: Specialization::Object(val) } @@ -417,7 +417,7 @@ impl Type { return Some(val); } if self.is_subtype(types::ArrayExact) { return Some(unsafe { rb_cArray }); } - if self.is_subtype(types::ClassExact) { return Some(unsafe { rb_cClass }); } + if self.is_subtype(types::Class) { return Some(unsafe { rb_cClass }); } if self.is_subtype(types::FalseClassExact) { return Some(unsafe { rb_cFalseClass }); } if self.is_subtype(types::FloatExact) { return Some(unsafe { rb_cFloat }); } if self.is_subtype(types::HashExact) { return Some(unsafe { rb_cHash }); } |
