mirror of
https://github.com/ruby/ruby.git
synced 2026-01-27 04:24:23 +00:00
YJIT simplify gen_get_iver and gen_set_ivar
The `shape_id` now includes 3 bits for the `heap_id`. It is always non-zero for `T_OBJECT` and always zero for all other types. Hence all these allocator checks are no longer necessary.
This commit is contained in:
parent
bf3d6a17ee
commit
b1dbcd3ce3
@ -2848,24 +2848,12 @@ fn gen_get_ivar(
|
||||
recv: Opnd,
|
||||
recv_opnd: YARVOpnd,
|
||||
) -> Option<CodegenStatus> {
|
||||
let comptime_val_klass = comptime_receiver.class_of();
|
||||
|
||||
// If recv isn't already a register, load it.
|
||||
let recv = match recv {
|
||||
Opnd::InsnOut { .. } => recv,
|
||||
_ => asm.load(recv),
|
||||
};
|
||||
|
||||
// Check if the comptime class uses a custom allocator
|
||||
let custom_allocator = unsafe { rb_get_alloc_func(comptime_val_klass) };
|
||||
let uses_custom_allocator = match custom_allocator {
|
||||
Some(alloc_fun) => {
|
||||
let allocate_instance = rb_class_allocate_instance as *const u8;
|
||||
alloc_fun as *const u8 != allocate_instance
|
||||
}
|
||||
None => false,
|
||||
};
|
||||
|
||||
// Check if the comptime receiver is a T_OBJECT
|
||||
let receiver_t_object = unsafe { RB_TYPE_P(comptime_receiver, RUBY_T_OBJECT) };
|
||||
// Use a general C call at the last chain to avoid exits on megamorphic shapes
|
||||
@ -2874,12 +2862,9 @@ fn gen_get_ivar(
|
||||
gen_counter_incr(jit, asm, Counter::num_getivar_megamorphic);
|
||||
}
|
||||
|
||||
// If the class uses the default allocator, instances should all be T_OBJECT
|
||||
// NOTE: This assumes nobody changes the allocator of the class after allocation.
|
||||
// Eventually, we can encode whether an object is T_OBJECT or not
|
||||
// inside object shapes.
|
||||
// NOTE: This assumes T_OBJECT can't ever have the same shape_id as any other type.
|
||||
// too-complex shapes can't use index access, so we use rb_ivar_get for them too.
|
||||
if !receiver_t_object || uses_custom_allocator || comptime_receiver.shape_too_complex() || megamorphic {
|
||||
if !receiver_t_object || comptime_receiver.shape_too_complex() || megamorphic {
|
||||
// General case. Call rb_ivar_get().
|
||||
// VALUE rb_ivar_get(VALUE obj, ID id)
|
||||
asm_comment!(asm, "call rb_ivar_get()");
|
||||
@ -3073,8 +3058,6 @@ fn gen_set_ivar(
|
||||
recv_opnd: YARVOpnd,
|
||||
ic: Option<*const iseq_inline_iv_cache_entry>,
|
||||
) -> Option<CodegenStatus> {
|
||||
let comptime_val_klass = comptime_receiver.class_of();
|
||||
|
||||
// If the comptime receiver is frozen, writing an IV will raise an exception
|
||||
// and we don't want to JIT code to deal with that situation.
|
||||
if comptime_receiver.is_frozen() {
|
||||
@ -3084,16 +3067,6 @@ fn gen_set_ivar(
|
||||
|
||||
let stack_type = asm.ctx.get_opnd_type(StackOpnd(0));
|
||||
|
||||
// Check if the comptime class uses a custom allocator
|
||||
let custom_allocator = unsafe { rb_get_alloc_func(comptime_val_klass) };
|
||||
let uses_custom_allocator = match custom_allocator {
|
||||
Some(alloc_fun) => {
|
||||
let allocate_instance = rb_class_allocate_instance as *const u8;
|
||||
alloc_fun as *const u8 != allocate_instance
|
||||
}
|
||||
None => false,
|
||||
};
|
||||
|
||||
// Check if the comptime receiver is a T_OBJECT
|
||||
let receiver_t_object = unsafe { RB_TYPE_P(comptime_receiver, RUBY_T_OBJECT) };
|
||||
// Use a general C call at the last chain to avoid exits on megamorphic shapes
|
||||
@ -3149,10 +3122,9 @@ fn gen_set_ivar(
|
||||
None
|
||||
};
|
||||
|
||||
// If the receiver isn't a T_OBJECT, or uses a custom allocator,
|
||||
// then just write out the IV write as a function call.
|
||||
// If the receiver isn't a T_OBJECT, then just write out the IV write as a function call.
|
||||
// too-complex shapes can't use index access, so we use rb_ivar_get for them too.
|
||||
if !receiver_t_object || uses_custom_allocator || shape_too_complex || new_shape_too_complex || megamorphic {
|
||||
if !receiver_t_object || shape_too_complex || new_shape_too_complex || megamorphic {
|
||||
// The function could raise FrozenError.
|
||||
// Note that this modifies REG_SP, which is why we do it first
|
||||
jit_prepare_non_leaf_call(jit, asm);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user