[前][次][番号順一覧][スレッド一覧]

ruby-changes:73186

From: Maxime <ko1@a...>
Date: Tue, 30 Aug 2022 00:59:54 +0900 (JST)
Subject: [ruby-changes:73186] 6c50089599 (master): Port newhash, add tests for newhash, duphash

https://git.ruby-lang.org/ruby.git/commit/?id=6c50089599

From 6c5008959925d2768e9495a5601b5245784bc87f Mon Sep 17 00:00:00 2001
From: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@s...>
Date: Thu, 14 Jul 2022 16:51:01 -0400
Subject: Port newhash, add tests for newhash, duphash

---
 yjit/src/backend/arm64/mod.rs  |  3 ++
 yjit/src/backend/ir.rs         | 17 ++++++++-
 yjit/src/backend/x86_64/mod.rs |  5 +--
 yjit/src/codegen.rs            | 80 ++++++++++++++++++++++--------------------
 4 files changed, 64 insertions(+), 41 deletions(-)

diff --git a/yjit/src/backend/arm64/mod.rs b/yjit/src/backend/arm64/mod.rs
index 94da426ba3..22998b1ab5 100644
--- a/yjit/src/backend/arm64/mod.rs
+++ b/yjit/src/backend/arm64/mod.rs
@@ -466,6 +466,9 @@ impl Assembler https://github.com/ruby/ruby/blob/trunk/yjit/src/backend/arm64/mod.rs#L466
                     emit_push(cb, sys_scratch);
                 },
                 Op::CPop => {
+                    emit_pop(cb, insn.out.into());
+                },
+                Op::CPopInto => {
                     emit_pop(cb, insn.opnds[0].into());
                 },
                 Op::CPopAll => {
diff --git a/yjit/src/backend/ir.rs b/yjit/src/backend/ir.rs
index 5387629cb8..f4afa567b3 100644
--- a/yjit/src/backend/ir.rs
+++ b/yjit/src/backend/ir.rs
@@ -96,6 +96,7 @@ pub enum Op https://github.com/ruby/ruby/blob/trunk/yjit/src/backend/ir.rs#L96
     // 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
@@ -743,6 +744,19 @@ macro_rules! def_push_jcc { https://github.com/ruby/ruby/blob/trunk/yjit/src/backend/ir.rs#L744
     };
 }
 
+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
@@ -817,7 +831,8 @@ def_push_2_opnd!(sub, Op::Sub); https://github.com/ruby/ruby/blob/trunk/yjit/src/backend/ir.rs#L831
 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);
diff --git a/yjit/src/backend/x86_64/mod.rs b/yjit/src/backend/x86_64/mod.rs
index 4e0a9dcf02..dfbd9e990b 100644
--- a/yjit/src/backend/x86_64/mod.rs
+++ b/yjit/src/backend/x86_64/mod.rs
@@ -243,9 +243,10 @@ impl Assembler https://github.com/ruby/ruby/blob/trunk/yjit/src/backend/x86_64/mod.rs#L243
                 // 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
diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs
index a54137fa97..87815902ee 100644
--- a/yjit/src/codegen.rs
+++ b/yjit/src/codegen.rs
@@ -394,9 +394,9 @@ fn gen_code_for_exit_from_stub(ocb: &mut OutlinedCb) -> CodePtr { https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L394
 
     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());
 
@@ -443,9 +443,9 @@ fn gen_exit(exit_pc: *mut VALUE, ctx: &Context, asm: &mut Assembler) { https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L443
         }
     }
 
-    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());
 }
@@ -527,9 +527,9 @@ fn gen_full_cfunc_return(ocb: &mut OutlinedCb) -> CodePtr { https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L527
     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());
 
@@ -551,9 +551,9 @@ fn gen_leave_exit(ocb: &mut OutlinedCb) -> CodePtr { https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L551
     // 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);
 
@@ -580,9 +580,9 @@ fn gen_pc_guard(asm: &mut Assembler, iseq: IseqPtr, insn_idx: u32) { https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L580
     // 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());
 
@@ -1706,55 +1706,59 @@ fn gen_setlocal_wc1( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L1706
     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,
@@ -6005,8 +6009,8 @@ fn get_gen_fn(opcode: VALUE) -> Option<InsnGenFn> { https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L6009
         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),
         /*
-- 
cgit v1.2.1


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]