summaryrefslogtreecommitdiff
path: root/yjit_core.c
diff options
context:
space:
mode:
authorAlan Wu <XrXr@users.noreply.github.com>2021-03-24 18:07:26 -0400
committerAlan Wu <XrXr@users.noreply.github.com>2021-10-20 18:19:33 -0400
commitb626dd7211b9d45f1dab6f82057445781f34f20f (patch)
tree76f107f1a2b79b4be590eea99aa98f97bd6eed14 /yjit_core.c
parente81d1f4ae31086c19b936bb8d0bf4650b0c36f44 (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.c19
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