Skip to content

Commit 4f900e3

Browse files
committed
ZJIT: Only optimize [] and []= for exact Hash, not Hash subclasses
1 parent 309d6ef commit 4f900e3

File tree

3 files changed

+23
-13
lines changed

3 files changed

+23
-13
lines changed

zjit/src/cruby_methods.rs

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -350,18 +350,30 @@ fn inline_array_pop(fun: &mut hir::Function, block: hir::BlockId, recv: hir::Ins
350350
}
351351

352352
fn inline_hash_aref(fun: &mut hir::Function, block: hir::BlockId, recv: hir::InsnId, args: &[hir::InsnId], state: hir::InsnId) -> Option<hir::InsnId> {
353-
if let &[key] = args {
353+
let &[key] = args else { return None; };
354+
355+
// Only optimize exact Hash, not subclasses
356+
if fun.likely_a(recv, types::HashExact, state) {
357+
let recv = fun.coerce_to(block, recv, types::HashExact, state);
354358
let result = fun.push_insn(block, hir::Insn::HashAref { hash: recv, key, state });
355-
return Some(result);
359+
Some(result)
360+
} else {
361+
None
356362
}
357-
None
358363
}
359364

360365
fn inline_hash_aset(fun: &mut hir::Function, block: hir::BlockId, recv: hir::InsnId, args: &[hir::InsnId], state: hir::InsnId) -> Option<hir::InsnId> {
361366
let &[key, val] = args else { return None; };
362-
let _ = fun.push_insn(block, hir::Insn::HashAset { hash: recv, key, val, state });
363-
// Hash#[]= returns the value, not the hash
364-
Some(val)
367+
368+
// Only optimize exact Hash, not subclasses
369+
if fun.likely_a(recv, types::HashExact, state) {
370+
let recv = fun.coerce_to(block, recv, types::HashExact, state);
371+
let _ = fun.push_insn(block, hir::Insn::HashAset { hash: recv, key, val, state });
372+
// Hash#[]= returns the value, not the hash
373+
Some(val)
374+
} else {
375+
None
376+
}
365377
}
366378

367379
fn inline_string_bytesize(fun: &mut hir::Function, block: hir::BlockId, recv: hir::InsnId, args: &[hir::InsnId], state: hir::InsnId) -> Option<hir::InsnId> {

zjit/src/hir.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4710,7 +4710,7 @@ impl Function {
47104710
}
47114711
// Instructions with Hash operands
47124712
Insn::HashAref { hash, .. }
4713-
| Insn::HashAset { hash, .. } => self.assert_subtype(insn_id, hash, types::Hash),
4713+
| Insn::HashAset { hash, .. } => self.assert_subtype(insn_id, hash, types::HashExact),
47144714
Insn::HashDup { val, .. } => self.assert_subtype(insn_id, val, types::HashExact),
47154715
// Other
47164716
Insn::ObjectAllocClass { class, .. } => {

zjit/src/hir/opt_tests.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6678,7 +6678,7 @@ mod hir_opt_tests {
66786678
}
66796679

66806680
#[test]
6681-
fn test_hash_aref_subclass() {
6681+
fn test_no_optimize_hash_aref_subclass() {
66826682
eval("
66836683
class C < Hash; end
66846684
def test(hash, key)
@@ -6701,8 +6701,7 @@ mod hir_opt_tests {
67016701
PatchPoint MethodRedefined(C@0x1000, []@0x1008, cme:0x1010)
67026702
PatchPoint NoSingletonClass(C@0x1000)
67036703
v27:HashSubclass[class_exact:C] = GuardType v11, HashSubclass[class_exact:C]
6704-
v28:BasicObject = HashAref v27, v12
6705-
IncrCounter inline_cfunc_optimized_send_count
6704+
v28:BasicObject = CCallWithFrame v27, :Hash#[]@0x1038, v12
67066705
CheckInterrupts
67076706
Return v28
67086707
");
@@ -6803,7 +6802,7 @@ mod hir_opt_tests {
68036802
}
68046803

68056804
#[test]
6806-
fn test_hash_aset_subclass() {
6805+
fn test_no_optimize_hash_aset_subclass() {
68076806
eval("
68086807
class C < Hash; end
68096808
def test(hash, key, val)
@@ -6827,8 +6826,7 @@ mod hir_opt_tests {
68276826
PatchPoint MethodRedefined(C@0x1000, []=@0x1008, cme:0x1010)
68286827
PatchPoint NoSingletonClass(C@0x1000)
68296828
v35:HashSubclass[class_exact:C] = GuardType v13, HashSubclass[class_exact:C]
6830-
HashAset v35, v14, v15
6831-
IncrCounter inline_cfunc_optimized_send_count
6829+
v36:BasicObject = CCallWithFrame v35, :Hash#[]=@0x1038, v14, v15
68326830
CheckInterrupts
68336831
Return v15
68346832
");

0 commit comments

Comments
 (0)