ruby-changes:64404
From: Takashi <ko1@a...>
Date: Mon, 21 Dec 2020 16:18:39 +0900 (JST)
Subject: [ruby-changes:64404] f26f905b28 (master): Mark an ISeq being JIT-ed
https://git.ruby-lang.org/ruby.git/commit/?id=f26f905b28 From f26f905b28c5531c78445ac15d74ca1265eff5c5 Mon Sep 17 00:00:00 2001 From: Takashi Kokubun <takashikkbn@g...> Date: Sun, 20 Dec 2020 23:17:28 -0800 Subject: Mark an ISeq being JIT-ed This is to avoid SEGV on a CC reference in a normal compilation https://github.com/ruby/ruby/runs/1586578023 diff --git a/mjit.c b/mjit.c index 1b0fc68..d87961d 100644 --- a/mjit.c +++ b/mjit.c @@ -935,8 +935,13 @@ mjit_finish(bool close_handle_p) https://github.com/ruby/ruby/blob/trunk/mjit.c#L935 verbose(1, "Successful MJIT finish"); } -// Called by rb_vm_mark() to mark active_units so that we do not GC ISeq which -// may still be referred to by mjit_recompile() or compact_all_jit_code(). +// Called by rb_vm_mark(). +// +// Mark an ISeq being compiled to prevent its CCs from being GC-ed, which +// an MJIT worker may concurrently see. +// +// Also mark active_units so that we do not GC ISeq which may still be +// referred to by mjit_recompile() or compact_all_jit_code(). void mjit_mark(void) { @@ -944,6 +949,9 @@ mjit_mark(void) https://github.com/ruby/ruby/blob/trunk/mjit.c#L949 return; RUBY_MARK_ENTER("mjit"); + if (compiling_iseq != NULL) + rb_gc_mark((VALUE)compiling_iseq); + // We need to release a lock when calling rb_gc_mark to avoid doubly acquiring // a lock by by mjit_gc_start_hook inside rb_gc_mark. // diff --git a/mjit_worker.c b/mjit_worker.c index 2096ea7..ba90cca 100644 --- a/mjit_worker.c +++ b/mjit_worker.c @@ -1103,6 +1103,8 @@ compile_prelude(FILE *f) https://github.com/ruby/ruby/blob/trunk/mjit_worker.c#L1103 #endif } +static rb_iseq_t *compiling_iseq = NULL; + // Compile ISeq in UNIT and return function pointer of JIT-ed code. // It may return NOT_COMPILED_JIT_ISEQ_FUNC if something went wrong. static mjit_func_t @@ -1136,6 +1138,8 @@ convert_unit_to_func(struct rb_mjit_unit *unit) https://github.com/ruby/ruby/blob/trunk/mjit_worker.c#L1138 } // We need to check again here because we could've waited on GC above in_jit = (unit->iseq != NULL); + if (in_jit) + compiling_iseq = unit->iseq; CRITICAL_SECTION_FINISH(3, "before mjit_compile to wait GC finish"); if (!in_jit) { fclose(f); @@ -1160,6 +1164,7 @@ convert_unit_to_func(struct rb_mjit_unit *unit) https://github.com/ruby/ruby/blob/trunk/mjit_worker.c#L1164 // release blocking mjit_gc_start_hook CRITICAL_SECTION_START(3, "after mjit_compile to wakeup client for GC"); + compiling_iseq = NULL; in_jit = false; verbose(3, "Sending wakeup signal to client in a mjit-worker for GC"); rb_native_cond_signal(&mjit_client_wakeup); -- cgit v0.10.2 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/