summaryrefslogtreecommitdiff
path: root/mjit_worker.c
diff options
context:
space:
mode:
authorKoichi Sasada <ko1@atdot.net>2020-02-25 11:03:17 +0900
committerKoichi Sasada <ko1@atdot.net>2020-02-25 12:57:10 +0900
commit7ec23593746c8ccabd6c005cc34dde77d564c6c9 (patch)
treeb1979d603edb1808217db5d2b632a9ed24be41b3 /mjit_worker.c
parent82d27604adba94e147c1e848f80329a8286bde5c (diff)
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.
Diffstat (limited to 'mjit_worker.c')
-rw-r--r--mjit_worker.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/mjit_worker.c b/mjit_worker.c
index 8541184..d074b7b 100644
--- a/mjit_worker.c
+++ b/mjit_worker.c
@@ -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)) {