diff options
author | Alan Wu <XrXr@users.noreply.github.com> | 2021-03-24 18:07:26 -0400 |
---|---|---|
committer | Alan Wu <XrXr@users.noreply.github.com> | 2021-10-20 18:19:33 -0400 |
commit | b626dd7211b9d45f1dab6f82057445781f34f20f (patch) | |
tree | 76f107f1a2b79b4be590eea99aa98f97bd6eed14 /yjit_core.c | |
parent | e81d1f4ae31086c19b936bb8d0bf4650b0c36f44 (diff) |
YJIT: Fancier opt_getinlinecache
Make sure `opt_getinlinecache` is in a block all on its own, and
invalidate it from the interpreter when `opt_setinlinecache`.
It will recompile with a filled cache the second time around.
This lets YJIT runs well when the IC for constant is cold.
Diffstat (limited to 'yjit_core.c')
-rw-r--r-- | yjit_core.c | 19 |
1 files changed, 10 insertions, 9 deletions
diff --git a/yjit_core.c b/yjit_core.c index 521db462fa..3be45c12e5 100644 --- a/yjit_core.c +++ b/yjit_core.c @@ -289,8 +289,8 @@ int ctx_diff(const ctx_t* src, const ctx_t* dst) } // Get all blocks for a particular place in an iseq. -static rb_yjit_block_array_t -get_version_array(const rb_iseq_t *iseq, unsigned idx) +rb_yjit_block_array_t +yjit_get_version_array(const rb_iseq_t *iseq, unsigned idx) { struct rb_iseq_constant_body *body = iseq->body; @@ -305,7 +305,7 @@ get_version_array(const rb_iseq_t *iseq, unsigned idx) // Count the number of block versions matching a given blockid static size_t get_num_versions(blockid_t blockid) { - return rb_darray_size(get_version_array(blockid.iseq, blockid.idx)); + return rb_darray_size(yjit_get_version_array(blockid.iseq, blockid.idx)); } // Keep track of a block version. Block should be fully constructed. @@ -364,7 +364,7 @@ add_block_version(blockid_t blockid, block_t* block) // Retrieve a basic block version for an (iseq, idx) tuple block_t* find_block_version(blockid_t blockid, const ctx_t* ctx) { - rb_yjit_block_array_t versions = get_version_array(blockid.iseq, blockid.idx); + rb_yjit_block_array_t versions = yjit_get_version_array(blockid.iseq, blockid.idx); // Best match found block_t* best_version = NULL; @@ -522,7 +522,7 @@ branch_stub_hit(const uint32_t branch_idx, const uint32_t target_idx, rb_executi // Update the PC in the current CFP, because it // may be out of sync in JITted code - ec->cfp->pc = iseq_pc_at_idx(target.iseq, target.idx); + ec->cfp->pc = yjit_iseq_pc_at_idx(target.iseq, target.idx); // Try to find an existing compiled version of this block block_t* p_block = find_block_version(target, target_ctx); @@ -846,7 +846,8 @@ void invalidate_block_version(block_t* block) { ASSERT_vm_locking(); - rb_vm_barrier(); // Stop other ractors since we are going to patch machine code. + // TODO: want to assert that all other ractors are stopped here. Can't patch + // machine code that some other thread is running. const rb_iseq_t *iseq = block->blockid.iseq; @@ -854,7 +855,7 @@ invalidate_block_version(block_t* block) // fprintf(stderr, "block=%p\n", block); // Remove this block from the version array - rb_yjit_block_array_t versions = get_version_array(iseq, block->blockid.idx); + rb_yjit_block_array_t versions = yjit_get_version_array(iseq, block->blockid.idx); RB_UNUSED_VAR(bool removed); removed = block_array_remove(versions, block); RUBY_ASSERT(removed); @@ -909,8 +910,8 @@ invalidate_block_version(block_t* block) uint32_t idx = block->blockid.idx; // FIXME: the following says "if", but it's unconditional. // If the block is an entry point, it needs to be unmapped from its iseq - VALUE* entry_pc = iseq_pc_at_idx(iseq, idx); - int entry_opcode = opcode_at_pc(iseq, entry_pc); + VALUE* entry_pc = yjit_iseq_pc_at_idx(iseq, idx); + int entry_opcode = yjit_opcode_at_pc(iseq, entry_pc); // TODO: unmap_addr2insn in yjit_iface.c? Maybe we can write a function to encompass this logic? // Should check how it's used in exit and side-exit |