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

ruby-changes:68771

From: Maxime <ko1@a...>
Date: Thu, 21 Oct 2021 08:13:30 +0900 (JST)
Subject: [ruby-changes:68771] a7c1bc61d2 (master): Add missing VM_CHECK_INTS() for correctness

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

From a7c1bc61d2becac74743d8ab6efd6d5649b92311 Mon Sep 17 00:00:00 2001
From: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@s...>
Date: Thu, 11 Feb 2021 13:59:59 -0500
Subject: Add missing VM_CHECK_INTS() for correctness

---
 ujit_codegen.c | 64 ++++++++++++++++++++++++++++------------------------------
 1 file changed, 31 insertions(+), 33 deletions(-)

diff --git a/ujit_codegen.c b/ujit_codegen.c
index 452849d53c..90c1af21c4 100644
--- a/ujit_codegen.c
+++ b/ujit_codegen.c
@@ -149,6 +149,20 @@ ujit_entry_prologue(void) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L149
     return code_ptr;
 }
 
+/*
+Generate code to check for interrupts and take a side-exit
+*/
+static void
+ujit_check_ints(codeblock_t* cb, uint8_t* side_exit)
+{
+    // Check for interrupts
+    // see RUBY_VM_CHECK_INTS(ec) macro
+    mov(cb, REG0_32, member_opnd(REG_EC, rb_execution_context_t, interrupt_mask));
+    not(cb, REG0_32);
+    test(cb, member_opnd(REG_EC, rb_execution_context_t, interrupt_flag), REG0_32);
+    jnz_ptr(cb, side_exit);
+}
+
 /*
 Compile a sequence of bytecode instructions for a given basic block version
 */
@@ -894,14 +908,10 @@ gen_branchif_branch(codeblock_t* cb, uint8_t* target0, uint8_t* target1, uint8_t https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L908
 static bool
 gen_branchif(jitstate_t* jit, ctx_t* ctx)
 {
-    // TODO: we need to eventually do an interrupt check
-    // The check is supposed to happen only when we jump to the jump target block
-    //
-    // How can we do this while keeping the check logic out of line?
-    // Can we push the VM_CHECK_INTS() into the next block or the stub?
-    // Maybe into a transition edge block
-    //
-	// RUBY_VM_CHECK_INTS(ec);
+    // FIXME: eventually, put VM_CHECK_INTS() only on backward branch targets
+    // Check for interrupts
+    uint8_t* side_exit = ujit_side_exit(jit, ctx);
+    ujit_check_ints(cb, side_exit);
 
     // Test if any bit (outside of the Qnil bit) is on
     // RUBY_Qfalse  /* ...0000 0000 */
@@ -951,14 +961,10 @@ gen_branchunless_branch(codeblock_t* cb, uint8_t* target0, uint8_t* target1, uin https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L961
 static bool
 gen_branchunless(jitstate_t* jit, ctx_t* ctx)
 {
-    // TODO: we need to eventually do an interrupt check
-    // The check is supposed to happen only when we jump to the jump target block
-    //
-    // How can we do this while keeping the check logic out of line?
-    // Can we push the VM_CHECK_INTS() into the next block or the stub?
-    // Maybe into a transition edge block
-    //
-	// RUBY_VM_CHECK_INTS(ec);
+    // FIXME: eventually, put VM_CHECK_INTS() only on backward branch targets
+    // Check for interrupts
+    uint8_t* side_exit = ujit_side_exit(jit, ctx);
+    ujit_check_ints(cb, side_exit);
 
     // Test if any bit (outside of the Qnil bit) is on
     // RUBY_Qfalse  /* ...0000 0000 */
@@ -988,15 +994,15 @@ gen_branchunless(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L994
 static bool
 gen_jump(jitstate_t* jit, ctx_t* ctx)
 {
+    // FIXME: eventually, put VM_CHECK_INTS() only on backward branch targets
+    // Check for interrupts
+    uint8_t* side_exit = ujit_side_exit(jit, ctx);
+    ujit_check_ints(cb, side_exit);
+
     // Get the branch target instruction offsets
     uint32_t jump_idx = jit_next_idx(jit) + (int32_t)jit_get_arg(jit, 0);
     blockid_t jump_block = { jit->iseq, jump_idx };
 
-    //
-    // TODO:
-	// RUBY_VM_CHECK_INTS(ec);
-    //
-
     // Generate the jump instruction
     gen_direct_jump(
         ctx,
@@ -1027,11 +1033,7 @@ gen_opt_swb_cfunc(jitstate_t* jit, ctx_t* ctx, struct rb_call_data * cd, const r https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L1033
     uint8_t* side_exit = ujit_side_exit(jit, ctx);
 
     // Check for interrupts
-    // RUBY_VM_CHECK_INTS(ec)
-    mov(cb, REG0_32, member_opnd(REG_EC, rb_execution_context_t, interrupt_mask));
-    not(cb, REG0_32);
-    test(cb, member_opnd(REG_EC, rb_execution_context_t, interrupt_flag), REG0_32);
-    jnz_ptr(cb, side_exit);
+    ujit_check_ints(cb, side_exit);
 
     // Points to the receiver operand on the stack
     x86opnd_t recv = ctx_stack_opnd(ctx, argc);
@@ -1261,11 +1263,7 @@ 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#L1263
     uint8_t* side_exit = ujit_side_exit(jit, ctx);
 
     // Check for interrupts
-    // RUBY_VM_CHECK_INTS(ec)
-    mov(cb, REG0_32, member_opnd(REG_EC, rb_execution_context_t, interrupt_mask));
-    not(cb, REG0_32);
-    test(cb, member_opnd(REG_EC, rb_execution_context_t, interrupt_flag), REG0_32);
-    jnz_ptr(cb, side_exit);
+    ujit_check_ints(cb, side_exit);
 
     // Points to the receiver operand on the stack
     x86opnd_t recv = ctx_stack_opnd(ctx, argc);
@@ -1478,8 +1476,8 @@ gen_leave(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L1476
     test(cb, flags_opnd, imm_opnd(VM_FRAME_FLAG_FINISH));
     jnz_ptr(cb, side_exit);
 
-    // TODO:
-    // RUBY_VM_CHECK_INTS(ec);
+    // Check for interrupts
+    ujit_check_ints(cb, side_exit);
 
     // Load the return value
     mov(cb, REG0, ctx_stack_pop(ctx, 1));
-- 
cgit v1.2.1


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

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