diff options
author | k0kubun <k0kubun@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2018-11-27 12:00:51 +0000 |
---|---|---|
committer | k0kubun <k0kubun@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2018-11-27 12:00:51 +0000 |
commit | 86cb3d319f8a9b39deaad9acc6863e6c5c854eac (patch) | |
tree | 409ede741f22fd1ad614f7e5ff8520ad2d4a48a0 /mjit.c | |
parent | c3fe307808b4343dcb21c1451e2bfc7382fdceb5 (diff) |
mjit_worker.c: promote mjit_copy_job from function
-local variable to global variable.
Consider this case:
1. MJIT worker: dequeue ISeq (stop_worker_p was still FALSE)
2. Ruby thread: call Kernel#exec, which calls mjit_finish(FALSE),
sets `stop_worker_p = TRUE`, and fires RUBY_VM_CHECK_INTS() once
3. MJIT worker: register copy job, but found stop_worker_p is TRUE.
set `worker_stopped = TRUE` and the thread stops.
4. Function-local job variable expires by the thread stop (this is eliminated by this commit)
5. Ruby thread: find `worker_stopped` becamse TRUE, start Kernel#exec.
Kernel#exec fails but exception is rescued.
6. Ruby thread: call RUBY_VM_CHECK_INTS. copy job is dispatched but job variable
is already expired.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66035 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'mjit.c')
-rw-r--r-- | mjit.c | 12 |
1 files changed, 6 insertions, 6 deletions
@@ -24,17 +24,17 @@ static void mjit_copy_job_handler(void *data) { - struct mjit_copy_job *job = data; + mjit_copy_job_t *job = data; const struct rb_iseq_constant_body *body; - if (stop_worker_p) { - /* `copy_cache_from_main_thread()` stops to wait for this job. Then job data which is - allocated by `alloca()` could be expired and we might not be able to access that. - Also this should be checked before CRITICAL_SECTION_START to ensure that mutex is alive. */ + if (stop_worker_p) { /* check if mutex is still alive, before calling CRITICAL_SECTION_START. */ return; } CRITICAL_SECTION_START(3, "in mjit_copy_job_handler"); - /* Make sure that this job is never executed while job is being modified or ISeq is GC-ed */ + /* Make sure that this job is never executed when: + 1. job is being modified + 2. alloca memory inside job is expired + 3. ISeq is GC-ed */ if (job->finish_p || job->unit->iseq == NULL) { CRITICAL_SECTION_FINISH(3, "in mjit_copy_job_handler"); return; |