summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Wu <XrXr@users.noreply.github.com>2021-12-07 14:27:49 -0500
committerAlan Wu <XrXr@users.noreply.github.com>2021-12-07 17:20:56 -0500
commit6beb05c2ad924eed761e6a31fcc397a5faa57553 (patch)
treeb67dea7054742762131d6c1855235d9c24bc195d
parent286c07f0dcd7999bfb9cb4889125ebce59dca4cc (diff)
YJIT: Undo add_block_version() in OOM code path
Preivously, [1] failed to undo the effect of applying add_block_version() to a block, leaving dangling pointers in the iseq when compilation fails. [1]: d0772632bf2ff15f73c0d3601d958670a5c77855
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/5226
-rw-r--r--yjit_core.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/yjit_core.c b/yjit_core.c
index d420f0fcab..b226f8bd34 100644
--- a/yjit_core.c
+++ b/yjit_core.c
@@ -729,6 +729,7 @@ limit_block_versions(blockid_t blockid, const ctx_t *ctx)
}
static void yjit_free_block(block_t *block);
+static void block_array_remove(rb_yjit_block_array_t block_array, block_t *block);
// Immediately compile a series of block versions at a starting point and
// return the starting block.
@@ -810,7 +811,14 @@ gen_block_version(blockid_t blockid, const ctx_t *start_ctx, rb_execution_contex
else {
// The batch failed. Free everything in the batch
for (int block_idx = 0; block_idx < compiled_count; block_idx++) {
- yjit_free_block(batch[block_idx]);
+ block_t *const to_free = batch[block_idx];
+
+ // Undo add_block_version()
+ rb_yjit_block_array_t versions = yjit_get_version_array(to_free->blockid.iseq, to_free->blockid.idx);
+ block_array_remove(versions, to_free);
+
+ // Deallocate
+ yjit_free_block(to_free);
}
#if YJIT_STATS