diff options
author | Takashi Kokubun <takashikkbn@gmail.com> | 2020-04-30 21:37:55 -0700 |
---|---|---|
committer | Takashi Kokubun <takashikkbn@gmail.com> | 2020-04-30 21:38:50 -0700 |
commit | e8a78d7df899291aa025e41207436a450235a4d7 (patch) | |
tree | 01e3af7befd7dcbd59b7debd4efb039fcb3dd7b3 /mjit_worker.c | |
parent | 520ac5da22c30d6db25de6dcbff9607d8a9cd870 (diff) |
Do not stop the world during JIT compaction
Running C compiler for JIT compaction inside a critical section may lock
main thread for a long time when it triggers GC. As I'm planning to
increase this duration a bit, I'd like to make sure this doesn't stop
the world.
For now, I chose to give up unloading units when it's during JIT
compaction, assuming other calls may unload them later.
Diffstat (limited to 'mjit_worker.c')
-rw-r--r-- | mjit_worker.c | 18 |
1 files changed, 10 insertions, 8 deletions
diff --git a/mjit_worker.c b/mjit_worker.c index a2f62448e1..04eac1f55f 100644 --- a/mjit_worker.c +++ b/mjit_worker.c @@ -221,9 +221,11 @@ static rb_nativethread_cond_t mjit_worker_wakeup; // A thread conditional to wake up workers if at the end of GC. static rb_nativethread_cond_t mjit_gc_wakeup; // True when GC is working. -static bool in_gc; +static bool in_gc = false; // True when JIT is working. -static bool in_jit; +static bool in_jit = false; +// True when JIT compaction is running. +static bool in_compact = false; // Set to true to stop worker. static bool stop_worker_p; // Set to true if worker is stopped. @@ -913,21 +915,21 @@ compact_all_jit_code(void) // NULL-ending for form_args o_files = alloca(sizeof(char *) * (active_units.length + 1)); o_files[active_units.length] = NULL; - CRITICAL_SECTION_START(3, "in compact_all_jit_code to keep .o files"); + CRITICAL_SECTION_START(3, "in compact_all_jit_code to guard .o files from unload_units"); list_for_each(&active_units.head, cur, unode) { o_files[i] = cur->o_file; i++; } + in_compact = true; + CRITICAL_SECTION_FINISH(3, "in compact_all_jit_code to guard .o files from unload_units"); start_time = real_ms_time(); bool success = link_o_to_so(o_files, so_file); end_time = real_ms_time(); - // TODO: Shrink this big critical section. For now, this is needed to prevent failure by missing .o files. - // This assumes that o -> so link doesn't take long time because the bottleneck, which is compiler optimization, - // is already done. But actually it takes about 500ms for 5,000 methods on my Linux machine, so it's better to - // finish this critical section before link_o_to_so by disabling unload_units. - CRITICAL_SECTION_FINISH(3, "in compact_all_jit_code to keep .o files"); + CRITICAL_SECTION_START(3, "in compact_all_jit_code to release .o files"); + in_compact = false; + CRITICAL_SECTION_FINISH(3, "in compact_all_jit_code to release .o files"); if (success) { void *handle = dlopen(so_file, RTLD_NOW); |