зеркало из https://github.com/github/ruby.git
only generate wb when we really need to
This commit is contained in:
Родитель
744b0527ea
Коммит
07fe3d37c5
|
@ -2141,11 +2141,11 @@ fn gen_getinstancevariable(
|
||||||
// This function doesn't deal with writing the shape, or expanding an object
|
// This function doesn't deal with writing the shape, or expanding an object
|
||||||
// to use an IV buffer if necessary. That is the callers responsibility
|
// to use an IV buffer if necessary. That is the callers responsibility
|
||||||
fn gen_write_iv(
|
fn gen_write_iv(
|
||||||
ctx: &mut Context,
|
|
||||||
asm: &mut Assembler,
|
asm: &mut Assembler,
|
||||||
comptime_receiver: VALUE,
|
comptime_receiver: VALUE,
|
||||||
recv: Opnd,
|
recv: Opnd,
|
||||||
ivar_index: usize,
|
ivar_index: usize,
|
||||||
|
set_value: Opnd,
|
||||||
extension_needed: bool)
|
extension_needed: bool)
|
||||||
{
|
{
|
||||||
// Compile time self is embedded and the ivar index lands within the object
|
// Compile time self is embedded and the ivar index lands within the object
|
||||||
|
@ -2158,7 +2158,7 @@ fn gen_write_iv(
|
||||||
|
|
||||||
// Write the IV
|
// Write the IV
|
||||||
asm.comment("write IV");
|
asm.comment("write IV");
|
||||||
asm.mov(ivar_opnd, ctx.stack_pop(0));
|
asm.mov(ivar_opnd, set_value);
|
||||||
} else {
|
} else {
|
||||||
// Compile time value is *not* embedded.
|
// Compile time value is *not* embedded.
|
||||||
|
|
||||||
|
@ -2169,7 +2169,7 @@ fn gen_write_iv(
|
||||||
let ivar_opnd = Opnd::mem(64, tbl_opnd, (SIZEOF_VALUE * ivar_index) as i32);
|
let ivar_opnd = Opnd::mem(64, tbl_opnd, (SIZEOF_VALUE * ivar_index) as i32);
|
||||||
|
|
||||||
asm.comment("write IV");
|
asm.comment("write IV");
|
||||||
asm.mov(ivar_opnd, ctx.stack_pop(0));
|
asm.mov(ivar_opnd, set_value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2197,6 +2197,8 @@ fn gen_setinstancevariable(
|
||||||
return CantCompile;
|
return CantCompile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let (_, stack_type) = ctx.get_opnd_mapping(StackOpnd(0));
|
||||||
|
|
||||||
// Check if the comptime class uses a custom allocator
|
// Check if the comptime class uses a custom allocator
|
||||||
let custom_allocator = unsafe { rb_get_alloc_func(comptime_val_klass) };
|
let custom_allocator = unsafe { rb_get_alloc_func(comptime_val_klass) };
|
||||||
let uses_custom_allocator = match custom_allocator {
|
let uses_custom_allocator = match custom_allocator {
|
||||||
|
@ -2284,6 +2286,8 @@ fn gen_setinstancevariable(
|
||||||
megamorphic_side_exit,
|
megamorphic_side_exit,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let write_val = ctx.stack_pop(1);
|
||||||
|
|
||||||
match ivar_index {
|
match ivar_index {
|
||||||
// If we don't have an instance variable index, then we need to
|
// If we don't have an instance variable index, then we need to
|
||||||
// transition out of the current shape.
|
// transition out of the current shape.
|
||||||
|
@ -2326,7 +2330,7 @@ fn gen_setinstancevariable(
|
||||||
rb_shape_id(rb_shape_get_next(shape, comptime_receiver, ivar_name))
|
rb_shape_id(rb_shape_get_next(shape, comptime_receiver, ivar_name))
|
||||||
};
|
};
|
||||||
|
|
||||||
gen_write_iv(ctx, asm, comptime_receiver, recv, ivar_index, needs_extension);
|
gen_write_iv(asm, comptime_receiver, recv, ivar_index, write_val, needs_extension);
|
||||||
|
|
||||||
asm.comment("write shape");
|
asm.comment("write shape");
|
||||||
let cleared_flags = asm.and(
|
let cleared_flags = asm.and(
|
||||||
|
@ -2344,12 +2348,13 @@ fn gen_setinstancevariable(
|
||||||
// the iv index by searching up the shape tree. If we've
|
// the iv index by searching up the shape tree. If we've
|
||||||
// made the transition already, then there's no reason to
|
// made the transition already, then there's no reason to
|
||||||
// update the shape on the object. Just set the IV.
|
// update the shape on the object. Just set the IV.
|
||||||
gen_write_iv(ctx, asm, comptime_receiver, recv, ivar_index, false);
|
gen_write_iv(asm, comptime_receiver, recv, ivar_index, write_val, false);
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
let write_val = ctx.stack_pop(1);
|
// If we know the stack value is an immediate, there's no need to
|
||||||
|
// generate WB code.
|
||||||
|
if !stack_type.is_imm() {
|
||||||
let skip_wb = asm.new_label("skip_wb");
|
let skip_wb = asm.new_label("skip_wb");
|
||||||
// If the value we're writing is an immediate, we don't need to WB
|
// If the value we're writing is an immediate, we don't need to WB
|
||||||
asm.test(write_val, (RUBY_IMMEDIATE_MASK as u64).into());
|
asm.test(write_val, (RUBY_IMMEDIATE_MASK as u64).into());
|
||||||
|
@ -2370,6 +2375,7 @@ fn gen_setinstancevariable(
|
||||||
|
|
||||||
asm.write_label(skip_wb);
|
asm.write_label(skip_wb);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
KeepCompiling
|
KeepCompiling
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче