mirror of
https://github.com/ruby/ruby.git
synced 2025-08-15 13:39:04 +02:00
ZJIT: Add new ZJIT types for Set (#13743)
This commit is contained in:
parent
44e4b02754
commit
dc1b55a387
7 changed files with 66 additions and 13 deletions
2
zjit.c
2
zjit.c
|
@ -32,6 +32,8 @@
|
|||
|
||||
#include <errno.h>
|
||||
|
||||
RUBY_EXTERN VALUE rb_cSet; // defined in set.c and it's not exposed yet
|
||||
|
||||
uint32_t
|
||||
rb_zjit_get_page_size(void)
|
||||
{
|
||||
|
|
|
@ -186,6 +186,7 @@ fn main() {
|
|||
.allowlist_var("rb_cThread")
|
||||
.allowlist_var("rb_cArray")
|
||||
.allowlist_var("rb_cHash")
|
||||
.allowlist_var("rb_cSet")
|
||||
.allowlist_var("rb_cClass")
|
||||
.allowlist_var("rb_cISeq")
|
||||
|
||||
|
|
1
zjit/src/cruby_bindings.inc.rs
generated
1
zjit/src/cruby_bindings.inc.rs
generated
|
@ -900,6 +900,7 @@ unsafe extern "C" {
|
|||
lines: *mut ::std::os::raw::c_int,
|
||||
) -> ::std::os::raw::c_int;
|
||||
pub fn rb_jit_cont_each_iseq(callback: rb_iseq_callback, data: *mut ::std::os::raw::c_void);
|
||||
pub static mut rb_cSet: VALUE;
|
||||
pub fn rb_zjit_get_page_size() -> u32;
|
||||
pub fn rb_zjit_reserve_addr_space(mem_size: u32) -> *mut u8;
|
||||
pub fn rb_zjit_profile_disable(iseq: *const rb_iseq_t);
|
||||
|
|
|
@ -6235,4 +6235,24 @@ mod opt_tests {
|
|||
Return v11
|
||||
"#]]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_set_type_from_constant() {
|
||||
eval("
|
||||
MY_SET = Set.new
|
||||
|
||||
def test = MY_SET
|
||||
|
||||
test
|
||||
test
|
||||
");
|
||||
assert_optimized_method_hir("test", expect![[r#"
|
||||
fn test:
|
||||
bb0(v0:BasicObject):
|
||||
PatchPoint SingleRactorMode
|
||||
PatchPoint StableConstantNames(0x1000, MY_SET)
|
||||
v7:SetExact[VALUE(0x1008)] = Const Value(VALUE(0x1008))
|
||||
Return v7
|
||||
"#]]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -72,6 +72,7 @@ base_type "String"
|
|||
base_type "Array"
|
||||
base_type "Hash"
|
||||
base_type "Range"
|
||||
base_type "Set"
|
||||
|
||||
(integer, integer_exact) = base_type "Integer"
|
||||
# CRuby partitions Integer into immediate and non-immediate variants.
|
||||
|
|
33
zjit/src/hir_type/hir_type.inc.rs
generated
33
zjit/src/hir_type/hir_type.inc.rs
generated
|
@ -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 | FalseClassExact | FloatExact | HashExact | IntegerExact | NilClassExact | ObjectExact | RangeExact | StringExact | SymbolExact | TrueClassExact;
|
||||
pub const BuiltinExact: u64 = ArrayExact | BasicObjectExact | FalseClassExact | FloatExact | HashExact | IntegerExact | NilClassExact | ObjectExact | RangeExact | SetExact | StringExact | SymbolExact | TrueClassExact;
|
||||
pub const CBool: u64 = 1u64 << 5;
|
||||
pub const CDouble: u64 = 1u64 << 6;
|
||||
pub const CInt: u64 = CSigned | CUnsigned;
|
||||
|
@ -48,26 +48,29 @@ mod bits {
|
|||
pub const NilClass: u64 = NilClassExact | NilClassSubclass;
|
||||
pub const NilClassExact: u64 = 1u64 << 28;
|
||||
pub const NilClassSubclass: u64 = 1u64 << 29;
|
||||
pub const Object: u64 = Array | FalseClass | Float | Hash | Integer | NilClass | ObjectExact | ObjectSubclass | Range | String | Symbol | TrueClass;
|
||||
pub const Object: u64 = Array | FalseClass | Float | Hash | Integer | NilClass | ObjectExact | ObjectSubclass | Range | Set | String | Symbol | TrueClass;
|
||||
pub const ObjectExact: u64 = 1u64 << 30;
|
||||
pub const ObjectSubclass: u64 = 1u64 << 31;
|
||||
pub const Range: u64 = RangeExact | RangeSubclass;
|
||||
pub const RangeExact: u64 = 1u64 << 32;
|
||||
pub const RangeSubclass: u64 = 1u64 << 33;
|
||||
pub const RubyValue: u64 = BasicObject | CallableMethodEntry | Undef;
|
||||
pub const StaticSymbol: u64 = 1u64 << 34;
|
||||
pub const Set: u64 = SetExact | SetSubclass;
|
||||
pub const SetExact: u64 = 1u64 << 34;
|
||||
pub const SetSubclass: u64 = 1u64 << 35;
|
||||
pub const StaticSymbol: u64 = 1u64 << 36;
|
||||
pub const String: u64 = StringExact | StringSubclass;
|
||||
pub const StringExact: u64 = 1u64 << 35;
|
||||
pub const StringSubclass: u64 = 1u64 << 36;
|
||||
pub const Subclass: u64 = ArraySubclass | BasicObjectSubclass | FalseClassSubclass | FloatSubclass | HashSubclass | IntegerSubclass | NilClassSubclass | ObjectSubclass | RangeSubclass | StringSubclass | SymbolSubclass | TrueClassSubclass;
|
||||
pub const StringExact: u64 = 1u64 << 37;
|
||||
pub const StringSubclass: u64 = 1u64 << 38;
|
||||
pub const Subclass: u64 = ArraySubclass | BasicObjectSubclass | FalseClassSubclass | FloatSubclass | HashSubclass | IntegerSubclass | NilClassSubclass | ObjectSubclass | RangeSubclass | SetSubclass | StringSubclass | SymbolSubclass | TrueClassSubclass;
|
||||
pub const Symbol: u64 = SymbolExact | SymbolSubclass;
|
||||
pub const SymbolExact: u64 = DynamicSymbol | StaticSymbol;
|
||||
pub const SymbolSubclass: u64 = 1u64 << 37;
|
||||
pub const SymbolSubclass: u64 = 1u64 << 39;
|
||||
pub const TrueClass: u64 = TrueClassExact | TrueClassSubclass;
|
||||
pub const TrueClassExact: u64 = 1u64 << 38;
|
||||
pub const TrueClassSubclass: u64 = 1u64 << 39;
|
||||
pub const Undef: u64 = 1u64 << 40;
|
||||
pub const AllBitPatterns: [(&'static str, u64); 67] = [
|
||||
pub const TrueClassExact: u64 = 1u64 << 40;
|
||||
pub const TrueClassSubclass: u64 = 1u64 << 41;
|
||||
pub const Undef: u64 = 1u64 << 42;
|
||||
pub const AllBitPatterns: [(&'static str, u64); 70] = [
|
||||
("Any", Any),
|
||||
("RubyValue", RubyValue),
|
||||
("Immediate", Immediate),
|
||||
|
@ -87,6 +90,9 @@ mod bits {
|
|||
("StringExact", StringExact),
|
||||
("SymbolExact", SymbolExact),
|
||||
("StaticSymbol", StaticSymbol),
|
||||
("Set", Set),
|
||||
("SetSubclass", SetSubclass),
|
||||
("SetExact", SetExact),
|
||||
("Range", Range),
|
||||
("RangeSubclass", RangeSubclass),
|
||||
("RangeExact", RangeExact),
|
||||
|
@ -136,7 +142,7 @@ mod bits {
|
|||
("ArrayExact", ArrayExact),
|
||||
("Empty", Empty),
|
||||
];
|
||||
pub const NumTypeBits: u64 = 41;
|
||||
pub const NumTypeBits: u64 = 43;
|
||||
}
|
||||
pub mod types {
|
||||
use super::*;
|
||||
|
@ -195,6 +201,9 @@ pub mod types {
|
|||
pub const RangeExact: Type = Type::from_bits(bits::RangeExact);
|
||||
pub const RangeSubclass: Type = Type::from_bits(bits::RangeSubclass);
|
||||
pub const RubyValue: Type = Type::from_bits(bits::RubyValue);
|
||||
pub const Set: Type = Type::from_bits(bits::Set);
|
||||
pub const SetExact: Type = Type::from_bits(bits::SetExact);
|
||||
pub const SetSubclass: Type = Type::from_bits(bits::SetSubclass);
|
||||
pub const StaticSymbol: Type = Type::from_bits(bits::StaticSymbol);
|
||||
pub const String: Type = Type::from_bits(bits::String);
|
||||
pub const StringExact: Type = Type::from_bits(bits::StringExact);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#![allow(non_upper_case_globals)]
|
||||
use crate::cruby::{Qfalse, Qnil, Qtrue, VALUE, RUBY_T_ARRAY, RUBY_T_STRING, RUBY_T_HASH};
|
||||
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};
|
||||
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};
|
||||
use crate::cruby::ClassRelationship;
|
||||
use crate::cruby::get_class_name;
|
||||
use crate::cruby::rb_mRubyVMFrozenCore;
|
||||
|
@ -195,6 +195,9 @@ impl Type {
|
|||
else if is_string_exact(val) {
|
||||
Type { bits: bits::StringExact, 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) }
|
||||
}
|
||||
|
@ -394,6 +397,7 @@ impl Type {
|
|||
if self.is_subtype(types::NilClassExact) { 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::SetExact) { return Some(unsafe { rb_cSet }); }
|
||||
if self.is_subtype(types::StringExact) { return Some(unsafe { rb_cString }); }
|
||||
if self.is_subtype(types::SymbolExact) { return Some(unsafe { rb_cSymbol }); }
|
||||
if self.is_subtype(types::TrueClassExact) { return Some(unsafe { rb_cTrueClass }); }
|
||||
|
@ -585,6 +589,21 @@ mod tests {
|
|||
assert_eq!(types::Integer.inexact_ruby_class(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set() {
|
||||
assert_subtype(types::SetExact, types::Set);
|
||||
assert_subtype(types::SetSubclass, types::Set);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set_has_ruby_class() {
|
||||
crate::cruby::with_rubyvm(|| {
|
||||
assert_eq!(types::SetExact.runtime_exact_ruby_class(), Some(unsafe { rb_cSet }));
|
||||
assert_eq!(types::Set.runtime_exact_ruby_class(), None);
|
||||
assert_eq!(types::SetSubclass.runtime_exact_ruby_class(), None);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn display_exact_bits_match() {
|
||||
assert_eq!(format!("{}", Type::fixnum(4)), "Fixnum[4]");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue