Skip to content

Commit ff12b7a

Browse files
authored
Merge pull request ruby#96 from Shopify/yjit-thread-bug
YJIT: adjust branch shape properly when target already exists
2 parents e76ad90 + b5ab480 commit ff12b7a

File tree

2 files changed

+17
-16
lines changed

2 files changed

+17
-16
lines changed

yjit_core.c

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,7 @@ uint8_t* gen_entry_point(const rb_iseq_t *iseq, uint32_t insn_idx, rb_execution_
418418
// Called by the generated code when a branch stub is executed
419419
// Triggers compilation of branches and code patching
420420
static uint8_t *
421-
branch_stub_hit(uint32_t branch_idx, uint32_t target_idx, rb_execution_context_t* ec)
421+
branch_stub_hit(const uint32_t branch_idx, const uint32_t target_idx, rb_execution_context_t* ec)
422422
{
423423
uint8_t* dst_addr;
424424

@@ -449,18 +449,6 @@ branch_stub_hit(uint32_t branch_idx, uint32_t target_idx, rb_execution_context_t
449449
// may be out of sync in JITted code
450450
ec->cfp->pc = iseq_pc_at_idx(target.iseq, target.idx);
451451

452-
// If either of the target blocks will be placed next
453-
if (cb->write_pos == branch->end_pos)
454-
{
455-
//fprintf(stderr, "target idx %d will be placed next\n", target_idx);
456-
branch->shape = (uint8_t)target_idx;
457-
458-
// Rewrite the branch with the new, potentially more compact shape
459-
cb_set_pos(cb, branch->start_pos);
460-
branch->gen_fn(cb, branch->dst_addrs[0], branch->dst_addrs[1], branch->shape);
461-
RUBY_ASSERT(cb->write_pos <= branch->end_pos);
462-
}
463-
464452
// Try to find an existing compiled version of this block
465453
block_t* p_block = find_block_version(target, target_ctx);
466454

@@ -487,13 +475,26 @@ branch_stub_hit(uint32_t branch_idx, uint32_t target_idx, rb_execution_context_t
487475
dst_addr = cb_get_ptr(cb, p_block->start_pos);
488476
branch->dst_addrs[target_idx] = dst_addr;
489477

478+
// Adjust brach shape based on block placement relative to the branch
479+
if (branch->end_pos == p_block->start_pos) {
480+
branch->shape = (branch_shape_t)target_idx;
481+
}
482+
490483
// Rewrite the branch with the new jump target address
491484
RUBY_ASSERT(branch->dst_addrs[0] != NULL);
492485
uint32_t cur_pos = cb->write_pos;
493486
cb_set_pos(cb, branch->start_pos);
494487
branch->gen_fn(cb, branch->dst_addrs[0], branch->dst_addrs[1], branch->shape);
495-
RUBY_ASSERT(cb->write_pos <= branch->end_pos);
496-
branch->end_pos = cb->write_pos;
488+
RUBY_ASSERT(cb->write_pos <= branch->end_pos && "can't enlarge a branch");
489+
490+
// If the branch got smaller
491+
if (cb->write_pos < branch->end_pos) {
492+
// fill the difference with nops
493+
uint32_t shrinkage = branch->end_pos - cb->write_pos;
494+
nop(cb, shrinkage);
495+
}
496+
497+
// Done patching the branch. Restore write position.
497498
cb_set_pos(cb, cur_pos);
498499

499500
// Restore interpreter sp, since the code hitting the stub expects the original.

yjit_core.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ typedef void (*branchgen_fn)(codeblock_t* cb, uint8_t* target0, uint8_t* target1
156156
Store info about an outgoing branch in a code segment
157157
Note: care must be taken to minimize the size of branch_t objects
158158
*/
159-
typedef struct BranchEntry
159+
typedef struct yjit_branch_entry
160160
{
161161
// Positions where the generated code starts and ends
162162
uint32_t start_pos;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy