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

ruby-changes:69032

From: John <ko1@a...>
Date: Thu, 21 Oct 2021 08:20:36 +0900 (JST)
Subject: [ruby-changes:69032] 83c7f27ade (master): Add invokesuper

https://git.ruby-lang.org/ruby.git/commit/?id=83c7f27ade

From 83c7f27adec684d16fb01f3b098d694ab15e9295 Mon Sep 17 00:00:00 2001
From: John Hawthorn <john@h...>
Date: Wed, 9 Jun 2021 10:22:09 -0700
Subject: Add invokesuper

---
 yjit_codegen.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 85 insertions(+)

diff --git a/yjit_codegen.c b/yjit_codegen.c
index 4870911404..01fe83d786 100644
--- a/yjit_codegen.c
+++ b/yjit_codegen.c
@@ -2908,6 +2908,90 @@ gen_send(jitstate_t *jit, ctx_t *ctx) https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L2908
     return gen_send_general(jit, ctx, cd, block);
 }
 
+static codegen_status_t
+gen_invokesuper(jitstate_t *jit, ctx_t *ctx)
+{
+    struct rb_call_data *cd = (struct rb_call_data *)jit_get_arg(jit, 0);
+    rb_iseq_t *block = (rb_iseq_t *)jit_get_arg(jit, 1);
+
+    // Defer compilation so we can specialize on class of receiver
+    if (!jit_at_current_insn(jit)) {
+        defer_compilation(jit->block, jit->insn_idx, ctx);
+        return YJIT_END_BLOCK;
+    }
+
+    const rb_callable_method_entry_t *me = rb_vm_frame_method_entry(jit->ec->cfp);
+    if (!me) {
+        return YJIT_CANT_COMPILE;
+    } else if (me->def->type == VM_METHOD_TYPE_BMETHOD) {
+        return YJIT_CANT_COMPILE;
+    }
+
+    VALUE current_defined_class = me->defined_class;
+    ID mid = me->def->original_id;
+    VALUE comptime_superclass = RCLASS_SUPER(RCLASS_ORIGIN(current_defined_class));
+
+    const struct rb_callinfo *ci = cd->ci;
+    int32_t argc = (int32_t)vm_ci_argc(ci);
+
+    // Don't JIT calls that aren't simple
+    // Note, not using VM_CALL_ARGS_SIMPLE because sometimes we pass a block.
+    if ((vm_ci_flag(ci) & (VM_CALL_KW_SPLAT | VM_CALL_KWARG | VM_CALL_ARGS_SPLAT | VM_CALL_ARGS_BLOCKARG)) != 0) {
+        GEN_COUNTER_INC(cb, send_callsite_not_simple);
+        return YJIT_CANT_COMPILE;
+    }
+
+    VALUE comptime_recv = jit_peek_at_stack(jit, ctx, argc);
+    VALUE comptime_recv_klass = CLASS_OF(comptime_recv);
+
+    if (!rb_obj_is_kind_of(comptime_recv, current_defined_class)) {
+        return YJIT_CANT_COMPILE;
+    }
+
+    // Do method lookup
+    const rb_callable_method_entry_t *cme = rb_callable_method_entry(comptime_superclass, mid);
+
+    if (!cme) {
+        return YJIT_CANT_COMPILE;
+    }
+
+    switch (cme->def->type) {
+        case VM_METHOD_TYPE_ISEQ:
+        case VM_METHOD_TYPE_CFUNC:
+            break;
+        default:
+            // others unimplemented
+            return YJIT_CANT_COMPILE;
+    }
+
+    // Guard that the receiver has the same class as the one from compile time
+    uint8_t *side_exit = yjit_side_exit(jit, ctx);
+
+    // Points to the receiver operand on the stack
+    x86opnd_t recv = ctx_stack_opnd(ctx, argc);
+    insn_opnd_t recv_opnd = OPND_STACK(argc);
+    mov(cb, REG0, recv);
+    if (!jit_guard_known_klass(jit, ctx, comptime_recv_klass, recv_opnd, SEND_MAX_DEPTH, side_exit)) {
+        return YJIT_CANT_COMPILE;
+    }
+
+    assume_method_lookup_stable(comptime_recv_klass, cme, jit->block);
+
+    // Method calls may corrupt types
+    ctx_clear_local_types(ctx);
+
+    switch (cme->def->type) {
+        case VM_METHOD_TYPE_ISEQ:
+            return gen_send_iseq(jit, ctx, ci, cme, block, argc);
+        case VM_METHOD_TYPE_CFUNC:
+            return gen_send_cfunc(jit, ctx, ci, cme, block, argc);
+        default:
+            break;
+    }
+
+    RUBY_ASSERT(false);
+}
+
 static codegen_status_t
 gen_leave(jitstate_t* jit, ctx_t* ctx)
 {
@@ -3115,5 +3199,6 @@ yjit_init_codegen(void) https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L3199
     yjit_reg_op(BIN(getblockparamproxy), gen_getblockparamproxy);
     yjit_reg_op(BIN(opt_send_without_block), gen_opt_send_without_block);
     yjit_reg_op(BIN(send), gen_send);
+    yjit_reg_op(BIN(invokesuper), gen_invokesuper);
     yjit_reg_op(BIN(leave), gen_leave);
 }
-- 
cgit v1.2.1


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

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