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

ruby-changes:68758

From: Maxime <ko1@a...>
Date: Thu, 21 Oct 2021 08:13:27 +0900 (JST)
Subject: [ruby-changes:68758] 75b623776b (master): Fix jit_return bug, return address on wrong frame

https://git.ruby-lang.org/ruby.git/commit/?id=75b623776b

From 75b623776b920b0711c0c458997467d19a32ef8e Mon Sep 17 00:00:00 2001
From: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@s...>
Date: Wed, 10 Feb 2021 15:51:07 -0500
Subject: Fix jit_return bug, return address on wrong frame

---
 ujit_codegen.c | 72 ++++++++++++++++++++++++++++++++++++++--------------------
 1 file changed, 48 insertions(+), 24 deletions(-)

diff --git a/ujit_codegen.c b/ujit_codegen.c
index 51ae1bc4ce..33cf1b84d8 100644
--- a/ujit_codegen.c
+++ b/ujit_codegen.c
@@ -1278,26 +1278,6 @@ gen_opt_swb_iseq(jitstate_t* jit, ctx_t* ctx, struct rb_call_data * cd, const rb https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L1278
     mov(cb, REG0, const_ptr_opnd(jit->pc + insn_len(BIN(opt_send_without_block))));
     mov(cb, mem_opnd(64, REG_CFP, offsetof(rb_control_frame_t, pc)), REG0);
 
-    // Stub so we can return to JITted code
-    blockid_t return_block = { jit->iseq, jit_next_insn_idx(jit) };
-
-    // Pop arguments and receiver in return context, push the return value
-    // After the return, the JIT and interpreter SP will match up
-    ctx_t return_ctx = *ctx;
-    ctx_stack_pop(&return_ctx, argc + 1);
-    ctx_stack_push(&return_ctx, T_NONE);
-    return_ctx.sp_offset = 0;
-
-    // Write the JIT return address on the current frame
-    gen_branch(
-        ctx,
-        return_block,
-        &return_ctx,
-        return_block,
-        &return_ctx,
-        gen_return_branch
-    );
-
     // Stack overflow check
     // #define CHECK_VM_STACK_OVERFLOW0(cfp, sp, margin)
     lea(cb, REG0, ctx_sp_opnd(ctx, sizeof(VALUE) * (num_locals + iseq->body->stack_max) + sizeof(rb_control_frame_t)));
@@ -1332,6 +1312,15 @@ gen_opt_swb_iseq(jitstate_t* jit, ctx_t* ctx, struct rb_call_data * cd, const rb https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L1312
     sub(cb, REG_CFP, imm_opnd(sizeof(rb_control_frame_t)));
     mov(cb, member_opnd(REG_EC, rb_execution_context_t, cfp), REG_CFP);
 
+
+
+
+
+    // FIXME
+    // FIXME: we could use REG_CFP here instead of REG1???
+    // FIXME: no need to reload from CFP
+
+
     // Setup the new frame
     // *cfp = (const struct rb_control_frame_struct) {
     //    .pc         = pc,
@@ -1355,6 +1344,33 @@ gen_opt_swb_iseq(jitstate_t* jit, ctx_t* ctx, struct rb_call_data * cd, const rb https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L1344
     mov(cb, REG0, const_ptr_opnd(start_pc));
     mov(cb, member_opnd(REG1, rb_control_frame_t, pc), REG0);
 
+
+
+
+
+
+    // Stub so we can return to JITted code
+    blockid_t return_block = { jit->iseq, jit_next_insn_idx(jit) };
+
+    // Pop arguments and receiver in return context, push the return value
+    // After the return, the JIT and interpreter SP will match up
+    ctx_t return_ctx = *ctx;
+    ctx_stack_pop(&return_ctx, argc + 1);
+    ctx_stack_push(&return_ctx, T_NONE);
+    return_ctx.sp_offset = 0;
+
+    // Write the JIT return address on the callee frame
+    gen_branch(
+        ctx,
+        return_block,
+        &return_ctx,
+        return_block,
+        &return_ctx,
+        gen_return_branch
+    );
+
+
+
     //print_str(cb, "calling Ruby func:");
     //print_str(cb, rb_id2name(vm_ci_mid(cd->ci)));
 
@@ -1456,9 +1472,19 @@ gen_leave(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L1472
     // TODO:
     // RUBY_VM_CHECK_INTS(ec);
 
+
+
+    // FIXME: not needed for interpreter
     // Load the return value
     mov(cb, REG0, ctx_stack_pop(ctx, 1));
 
+
+
+    // Load the JIT return address
+    mov(cb, REG1, member_opnd(REG_CFP, rb_control_frame_t, jit_return));
+
+
+
     // Pop the current frame (ec->cfp++)
     // Note: the return PC is already in the previous CFP
     add(cb, REG_CFP, imm_opnd(sizeof(rb_control_frame_t)));
@@ -1476,16 +1502,14 @@ gen_leave(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L1502
 
 
     
-    // Load the JIT return address
-    mov(cb, REG0, member_opnd(REG_CFP, rb_control_frame_t, jit_return));
 
     // If the return address is NULL, fall back to the interpreter
     int FALLBACK_LABEL = cb_new_label(cb, "FALLBACK");
-    cmp(cb, REG0, imm_opnd(0));
+    cmp(cb, REG1, imm_opnd(0));
     jz(cb, FALLBACK_LABEL);
 
     // Jump to the JIT return address
-    jmp_rm(cb, REG0);
+    jmp_rm(cb, REG1);
 
     // Fall back to the interpreter
     cb_write_label(cb, FALLBACK_LABEL);
-- 
cgit v1.2.1


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

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