Skip to content

Commit eb379bc

Browse files
committed
.
1 parent c6e465a commit eb379bc

File tree

1 file changed

+14
-35
lines changed

1 file changed

+14
-35
lines changed

zjit/src/hir.rs

Lines changed: 14 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -2943,61 +2943,34 @@ impl Function {
29432943
self.push_insn_id(block, insn_id); continue;
29442944
}
29452945
let mut ivar_index: u16 = 0;
2946+
let mut next_shape_id = recv_type.shape();
29462947
if !unsafe { rb_shape_get_iv_index(recv_type.shape().0, id, &mut ivar_index) } {
29472948
// Current shape does not contain this ivar; do a shape transition.
29482949
let current_shape_id = recv_type.shape();
29492950
let class = recv_type.class();
29502951
// We're only looking at T_OBJECT so ignore all of the imemo stuff.
29512952
assert!(recv_type.flags().is_t_object());
2952-
let next_shape_id = unsafe { rb_shape_transition_add_ivar_no_warnings(class, current_shape_id.0, id) };
2953-
let ivar_result = unsafe { rb_shape_get_iv_index(next_shape_id, id, &mut ivar_index) };
2953+
next_shape_id = ShapeId(unsafe { rb_shape_transition_add_ivar_no_warnings(class, current_shape_id.0, id) });
2954+
let ivar_result = unsafe { rb_shape_get_iv_index(next_shape_id.0, id, &mut ivar_index) };
29542955
assert!(ivar_result, "New shape must have the ivar index");
29552956
// If the VM ran out of shapes, or this class generated too many leaf,
29562957
// it may be de-optimized into OBJ_TOO_COMPLEX_SHAPE (hash-table).
2957-
let new_shape_too_complex = unsafe { rb_jit_shape_too_complex_p(next_shape_id) };
2958+
let new_shape_too_complex = unsafe { rb_jit_shape_too_complex_p(next_shape_id.0) };
29582959
// TODO(max): Is it OK to bail out here after making a shape transition?
29592960
if new_shape_too_complex {
2960-
// TODO(max): Handle too-complex case
29612961
self.push_insn(block, Insn::IncrCounter(Counter::setivar_fallback_new_shape_too_complex));
29622962
self.push_insn_id(block, insn_id); continue;
29632963
}
29642964
let current_capacity = unsafe { rb_jit_shape_capacity(current_shape_id.0) };
2965-
let next_capacity = unsafe { rb_jit_shape_capacity(next_shape_id) };
2965+
let next_capacity = unsafe { rb_jit_shape_capacity(next_shape_id.0) };
29662966
// If the new shape has a different capacity, or is TOO_COMPLEX, we'll have to
29672967
// reallocate it.
29682968
let needs_extension = next_capacity != current_capacity;
29692969
if needs_extension {
2970-
// TODO(max): Handle needs-extension case
29712970
self.push_insn(block, Insn::IncrCounter(Counter::setivar_fallback_new_shape_needs_extension));
29722971
self.push_insn_id(block, insn_id); continue;
29732972
}
2974-
2975-
2976-
let self_val = self.push_insn(block, Insn::GuardType { val: self_val, guard_type: types::HeapBasicObject, state });
2977-
let self_val = self.push_insn(block, Insn::GuardShape { val: self_val, shape: recv_type.shape(), state });
2978-
let (ivar_storage, offset) = if recv_type.flags().is_embedded() {
2979-
// See ROBJECT_FIELDS() from include/ruby/internal/core/robject.h
2980-
let offset = ROBJECT_OFFSET_AS_ARY as i32 + (SIZEOF_VALUE * ivar_index.to_usize()) as i32;
2981-
(self_val, offset)
2982-
} else {
2983-
let as_heap = self.push_insn(block, Insn::LoadField { recv: self_val, id: ID!(_as_heap), offset: ROBJECT_OFFSET_AS_HEAP_FIELDS as i32, return_type: types::CPtr });
2984-
let offset = SIZEOF_VALUE_I32 * ivar_index as i32;
2985-
(as_heap, offset)
2986-
};
2987-
self.push_insn(block, Insn::StoreField { recv: ivar_storage, id, offset, val });
2988-
self.push_insn(block, Insn::WriteBarrier { recv: self_val, val });
2989-
// Write the new shape ID
2990-
assert_eq!(SHAPE_ID_NUM_BITS, 32);
2991-
let shape_id = self.push_insn(block, Insn::Const { val: Const::CUInt32(next_shape_id) });
2992-
let shape_id_offset = unsafe { rb_shape_id_offset() };
2993-
self.push_insn(block, Insn::StoreField { recv: self_val, id: ID!(_shape_id), offset: shape_id_offset, val: shape_id });
2994-
continue;
2995-
2996-
2997-
2998-
// // TODO(max): Shape transition
2999-
// self.push_insn(block, Insn::IncrCounter(Counter::setivar_fallback_shape_transition));
3000-
// self.push_insn_id(block, insn_id); continue;
2973+
// Fall through to emitting the ivar write
30012974
}
30022975
let self_val = self.push_insn(block, Insn::GuardType { val: self_val, guard_type: types::HeapBasicObject, state });
30032976
let self_val = self.push_insn(block, Insn::GuardShape { val: self_val, shape: recv_type.shape(), state });
@@ -3011,9 +2984,15 @@ impl Function {
30112984
let offset = SIZEOF_VALUE_I32 * ivar_index as i32;
30122985
(as_heap, offset)
30132986
};
3014-
let replacement = self.push_insn(block, Insn::StoreField { recv: ivar_storage, id, offset, val });
2987+
self.push_insn(block, Insn::StoreField { recv: ivar_storage, id, offset, val });
30152988
self.push_insn(block, Insn::WriteBarrier { recv: self_val, val });
3016-
self.make_equal_to(insn_id, replacement);
2989+
if next_shape_id != recv_type.shape() {
2990+
// Write the new shape ID
2991+
assert_eq!(SHAPE_ID_NUM_BITS, 32);
2992+
let shape_id = self.push_insn(block, Insn::Const { val: Const::CUInt32(next_shape_id.0) });
2993+
let shape_id_offset = unsafe { rb_shape_id_offset() };
2994+
self.push_insn(block, Insn::StoreField { recv: self_val, id: ID!(_shape_id), offset: shape_id_offset, val: shape_id });
2995+
}
30172996
}
30182997
_ => { self.push_insn_id(block, insn_id); }
30192998
}

0 commit comments

Comments
 (0)