Skip to content

Commit

Permalink
Port newhash, add tests for newhash, duphash
Browse files Browse the repository at this point in the history
  • Loading branch information
maximecb authored and k0kubun committed Aug 25, 2022
1 parent f17932c commit 89cfaff
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 41 deletions.
16 changes: 16 additions & 0 deletions bootstraptest/test_yjit_new_backend.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,22 @@ def foo(n)
foo(7)
}

# duphash
assert_equal '{:a=>888}', %q{
def foo()
{ a: 888 }
end
foo()
}

# putobject, getlocal, newhash
assert_equal '{:a=>777}', %q{
def foo(n)
{ a: n }
end
foo(777)
}

# TODO: progress towards getting branches and calls working
=begin
def foo(n)
Expand Down
3 changes: 3 additions & 0 deletions yjit/src/backend/arm64/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,9 @@ impl Assembler
emit_push(cb, sys_scratch);
},
Op::CPop => {
emit_pop(cb, insn.out.into());
},
Op::CPopInto => {
emit_pop(cb, insn.opnds[0].into());
},
Op::CPopAll => {
Expand Down
17 changes: 16 additions & 1 deletion yjit/src/backend/ir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ pub enum Op
// Push and pop registers to/from the C stack
CPush,
CPop,
CPopInto,

// Push and pop all of the caller-save registers and the flags to/from the C
// stack
Expand Down Expand Up @@ -743,6 +744,19 @@ macro_rules! def_push_jcc {
};
}

macro_rules! def_push_0_opnd {
($op_name:ident, $opcode:expr) => {
impl Assembler
{
#[must_use]
pub fn $op_name(&mut self) -> Opnd
{
self.push_insn($opcode, vec![], None)
}
}
};
}

