Skip to content

Commit 1a03f53

Browse files
tobiclaude
andcommitted
ZJIT: Eliminate GuardType on frozen objects
When GuardType operates on a value that is a known frozen object (from a constant), we can check at compile time if the object's type matches the guard. Since frozen objects cannot change their class, the runtime guard becomes unnecessary. This optimization eliminates redundant type guards when accessing methods on frozen constant objects, complementing the LoadField folding for ivar reads. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent b208f46 commit 1a03f53

File tree

1 file changed

+17
-4
lines changed

1 file changed

+17
-4
lines changed

zjit/src/hir.rs

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3677,11 +3677,24 @@ impl Function {
36773677
let mut new_insns = vec![];
36783678
for insn_id in old_insns {
36793679
let replacement_id = match self.find(insn_id) {
3680-
Insn::GuardType { val, guard_type, .. } if self.is_a(val, guard_type) => {
3681-
self.make_equal_to(insn_id, val);
3682-
// Don't bother re-inferring the type of val; we already know it.
3683-
continue;
3680+
Insn::GuardType { val, guard_type, .. } => {
3681+
// If we already know the type matches, eliminate the guard
3682+
if self.is_a(val, guard_type) {
3683+
self.make_equal_to(insn_id, val);
3684+
continue;
3685+
}
3686+
// If GuardType is on a frozen object, we can check at compile time if the
3687+
// object's type matches the guard. Frozen objects can't change class.
3688+
let val_type = self.type_of(val);
3689+
if let Some(obj) = val_type.ruby_object() {
3690+
if obj.is_frozen() && Type::from_value(obj).is_subtype(guard_type) {
3691+
self.make_equal_to(insn_id, val);
3692+
continue;
3693+
}
3694+
}
3695+
insn_id
36843696
}
3697+
36853698
Insn::LoadField { recv, offset, return_type, .. } if return_type.is_subtype(types::BasicObject) &&
36863699
u32::try_from(offset).is_ok() => {
36873700
let offset = (offset as u32).to_usize();

0 commit comments

Comments
 (0)