зеркало из https://github.com/github/ruby.git
prevent GC from mjit worker.
ALLOC_N() can causes GC. Sometimes `mjit_copy_job_handler()` can be called by mjit_worker thread which is not a Ruby thread, so we need to prevent GC in this function. This patch has some issues, but I introduce it to pass the tests.
This commit is contained in:
Родитель
82d27604ad
Коммит
7ec2359374
15
mjit.c
15
mjit.c
|
@ -54,13 +54,13 @@ mjit_copy_job_handler(void *data)
|
|||
}
|
||||
|
||||
const struct rb_iseq_constant_body *body = job->iseq->body;
|
||||
unsigned int ci_size = body->ci_size;
|
||||
const unsigned int ci_size = body->ci_size;
|
||||
if (ci_size > 0) {
|
||||
const struct rb_callcache **cc_entries = ALLOC_N(const struct rb_callcache *, ci_size);
|
||||
if (body->jit_unit == NULL) {
|
||||
create_unit(job->iseq);
|
||||
}
|
||||
body->jit_unit->cc_entries = cc_entries;
|
||||
VM_ASSERT(body->jit_unit != NULL);
|
||||
VM_ASSERT(body->jit_unit->cc_entries != NULL);
|
||||
|
||||
const struct rb_callcache **cc_entries = body->jit_unit->cc_entries;
|
||||
|
||||
for (unsigned int i=0; i<ci_size; i++) {
|
||||
cc_entries[i] = body->call_data[i].cc;
|
||||
}
|
||||
|
@ -294,6 +294,9 @@ create_unit(const rb_iseq_t *iseq)
|
|||
|
||||
unit->id = current_unit_num++;
|
||||
unit->iseq = (rb_iseq_t *)iseq;
|
||||
if (iseq->body->ci_size > 0) {
|
||||
unit->cc_entries = ALLOC_N(const struct rb_callcache *, iseq->body->ci_size);
|
||||
}
|
||||
iseq->body->jit_unit = unit;
|
||||
}
|
||||
|
||||
|
|
|
@ -1131,6 +1131,20 @@ mjit_copy_cache_from_main_thread(const rb_iseq_t *iseq, union iseq_inline_storag
|
|||
CRITICAL_SECTION_FINISH(3, "in mjit_copy_cache_from_main_thread");
|
||||
|
||||
if (UNLIKELY(mjit_opts.wait)) {
|
||||
// setup pseudo jit_unit
|
||||
if (iseq->body->jit_unit == NULL) {
|
||||
// This function is invoked in mjit worker thread, so GC should not be invoked.
|
||||
// To prevent GC with xmalloc(), use malloc() directly here.
|
||||
// However, mixing xmalloc() and malloc() will cause another issue.
|
||||
// TODO: fix this allocation code.
|
||||
iseq->body->jit_unit = (struct rb_mjit_unit *)malloc(sizeof(struct rb_mjit_unit));
|
||||
if (iseq->body->jit_unit == NULL) rb_fatal("malloc failed");
|
||||
if (iseq->body->ci_size > 0) {
|
||||
iseq->body->jit_unit->cc_entries =
|
||||
(const struct rb_callcache **)malloc(sizeof(const struct rb_callcache *) * iseq->body->ci_size);
|
||||
if (iseq->body->jit_unit->cc_entries == NULL) rb_fatal("malloc failed");
|
||||
}
|
||||
}
|
||||
mjit_copy_job_handler((void *)job);
|
||||
}
|
||||
else if (rb_workqueue_register(0, mjit_copy_job_handler, (void *)job)) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче