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/