ruby-changes:74439
From: Takashi <ko1@a...>
Date: Fri, 11 Nov 2022 07:13:10 +0900 (JST)
Subject: [ruby-changes:74439] 2b8191bdad (master): YJIT: Invalidate JIT code only for ISEQ_TRACE_EVENTS (#6695)
https://git.ruby-lang.org/ruby.git/commit/?id=2b8191bdad From 2b8191bdad7545b71f270d2b25a34cd2b3afa02f Mon Sep 17 00:00:00 2001 From: Takashi Kokubun <takashikkbn@g...> Date: Thu, 10 Nov 2022 14:12:38 -0800 Subject: YJIT: Invalidate JIT code only for ISEQ_TRACE_EVENTS (#6695) --- test/ruby/test_yjit.rb | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ vm_trace.c | 10 ++++++---- 2 files changed, 54 insertions(+), 4 deletions(-) diff --git a/test/ruby/test_yjit.rb b/test/ruby/test_yjit.rb index 1a564889af..fab8768a7e 100644 --- a/test/ruby/test_yjit.rb +++ b/test/ruby/test_yjit.rb @@ -918,6 +918,54 @@ class TestYJIT < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_yjit.rb#L918 RUBY end + def test_trace_script_compiled # not ISEQ_TRACE_EVENTS + assert_compiles(<<~'RUBY', exits: :any, result: :ok) + @eval_counter = 0 + def eval_script + eval('@eval_counter += 1') + end + + @trace_counter = 0 + trace = TracePoint.new(:script_compiled) do |t| + @trace_counter += 1 + end + + eval_script # JIT without TracePoint + trace.enable + eval_script # call with TracePoint + trace.disable + + return :"eval_#{@eval_counter}" if @eval_counter != 2 + return :"trace_#{@trace_counter}" if @trace_counter != 1 + + :ok + RUBY + end + + def test_trace_b_call # ISEQ_TRACE_EVENTS + assert_compiles(<<~'RUBY', exits: :any, result: :ok) + @call_counter = 0 + def block_call + 1.times { @call_counter += 1 } + end + + @trace_counter = 0 + trace = TracePoint.new(:b_call) do |t| + @trace_counter += 1 + end + + block_call # JIT without TracePoint + trace.enable + block_call # call with TracePoint + trace.disable + + return :"call_#{@call_counter}" if @call_counter != 2 + return :"trace_#{@trace_counter}" if @trace_counter != 1 + + :ok + RUBY + end + private def code_gc_helpers diff --git a/vm_trace.c b/vm_trace.c index 93a8c1a4ed..caed71e96f 100644 --- a/vm_trace.c +++ b/vm_trace.c @@ -87,8 +87,9 @@ update_global_event_hook(rb_event_flag_t prev_events, rb_event_flag_t new_events https://github.com/ruby/ruby/blob/trunk/vm_trace.c#L87 { rb_event_flag_t new_iseq_events = new_events & ISEQ_TRACE_EVENTS; rb_event_flag_t enabled_iseq_events = ruby_vm_event_enabled_global_flags & ISEQ_TRACE_EVENTS; + bool trace_iseq_p = new_iseq_events & ~enabled_iseq_events; - if (new_iseq_events & ~enabled_iseq_events) { + if (trace_iseq_p) { // :class events are triggered only in ISEQ_TYPE_CLASS, but mjit_target_iseq_p ignores such iseqs. // Thus we don't need to cancel JIT-ed code for :class events. if (new_iseq_events != RUBY_EVENT_CLASS) { @@ -111,10 +112,11 @@ update_global_event_hook(rb_event_flag_t prev_events, rb_event_flag_t new_events https://github.com/ruby/ruby/blob/trunk/vm_trace.c#L112 ruby_vm_event_enabled_global_flags |= new_events; rb_objspace_set_event_hook(new_events); - if (new_events & RUBY_EVENT_TRACEPOINT_ALL) { - // Invalidate all code if listening for any TracePoint event. + if (trace_iseq_p) { + // Invalidate all code when ISEQs are modified to use trace_* insns above. // Internal events fire inside C routines so don't need special handling. - // Do this last so other ractors see updated vm events when they wake up. + // Do this after event flags updates so other ractors see updated vm events + // when they wake up. rb_yjit_tracing_invalidate_all(); } } -- cgit v1.2.3 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/