macro_rules! def_push_0_opnd_no_out {
($op_name:ident, $opcode:expr) => {
impl Assembler
Expand Down Expand Up @@ -817,7 +831,8 @@ def_push_2_opnd!(sub, Op::Sub);
def_push_2_opnd!(and, Op::And);
def_push_1_opnd!(not, Op::Not);
def_push_1_opnd_no_out!(cpush, Op::CPush);
def_push_1_opnd_no_out!(cpop, Op::CPop);
def_push_0_opnd!(cpop, Op::CPop);
def_push_1_opnd_no_out!(cpop_into, Op::CPopInto);
def_push_0_opnd_no_out!(cpush_all, Op::CPushAll);
def_push_0_opnd_no_out!(cpop_all, Op::CPopAll);
def_push_1_opnd_no_out!(cret, Op::CRet);
Expand Down
5 changes: 3 additions & 2 deletions yjit/src/backend/x86_64/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,9 +243,10 @@ impl Assembler
// Load effective address
Op::Lea => lea(cb, insn.out.into(), insn.opnds[0].into()),

// Push and pop to the C stack
// Push and pop to/from the C stack
Op::CPush => push(cb, insn.opnds[0].into()),
Op::CPop => pop(cb, insn.opnds[0].into()),
Op::CPop => pop(cb, insn.out.into()),
Op::CPopInto => pop(cb, insn.opnds[0].into()),

// Push and pop to the C stack all caller-save registers and the
// flags
Expand Down
80 changes: 42 additions & 38 deletions yjit/src/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -394,9 +394,9 @@ fn gen_code_for_exit_from_stub(ocb: &mut OutlinedCb) -> CodePtr {

gen_counter_incr!(asm, exit_from_branch_stub);

asm.cpop(SP);
asm.cpop(EC);
asm.cpop(CFP);
asm.cpop_into(SP);
asm.cpop_into(EC);
asm.cpop_into(CFP);

asm.cret(Qundef.into());

Expand Down Expand Up @@ -443,9 +443,9 @@ fn gen_exit(exit_pc: *mut VALUE, ctx: &Context, asm: &mut Assembler) {
}
}

asm.cpop(SP);
asm.cpop(EC);
asm.cpop(CFP);
asm.cpop_into(SP);
asm.cpop_into(EC);
asm.cpop_into(CFP);

asm.cret(Qundef.into());
}
Expand Down Expand Up @@ -527,9 +527,9 @@ fn gen_full_cfunc_return(ocb: &mut OutlinedCb) -> CodePtr {
gen_counter_incr!(asm, traced_cfunc_return);

// Return to the interpreter
asm.cpop(SP);
asm.cpop(EC);
asm.cpop(CFP);
asm.cpop_into(SP);
asm.cpop_into(EC);
asm.cpop_into(CFP);

asm.cret(Qundef.into());

Expand All @@ -551,9 +551,9 @@ fn gen_leave_exit(ocb: &mut OutlinedCb) -> CodePtr {
// Every exit to the interpreter should be counted
gen_counter_incr!(asm, leave_interp_return);

asm.cpop(SP);
asm.cpop(EC);
asm.cpop(CFP);
asm.cpop_into(SP);
asm.cpop_into(EC);
asm.cpop_into(CFP);

asm.cret(C_RET_OPND);

Expand All @@ -580,9 +580,9 @@ fn gen_pc_guard(asm: &mut Assembler, iseq: IseqPtr, insn_idx: u32) {
// We're not starting at the first PC, so we need to exit.
gen_counter_incr!(asm, leave_start_pc_non_zero);

asm.cpop(SP);
asm.cpop(EC);
asm.cpop(CFP);
asm.cpop_into(SP);
asm.cpop_into(EC);
asm.cpop_into(CFP);

asm.cret(Qundef.into());

Expand Down Expand Up @@ -1706,55 +1706,59 @@ fn gen_setlocal_wc1(
let idx = jit_get_arg(jit, 0).as_i32();
gen_setlocal_generic(jit, ctx, cb, ocb, idx, 1)
}
*/

// new hash initialized from top N values
fn gen_newhash(
jit: &mut JITState,
ctx: &mut Context,
cb: &mut CodeBlock,
asm: &mut Assembler,
_ocb: &mut OutlinedCb,
) -> CodegenStatus {
let num: i64 = jit_get_arg(jit, 0).as_i64();
let num: u64 = jit_get_arg(jit, 0).as_u64();

// Save the PC and SP because we are allocating
jit_prepare_routine_call(jit, ctx, cb, REG0);
jit_prepare_routine_call(jit, ctx, asm);

if num != 0 {
// val = rb_hash_new_with_size(num / 2);
mov(cb, C_ARG_REGS[0], imm_opnd(num / 2));
call_ptr(cb, REG0, rb_hash_new_with_size as *const u8);
let new_hash = asm.ccall(
rb_hash_new_with_size as *const u8,
vec![Opnd::UImm(num / 2)]
);

// Save the allocated hash as we want to push it after insertion
asm.cpush(new_hash);
asm.cpush(new_hash); // x86 alignment

// save the allocated hash as we want to push it after insertion
push(cb, RAX);
push(cb, RAX); // alignment
// Get a pointer to the values to insert into the hash
let stack_addr_from_top = asm.lea(ctx.stack_opnd((num - 1) as i32));

// rb_hash_bulk_insert(num, STACK_ADDR_FROM_TOP(num), val);
mov(cb, C_ARG_REGS[0], imm_opnd(num));
lea(
cb,
C_ARG_REGS[1],
ctx.stack_opnd((num - 1).try_into().unwrap()),
asm.ccall(
rb_hash_bulk_insert as *const u8,
vec![
Opnd::UImm(num),
stack_addr_from_top,
new_hash
]
);
mov(cb, C_ARG_REGS[2], RAX);
call_ptr(cb, REG0, rb_hash_bulk_insert as *const u8);

pop(cb, RAX); // alignment
pop(cb, RAX);
let new_hash = asm.cpop();
asm.cpop_into(new_hash); // x86 alignment

ctx.stack_pop(num.try_into().unwrap());
let stack_ret = ctx.stack_push(Type::Hash);
mov(cb, stack_ret, RAX);
asm.mov(stack_ret, new_hash);
} else {
// val = rb_hash_new();
call_ptr(cb, REG0, rb_hash_new as *const u8);
let new_hash = asm.ccall(rb_hash_new as *const u8, vec![]);
let stack_ret = ctx.stack_push(Type::Hash);
mov(cb, stack_ret, RAX);
asm.mov(stack_ret, new_hash);
}

KeepCompiling
}
*/

fn gen_putstring(
jit: &mut JITState,
Expand Down Expand Up @@ -6005,8 +6009,8 @@ fn get_gen_fn(opcode: VALUE) -> Option<InsnGenFn> {
YARVINSN_opt_minus => Some(gen_opt_minus),
YARVINSN_opt_and => Some(gen_opt_and),
YARVINSN_opt_or => Some(gen_opt_or),
YARVINSN_newhash => Some(gen_newhash),
*/
YARVINSN_newhash => Some(gen_newhash),
YARVINSN_duphash => Some(gen_duphash),
YARVINSN_newarray => Some(gen_newarray),
/*
Expand Down

0 comments on commit 89cfaff

Please sign in to comment.