summaryrefslogtreecommitdiff
path: root/yjit/src/codegen.rs
diff options
context:
space:
mode:
authorAaron Patterson <[email protected]>2022-09-30 16:01:50 -0700
committerAaron Patterson <[email protected]>2022-09-30 16:01:50 -0700
commit9a6803c90b817f70389cae10d60b50ad752da48f ()
treefd03366733e1d8198c74592474adf18bb841b1a5 /yjit/src/codegen.rs
parent0ab0229c1162308509b36cafbf6eaafd7ae054d7 (diff)
Revert "This commit implements the Object Shapes technique in CRuby."
This reverts commit 68bc9e2e97d12f80df0d113e284864e225f771c2.
-rw-r--r--yjit/src/codegen.rs133
1 files changed, 76 insertions, 57 deletions
@@ -1938,9 +1938,11 @@ fn gen_set_ivar(
let val_opnd = ctx.stack_pop(1);
let recv_opnd = ctx.stack_pop(1);
- // Call rb_vm_set_ivar_id with the receiver, the ivar name, and the value
let val = asm.ccall(
- rb_vm_set_ivar_id as *const u8,
vec![
recv_opnd,
Opnd::UImm(ivar_name),
@@ -2021,82 +2023,81 @@ fn gen_get_ivar(
return EndBlock;
}
- let ivar_index = unsafe {
- let shape_id = comptime_receiver.shape_of();
- let shape = rb_shape_get_shape_by_id(shape_id);
- let mut ivar_index: u32 = 0;
- if rb_shape_get_iv_index(shape, ivar_name, &mut ivar_index) {
- Some(ivar_index as usize)
- } else {
- None
- }
- };
-
- // must be before stack_pop
- let recv_type = ctx.get_opnd_type(recv_opnd);
-
- // Upgrade type
- if !recv_type.is_heap() {
- ctx.upgrade_opnd_type(recv_opnd, Type::UnknownHeap);
- }
// Pop receiver if it's on the temp stack
if recv_opnd != SelfOpnd {
ctx.stack_pop(1);
}
- // Guard heap object
- if !recv_type.is_heap() {
- guard_object_is_heap(asm, recv, side_exit);
}
// Compile time self is embedded and the ivar index lands within the object
- let embed_test_result = unsafe { FL_TEST_RAW(comptime_receiver, VALUE(ROBJECT_EMBED.as_usize())) != VALUE(0) };
-
- let flags_mask: usize = unsafe { rb_shape_flags_mask() }.as_usize();
- let expected_flags_mask: usize = (RUBY_T_MASK as usize) | !flags_mask | (ROBJECT_EMBED as usize);
- let expected_flags = comptime_receiver.builtin_flags() & expected_flags_mask;
-
- // Combined guard for all flags: shape, embeddedness, and T_OBJECT
- let flags_opnd = Opnd::mem(64, recv, RUBY_OFFSET_RBASIC_FLAGS);
-
- asm.comment("guard shape, embedded, and T_OBJECT");
- let flags_opnd = asm.and(flags_opnd, Opnd::UImm(expected_flags_mask as u64));
- asm.cmp(flags_opnd, Opnd::UImm(expected_flags as u64));
- jit_chain_guard(
- JCC_JNE,
- jit,
- &starting_context,
- asm,
- ocb,
- max_chain_depth,
- side_exit,
- );
-
- // If there is no IVAR index, then the ivar was undefined
- // when we entered the compiler. That means we can just return
- // nil for this shape + iv name
- if ivar_index.is_none() {
- let out_opnd = ctx.stack_push(Type::Nil);
- asm.mov(out_opnd, Qnil.into());
- } else if embed_test_result {
// See ROBJECT_IVPTR() from include/ruby/internal/core/robject.h
// Load the variable
- let offs = ROBJECT_OFFSET_AS_ARY + (ivar_index.unwrap() * SIZEOF_VALUE) as i32;
let ivar_opnd = Opnd::mem(64, recv, offs);
// Push the ivar on the stack
let out_opnd = ctx.stack_push(Type::Unknown);
- asm.mov(out_opnd, ivar_opnd);
} else {
// Compile time value is *not* embedded.
if USE_RVARGC == 0 {
// Check that the extended table is big enough
// Check that the slot is inside the extended table (num_slots > index)
let num_slots = Opnd::mem(32, recv, ROBJECT_OFFSET_NUMIV);
- asm.cmp(num_slots, Opnd::UImm(ivar_index.unwrap() as u64));
asm.jbe(counted_exit!(ocb, side_exit, getivar_idx_out_of_range).into());
}
@@ -2104,10 +2105,15 @@ fn gen_get_ivar(
let tbl_opnd = asm.load(Opnd::mem(64, recv, ROBJECT_OFFSET_AS_HEAP_IVPTR));
// Read the ivar from the extended table
- let ivar_opnd = Opnd::mem(64, tbl_opnd, (SIZEOF_VALUE * ivar_index.unwrap()) as i32);
let out_opnd = ctx.stack_push(Type::Unknown);
- asm.mov(out_opnd, ivar_opnd);
}
// Jump to next instruction. This allows guard chains to share the same successor.
@@ -2130,12 +2136,25 @@ fn gen_getinstancevariable(
let ivar_name = jit_get_arg(jit, 0).as_u64();
let comptime_val = jit_peek_at_self(jit);
// Generate a side exit
let side_exit = get_side_exit(jit, ocb, ctx);
// Guard that the receiver has the same class as the one from compile time.
let self_asm_opnd = Opnd::mem(64, CFP, RUBY_OFFSET_CFP_SELF);
gen_get_ivar(
jit,