summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakashi Kokubun <takashikkbn@gmail.com>2023-02-14 09:12:48 -0800
committerGitHub <noreply@github.com>2023-02-14 12:12:48 -0500
commit55af69b15eff474b3820ee38242c83e7af5ee07f (patch)
treef3c7204a4aaaf98c6ea823b035e2ab058008d03d
parente5e506095cdcffca8938aae1391a2ce9809a164b (diff)
YJIT: Don't side-exit on too-complex shapes (#7298)
Notes
Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
-rw-r--r--yjit/src/codegen.rs19
-rw-r--r--yjit/src/stats.rs2
2 files changed, 5 insertions, 16 deletions
diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs
index e9a90b2712..9eb192b66b 100644
--- a/yjit/src/codegen.rs
+++ b/yjit/src/codegen.rs
@@ -1975,12 +1975,6 @@ fn gen_get_ivar(
recv_opnd: YARVOpnd,
side_exit: Target,
) -> CodegenStatus {
- // If the object has a too complex shape, we exit
- if comptime_receiver.shape_too_complex() {
- gen_counter_incr!(asm, getivar_too_complex);
- return CantCompile;
- }
-
let comptime_val_klass = comptime_receiver.class_of();
let starting_context = ctx.clone(); // make a copy for use with jit_chain_guard
@@ -2007,7 +2001,8 @@ fn gen_get_ivar(
// 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.
- if !receiver_t_object || uses_custom_allocator {
+ // 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() {
// General case. Call rb_ivar_get().
// VALUE rb_ivar_get(VALUE obj, ID id)
asm.comment("call rb_ivar_get()");
@@ -2214,11 +2209,6 @@ fn gen_setinstancevariable(
gen_counter_incr!(asm, setivar_frozen);
return CantCompile;
}
- // If the object has a too complex shape, we will also exit
- if comptime_receiver.shape_too_complex() {
- gen_counter_incr!(asm, setivar_too_complex);
- return CantCompile;
- }
let (_, stack_type) = ctx.get_opnd_mapping(StackOpnd(0));
@@ -2236,8 +2226,9 @@ fn gen_setinstancevariable(
let receiver_t_object = unsafe { RB_TYPE_P(comptime_receiver, RUBY_T_OBJECT) };
// 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 !receiver_t_object || uses_custom_allocator {
+ // 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 || comptime_receiver.shape_too_complex() {
asm.comment("call rb_vm_setinstancevariable()");
let ic = jit_get_arg(jit, 1).as_u64(); // type IVC
diff --git a/yjit/src/stats.rs b/yjit/src/stats.rs
index 91b253ecfb..5ca1fe55ae 100644
--- a/yjit/src/stats.rs
+++ b/yjit/src/stats.rs
@@ -265,7 +265,6 @@ make_counters! {
getivar_se_self_not_heap,
getivar_idx_out_of_range,
getivar_megamorphic,
- getivar_too_complex,
setivar_se_self_not_heap,
setivar_idx_out_of_range,
@@ -274,7 +273,6 @@ make_counters! {
setivar_not_object,
setivar_frozen,
setivar_megamorphic,
- setivar_too_complex,
oaref_argc_not_one,
oaref_arg_not_fixnum,