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

ruby-changes:69103

From: Alan <ko1@a...>
Date: Thu, 21 Oct 2021 08:20:50 +0900 (JST)
Subject: [ruby-changes:69103] f4f940e5a6 (master): Save PC and SP before accessing globals

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

From f4f940e5a63e542a59fc7510332efb38ccafc10f Mon Sep 17 00:00:00 2001
From: Alan Wu <XrXr@u...>
Date: Thu, 29 Jul 2021 12:41:59 -0400
Subject: Save PC and SP before accessing globals

These instructions are marked as not leaf in insns.def, which indicate
that they could raise exceptions and/or call Ruby methods.
---
 bootstraptest/test_yjit.rb | 32 ++++++++++++++++++++++++++++++++
 yjit_codegen.c             | 13 +++++++++++--
 2 files changed, 43 insertions(+), 2 deletions(-)

diff --git a/bootstraptest/test_yjit.rb b/bootstraptest/test_yjit.rb
index 1a683c1c41..a164b7a413 100644
--- a/bootstraptest/test_yjit.rb
+++ b/bootstraptest/test_yjit.rb
@@ -7,6 +7,19 @@ assert_equal 'string', %q{ https://github.com/ruby/ruby/blob/trunk/bootstraptest/test_yjit.rb#L7
   foo
 }
 
+# Check that exceptions work when setting global variables
+assert_equal 'rescued', %q{
+  def set_var
+    $var = 100
+  rescue
+    :rescued
+  end
+
+  set_var
+  trace_var(:$var) { raise }
+  set_var
+}
+
 # Check that global variables work
 assert_equal 'string', %q{
   $foo = "string"
@@ -18,6 +31,25 @@ assert_equal 'string', %q{ https://github.com/ruby/ruby/blob/trunk/bootstraptest/test_yjit.rb#L31
   foo
 }
 
+# Check that exceptions work when getting global variable
+assert_equal 'rescued', %q{
+  module Warning
+    def warn(message)
+      raise
+    end
+  end
+
+  def get_var
+    $=
+  rescue
+    :rescued
+  end
+
+  $VERBOSE = true
+  get_var
+  get_var
+}
+
 # Check that global tracepoints work
 assert_equal 'true', %q{
   def foo
diff --git a/yjit_codegen.c b/yjit_codegen.c
index 3658d208fa..5d05cce365 100644
--- a/yjit_codegen.c
+++ b/yjit_codegen.c
@@ -149,7 +149,7 @@ jit_type_of_value(VALUE val) https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L149
 
 // Save the incremented PC on the CFP
 // This is necessary when calleees can raise or allocate
-void
+static void
 jit_save_pc(jitstate_t* jit, x86opnd_t scratch_reg)
 {
     mov(cb, scratch_reg, const_ptr_opnd(jit->pc + insn_len(jit->opcode)));
@@ -160,7 +160,7 @@ jit_save_pc(jitstate_t* jit, x86opnd_t scratch_reg) https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L160
 // This realigns the interpreter SP with the JIT SP
 // Note: this will change the current value of REG_SP,
 //       which could invalidate memory operands
-void
+static void
 jit_save_sp(jitstate_t* jit, ctx_t* ctx)
 {
     if (ctx->sp_offset != 0) {
@@ -3431,6 +3431,10 @@ gen_getglobal(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L3431
 {
     ID gid = jit_get_arg(jit, 0);
 
+    // Save the PC and SP because we might make a Ruby call for warning
+    jit_save_pc(jit, REG0);
+    jit_save_sp(jit, ctx);
+
     // Save YJIT registers
     yjit_save_regs(cb);
 
@@ -3452,6 +3456,11 @@ gen_setglobal(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L3456
 {
     ID gid = jit_get_arg(jit, 0);
 
+    // Save the PC and SP because we might make a Ruby call for
+    // Kernel#set_trace_var
+    jit_save_pc(jit, REG0);
+    jit_save_sp(jit, ctx);
+
     // Save YJIT registers
     yjit_save_regs(cb);
 
-- 
cgit v1.2.1


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

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