зеркало из https://github.com/github/ruby.git
Do not doubly hold an MJIT lock
This is a follow-up of 86c262541a
.
CRITICAL_SECTION_START/FINISH are not needed when it's called from an
MJIT worker.
Also, ZALLOC needs to be calloc because ZALLOC may trigger GC, which an
MJIT worker must not do.
This commit is contained in:
Родитель
9f3888d6a3
Коммит
7e14762159
23
mjit.c
23
mjit.c
|
@ -230,13 +230,13 @@ finish_conts(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create unit for `iseq`.
|
// Create unit for `iseq`. This function may be called from an MJIT worker.
|
||||||
static void
|
static void
|
||||||
create_unit(const rb_iseq_t *iseq)
|
create_unit(const rb_iseq_t *iseq)
|
||||||
{
|
{
|
||||||
struct rb_mjit_unit *unit;
|
struct rb_mjit_unit *unit;
|
||||||
|
|
||||||
unit = ZALLOC(struct rb_mjit_unit);
|
unit = calloc(1, sizeof(struct rb_mjit_unit));
|
||||||
if (unit == NULL)
|
if (unit == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -253,8 +253,9 @@ mjit_target_iseq_p(struct rb_iseq_constant_body *body)
|
||||||
&& !body->builtin_inline_p;
|
&& !body->builtin_inline_p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is called from an MJIT worker when worker_p is true.
|
||||||
static void
|
static void
|
||||||
mjit_add_iseq_to_process(const rb_iseq_t *iseq, const struct rb_mjit_compile_info *compile_info)
|
mjit_add_iseq_to_process(const rb_iseq_t *iseq, const struct rb_mjit_compile_info *compile_info, bool worker_p)
|
||||||
{
|
{
|
||||||
if (!mjit_enabled || pch_status == PCH_FAILED)
|
if (!mjit_enabled || pch_status == PCH_FAILED)
|
||||||
return;
|
return;
|
||||||
|
@ -273,14 +274,18 @@ mjit_add_iseq_to_process(const rb_iseq_t *iseq, const struct rb_mjit_compile_inf
|
||||||
if (compile_info != NULL)
|
if (compile_info != NULL)
|
||||||
iseq->body->jit_unit->compile_info = *compile_info;
|
iseq->body->jit_unit->compile_info = *compile_info;
|
||||||
|
|
||||||
CRITICAL_SECTION_START(3, "in add_iseq_to_process");
|
if (!worker_p) {
|
||||||
|
CRITICAL_SECTION_START(3, "in add_iseq_to_process");
|
||||||
|
}
|
||||||
add_to_list(iseq->body->jit_unit, &unit_queue);
|
add_to_list(iseq->body->jit_unit, &unit_queue);
|
||||||
if (active_units.length >= mjit_opts.max_cache_size) {
|
if (active_units.length >= mjit_opts.max_cache_size) {
|
||||||
unload_requests++;
|
unload_requests++;
|
||||||
}
|
}
|
||||||
verbose(3, "Sending wakeup signal to workers in mjit_add_iseq_to_process");
|
if (!worker_p) {
|
||||||
rb_native_cond_broadcast(&mjit_worker_wakeup);
|
verbose(3, "Sending wakeup signal to workers in mjit_add_iseq_to_process");
|
||||||
CRITICAL_SECTION_FINISH(3, "in add_iseq_to_process");
|
rb_native_cond_broadcast(&mjit_worker_wakeup);
|
||||||
|
CRITICAL_SECTION_FINISH(3, "in add_iseq_to_process");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add ISEQ to be JITed in parallel with the current thread.
|
// Add ISEQ to be JITed in parallel with the current thread.
|
||||||
|
@ -288,7 +293,7 @@ mjit_add_iseq_to_process(const rb_iseq_t *iseq, const struct rb_mjit_compile_inf
|
||||||
void
|
void
|
||||||
rb_mjit_add_iseq_to_process(const rb_iseq_t *iseq)
|
rb_mjit_add_iseq_to_process(const rb_iseq_t *iseq)
|
||||||
{
|
{
|
||||||
mjit_add_iseq_to_process(iseq, NULL);
|
mjit_add_iseq_to_process(iseq, NULL, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// For this timeout seconds, --jit-wait will wait for JIT compilation finish.
|
// For this timeout seconds, --jit-wait will wait for JIT compilation finish.
|
||||||
|
@ -353,7 +358,7 @@ mjit_recompile(const rb_iseq_t *iseq)
|
||||||
if (UNLIKELY(mjit_opts.wait)) {
|
if (UNLIKELY(mjit_opts.wait)) {
|
||||||
remove_from_list(iseq->body->jit_unit, &active_units);
|
remove_from_list(iseq->body->jit_unit, &active_units);
|
||||||
add_to_list(iseq->body->jit_unit, &stale_units);
|
add_to_list(iseq->body->jit_unit, &stale_units);
|
||||||
mjit_add_iseq_to_process(iseq, &iseq->body->jit_unit->compile_info);
|
mjit_add_iseq_to_process(iseq, &iseq->body->jit_unit->compile_info, false);
|
||||||
mjit_wait(iseq->body);
|
mjit_wait(iseq->body);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -1396,7 +1396,7 @@ unload_units(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mjit_add_iseq_to_process(const rb_iseq_t *iseq, const struct rb_mjit_compile_info *compile_info);
|
static void mjit_add_iseq_to_process(const rb_iseq_t *iseq, const struct rb_mjit_compile_info *compile_info, bool worker_p);
|
||||||
|
|
||||||
// The function implementing a worker. It is executed in a separate
|
// The function implementing a worker. It is executed in a separate
|
||||||
// thread by rb_thread_create_mjit_thread. It compiles precompiled header
|
// thread by rb_thread_create_mjit_thread. It compiles precompiled header
|
||||||
|
@ -1448,7 +1448,7 @@ mjit_worker(void)
|
||||||
remove_from_list(unit, &active_units);
|
remove_from_list(unit, &active_units);
|
||||||
add_to_list(unit, &stale_units);
|
add_to_list(unit, &stale_units);
|
||||||
// Lazily put it to unit_queue as well to avoid race conditions on jit_unit with mjit_compile.
|
// Lazily put it to unit_queue as well to avoid race conditions on jit_unit with mjit_compile.
|
||||||
mjit_add_iseq_to_process(unit->iseq, &unit->iseq->body->jit_unit->compile_info);
|
mjit_add_iseq_to_process(unit->iseq, &unit->iseq->body->jit_unit->compile_info, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче