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

ruby-changes:73277

From: Noah <ko1@a...>
Date: Tue, 30 Aug 2022 01:07:31 +0900 (JST)
Subject: [ruby-changes:73277] 6b9cec78a1 (master): Port cfunc lookup, plus simpler cfunc generators. (https://github.com/Shopify/ruby/pull/388)

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

From 6b9cec78a18ae1788c8c939c705b85bd0a6efc3a Mon Sep 17 00:00:00 2001
From: Noah Gibbs <the.codefolio.guy@g...>
Date: Wed, 10 Aug 2022 16:13:22 +0100
Subject: Port cfunc lookup, plus simpler cfunc generators.
 (https://github.com/Shopify/ruby/pull/388)

This port does *not* create invalidation regions to
ensure minimum invalidatable block sizes, and so it
does not port the to_s generator.
---
 yjit/src/codegen.rs | 161 +++++++++++++++++++++++++---------------------------
 1 file changed, 77 insertions(+), 84 deletions(-)

diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs
index 67cad1c141..83d09362d1 100644
--- a/yjit/src/codegen.rs
+++ b/yjit/src/codegen.rs
@@ -3531,6 +3531,7 @@ fn jit_protected_callee_ancestry_guard( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L3531
         counted_exit!(ocb, side_exit, send_se_protected_check_failed),
     );
 }
+*/
 
 // Codegen for rb_obj_not().
 // Note, caller is responsible for generating all the right guards, including
@@ -3538,7 +3539,7 @@ fn jit_protected_callee_ancestry_guard( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L3539
 fn jit_rb_obj_not(
     _jit: &mut JITState,
     ctx: &mut Context,
-    cb: &mut CodeBlock,
+    asm: &mut Assembler,
     _ocb: &mut OutlinedCb,
     _ci: *const rb_callinfo,
     _cme: *const rb_callable_method_entry_t,
@@ -3550,17 +3551,17 @@ fn jit_rb_obj_not( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L3551
 
     match recv_opnd.known_truthy() {
         Some(false) => {
-            add_comment(cb, "rb_obj_not(nil_or_false)");
+            asm.comment("rb_obj_not(nil_or_false)");
             ctx.stack_pop(1);
             let out_opnd = ctx.stack_push(Type::True);
-            mov(cb, out_opnd, uimm_opnd(Qtrue.into()));
+            asm.mov(out_opnd, Qtrue.into());
         },
         Some(true) => {
             // Note: recv_opnd != Type::Nil && recv_opnd != Type::False.
-            add_comment(cb, "rb_obj_not(truthy)");
+            asm.comment("rb_obj_not(truthy)");
             ctx.stack_pop(1);
             let out_opnd = ctx.stack_push(Type::False);
-            mov(cb, out_opnd, uimm_opnd(Qfalse.into()));
+            asm.mov(out_opnd, Qfalse.into());
         },
         _ => {
             return false;
@@ -3574,7 +3575,7 @@ fn jit_rb_obj_not( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L3575
 fn jit_rb_true(
     _jit: &mut JITState,
     ctx: &mut Context,
-    cb: &mut CodeBlock,
+    asm: &mut Assembler,
     _ocb: &mut OutlinedCb,
     _ci: *const rb_callinfo,
     _cme: *const rb_callable_method_entry_t,
@@ -3582,10 +3583,10 @@ fn jit_rb_true( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L3583
     _argc: i32,
     _known_recv_class: *const VALUE,
 ) -> bool {
-    add_comment(cb, "nil? == true");
+    asm.comment("nil? == true");
     ctx.stack_pop(1);
     let stack_ret = ctx.stack_push(Type::True);
-    mov(cb, stack_ret, uimm_opnd(Qtrue.into()));
+    asm.mov(stack_ret, Qtrue.into());
     true
 }
 
@@ -3593,7 +3594,7 @@ fn jit_rb_true( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L3594
 fn jit_rb_false(
     _jit: &mut JITState,
     ctx: &mut Context,
-    cb: &mut CodeBlock,
+    asm: &mut Assembler,
     _ocb: &mut OutlinedCb,
     _ci: *const rb_callinfo,
     _cme: *const rb_callable_method_entry_t,
@@ -3601,10 +3602,10 @@ fn jit_rb_false( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L3602
     _argc: i32,
     _known_recv_class: *const VALUE,
 ) -> bool {
-    add_comment(cb, "nil? == false");
+    asm.comment("nil? == false");
     ctx.stack_pop(1);
     let stack_ret = ctx.stack_push(Type::False);
-    mov(cb, stack_ret, uimm_opnd(Qfalse.into()));
+    asm.mov(stack_ret, Qfalse.into());
     true
 }
 
@@ -3613,7 +3614,7 @@ fn jit_rb_false( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L3614
 fn jit_rb_obj_equal(
     _jit: &mut JITState,
     ctx: &mut Context,
-    cb: &mut CodeBlock,
+    asm: &mut Assembler,
     _ocb: &mut OutlinedCb,
     _ci: *const rb_callinfo,
     _cme: *const rb_callable_method_entry_t,
@@ -3621,18 +3622,15 @@ fn jit_rb_obj_equal( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L3622
     _argc: i32,
     _known_recv_class: *const VALUE,
 ) -> bool {
-    add_comment(cb, "equal?");
+    asm.comment("equal?");
     let obj1 = ctx.stack_pop(1);
     let obj2 = ctx.stack_pop(1);
 
-    mov(cb, REG0, obj1);
-    cmp(cb, REG0, obj2);
-    mov(cb, REG0, uimm_opnd(Qtrue.into()));
-    mov(cb, REG1, uimm_opnd(Qfalse.into()));
-    cmovne(cb, REG0, REG1);
+    asm.cmp(obj1, obj2);
+    let ret_opnd = asm.csel_e(Qtrue.into(), Qfalse.into());
 
     let stack_ret = ctx.stack_push(Type::UnknownImm);
-    mov(cb, stack_ret, REG0);
+    asm.mov(stack_ret, ret_opnd);
     true
 }
 
@@ -3640,7 +3638,7 @@ fn jit_rb_obj_equal( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L3638
 fn jit_rb_str_uplus(
     _jit: &mut JITState,
     ctx: &mut Context,
-    cb: &mut CodeBlock,
+    asm: &mut Assembler,
     _ocb: &mut OutlinedCb,
     _ci: *const rb_callinfo,
     _cme: *const rb_callable_method_entry_t,
@@ -3649,35 +3647,30 @@ fn jit_rb_str_uplus( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L3647
     _known_recv_class: *const VALUE,
 ) -> bool
 {
-    let recv = ctx.stack_pop(1);
-
-    add_comment(cb, "Unary plus on string");
-    mov(cb, REG0, recv);
-    mov(cb, REG1, mem_opnd(64, REG0, RUBY_OFFSET_RBASIC_FLAGS));
-    test(cb, REG1, imm_opnd(RUBY_FL_FREEZE as i64));
+    asm.comment("Unary plus on string");
+    let recv_opnd = asm.load(ctx.stack_pop(1));
+    let flags_opnd = asm.load(Opnd::mem(64, recv_opnd, RUBY_OFFSET_RBASIC_FLAGS));
+    asm.test(flags_opnd, Opnd::Imm(RUBY_FL_FREEZE as i64));
 
-    let ret_label = cb.new_label("stack_ret".to_string());
+    let ret_label = asm.new_label("stack_ret");
     // If the string isn't frozen, we just return it. It's already in REG0.
-    jz_label(cb, ret_label);
+    asm.jz(ret_label);
 
     // Str is frozen - duplicate
-    mov(cb, C_ARG_REGS[0], REG0);
-    call_ptr(cb, REG0, rb_str_dup as *const u8);
-    // Return value is in REG0, drop through and return it.
+    let ret_opnd = asm.ccall(rb_str_dup as *const u8, vec![recv_opnd]);
 
-    cb.write_label(ret_label);
+    asm.write_label(ret_label);
     // We guard for an exact-class match on the receiver of rb_cString
     let stack_ret = ctx.stack_push(Type::CString);
-    mov(cb, stack_ret, REG0);
+    asm.mov(stack_ret, ret_opnd);
 
-    cb.link_labels();
     true
 }
 
 fn jit_rb_str_bytesize(
     _jit: &mut JITState,
     ctx: &mut Context,
-    cb: &mut CodeBlock,
+    asm: &mut Assembler,
     _ocb: &mut OutlinedCb,
     _ci: *const rb_callinfo,
     _cme: *const rb_callable_method_entry_t,
@@ -3685,18 +3678,18 @@ fn jit_rb_str_bytesize( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L3678
     _argc: i32,
     _known_recv_class: *const VALUE,
 ) -> bool {
-    add_comment(cb, "String#bytesize");
+    asm.comment("String#bytesize");
 
     let recv = ctx.stack_pop(1);
-    mov(cb, C_ARG_REGS[0], recv);
-    call_ptr(cb, REG0, rb_str_bytesize as *const u8);
+    let ret_opnd = asm.ccall(rb_str_bytesize as *const u8, vec![recv]);
 
     let out_opnd = ctx.stack_push(Type::Fixnum);
-    mov(cb, out_opnd, RAX);
+    asm.mov(out_opnd, ret_opnd);
 
     true
 }
 
+/*
 // Codegen for rb_str_to_s()
 // When String#to_s is called on a String instance, the method returns self and
 // most of the overhead comes from setting up the method call. We observed that
@@ -3727,7 +3720,7 @@ fn jit_rb_str_to_s( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L3720
 fn jit_rb_str_concat(
     jit: &mut JITState,
     ctx: &mut Context,
-    cb: &mut CodeBlock,
+    asm: &mut Assembler,
     ocb: &mut OutlinedCb,
     _ci: *const rb_callinfo,
     _cme: *const rb_callable_method_entry_t,
@@ -3748,64 +3741,69 @@ fn jit_rb_str_concat( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L3741
     let side_exit = get_side_exit(jit, ocb, ctx);
 
     // Guard that the argument is of class String at runtime.
-    jit_guard_known_klass(
-        jit,
-        ctx,
-        cb,
-        ocb,
-        unsafe { rb_cString },
-        ctx.stack_opnd(0),
-        StackOpnd(0),
-        comptime_arg,
-        SEND_MAX_DEPTH,
-        side_exit,
-    );
+    let insn_opnd = StackOpnd(0);
+    let arg_opnd = asm.load(ctx.stack_opnd(0));
+    let arg_type = ctx.get_opnd_type(insn_opnd);
+
+    if arg_type != Type::CString && arg_type != Type::TString {
+        if !arg_type.is_heap() {
+            asm.comment("guard arg not immediate");
+            asm.test(REG0, imm_opnd(RUBY_IMMEDIATE_MASK as i64));
+            asm.jnz(Target::CodePtr(side_exit));
+            asm.cmp(arg_opnd, Qnil.into());
+            asm.jbe(Target::CodePtr(side_exit));
+
+            ctx.upgrade_opnd_type(insn_opnd, Type::UnknownHeap);
+        }
+        guard_object_is_string(cb, REG0, REG1, side_exit);
+        // We know this has type T_STRING, but not necessarily that it's a ::String
+        ctx.upgrade_opnd_type(insn_opnd, Type::TString);
+    }
 
     let concat_arg = ctx.stack_pop(1);
     let recv = ctx.stack_pop(1);
 
     // Test if string encodings differ. If different, use rb_str_append. If the same,
     // use rb_yjit_str_simple_append, which calls rb_str_cat.
-    add_comment(cb, "<< on strings");
+    asm.comment("<< on strings");
 
     // Both rb_str_append and rb_yjit_str_simple_append take identical args
-    mov(cb, C_ARG_REGS[0], recv);
-    mov(cb, C_ARG_REGS[1], concat_arg);
+    let ccall_args = vec![recv, concat_arg];
 
     // Take receiver's object flags XOR arg's flags. If any
     // string-encoding flags are different between the two,
     // the encodings don't match.
-    mov(cb, REG0, recv);
-    mov(cb, REG1, concat_arg);
-    mov(cb, REG0, mem_opnd(64, REG0, RUBY_OFFSET_RBASIC_FLAGS));
-    xor(cb (... truncated)

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

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