diff options
author | Takashi Kokubun <takashikkbn@gmail.com> | 2020-03-12 22:51:33 -0700 |
---|---|---|
committer | Takashi Kokubun <takashikkbn@gmail.com> | 2020-03-12 22:51:34 -0700 |
commit | 0cd7be99e9a15f649970559e43e3edb704568670 (patch) | |
tree | 848fb360585d0f78ad6f26fdb89a4b61b920beb0 /mjit_worker.c | |
parent | 43e18c68f4d53767db7aae232ca46c2b400148cd (diff) |
Avoid referring to an old value of realloc
OpenBSD RubyCI has failed with SEGV since 4bcd5981e80d3e1852c8723741a0069779464128.
https://rubyci.org/logs/rubyci.s3.amazonaws.com/openbsd-current/ruby-master/log/20200312T223005Z.fail.html.gz
This was because `status->cc_entries` could be stale after `realloc` call
for inlined iseqs.
Diffstat (limited to 'mjit_worker.c')
-rw-r--r-- | mjit_worker.c | 21 |
1 files changed, 16 insertions, 5 deletions
diff --git a/mjit_worker.c b/mjit_worker.c index e9ba24b0af..e7350454b7 100644 --- a/mjit_worker.c +++ b/mjit_worker.c @@ -1151,11 +1151,21 @@ static void mjit_copy_job_handler(void *data); // vm_trace.c int rb_workqueue_register(unsigned flags, rb_postponed_job_func_t , void *); +// To see cc_entries using index returned by `mjit_capture_cc_entries` in mjit_compile.c +const struct rb_callcache ** +mjit_iseq_cc_entries(const struct rb_iseq_constant_body *const body) +{ + return body->jit_unit->cc_entries; +} + // Capture cc entries of `captured_iseq` and append them to `compiled_iseq->jit_unit->cc_entries`. // This is needed when `captured_iseq` is inlined by `compiled_iseq` and GC needs to mark inlined cc. // +// Index to refer to `compiled_iseq->jit_unit->cc_entries` is returned instead of the address +// because old addresses may be invalidated by `realloc` later. -1 is returned on failure. +// // This assumes that it's safe to reference cc without acquiring GVL. -const struct rb_callcache ** +int mjit_capture_cc_entries(const struct rb_iseq_constant_body *compiled_iseq, const struct rb_iseq_constant_body *captured_iseq) { struct rb_mjit_unit *unit = compiled_iseq->jit_unit; @@ -1164,16 +1174,17 @@ mjit_capture_cc_entries(const struct rb_iseq_constant_body *compiled_iseq, const // Allocate new cc_entries and append them to unit->cc_entries const struct rb_callcache **cc_entries; + int cc_entries_index = unit->cc_entries_size; if (unit->cc_entries_size == 0) { VM_ASSERT(unit->cc_entries == NULL); unit->cc_entries = cc_entries = malloc(sizeof(struct rb_callcache *) * new_entries_size); - if (cc_entries == NULL) return NULL; + if (cc_entries == NULL) return -1; } else { cc_entries = realloc(unit->cc_entries, sizeof(struct rb_callcache *) * new_entries_size); - if (cc_entries == NULL) return NULL; + if (cc_entries == NULL) return -1; unit->cc_entries = cc_entries; - cc_entries += unit->cc_entries_size; + cc_entries += cc_entries_index; } unit->cc_entries_size = new_entries_size; @@ -1182,7 +1193,7 @@ mjit_capture_cc_entries(const struct rb_iseq_constant_body *compiled_iseq, const cc_entries[i] = captured_iseq->call_data[i].cc; } - return cc_entries; + return cc_entries_index; } // Copy inline cache values of `iseq` to `cc_entries` and `is_entries`. |