@@ -113,6 +113,15 @@ Returns INT_MAX if incompatible
113113*/
114114int ctx_diff (const ctx_t * src , const ctx_t * dst )
115115{
116+ // Can only lookup the first version in the chain
117+ if (dst -> chain_depth != 0 )
118+ return INT_MAX ;
119+
120+ // Blocks with depth > 0 always produce new versions
121+ // Sidechains cannot overlap
122+ if (src -> chain_depth != 0 )
123+ return INT_MAX ;
124+
116125 if (dst -> stack_size != src -> stack_size )
117126 return INT_MAX ;
118127
@@ -353,6 +362,7 @@ uint8_t* branch_stub_hit(uint32_t branch_idx, uint32_t target_idx, rb_execution_
353362
354363 //fprintf(stderr, "\nstub hit, branch idx: %d, target idx: %d\n", branch_idx, target_idx);
355364 //fprintf(stderr, "blockid.iseq=%p, blockid.idx=%d\n", target.iseq, target.idx);
365+ //fprintf(stderr, "chain_depth=%d\n", target_ctx->chain_depth);
356366
357367 // Update the PC in the current CFP, because it
358368 // may be out of sync in JITted code
@@ -376,7 +386,7 @@ uint8_t* branch_stub_hit(uint32_t branch_idx, uint32_t target_idx, rb_execution_
376386 generic_ctx .sp_offset = target_ctx -> sp_offset ;
377387 if (get_num_versions (target ) >= MAX_VERSIONS - 1 )
378388 {
379- fprintf (stderr , "version limit hit in branch_stub_hit\n" );
389+ // fprintf(stderr, "version limit hit in branch_stub_hit\n");
380390 target_ctx = & generic_ctx ;
381391 }
382392
@@ -542,7 +552,7 @@ void gen_direct_jump(
542552 generic_ctx .sp_offset = ctx -> sp_offset ;
543553 if (get_num_versions (target0 ) >= MAX_VERSIONS - 1 )
544554 {
545- fprintf (stderr , "version limit hit in gen_direct_jump\n" );
555+ // fprintf(stderr, "version limit hit in gen_direct_jump\n");
546556 ctx = & generic_ctx ;
547557 }
548558
@@ -588,42 +598,50 @@ void gen_direct_jump(
588598// Create a stub to force the code up to this point to be executed
589599void defer_compilation (
590600 block_t * block ,
591- ctx_t * cur_ctx ,
592- uint32_t insn_idx
601+ uint32_t insn_idx ,
602+ ctx_t * cur_ctx
593603)
594604{
605+ //fprintf(stderr, "defer compilation at (%p, %d) depth=%d\n", block->blockid.iseq, insn_idx, cur_ctx->chain_depth);
595606
607+ if (cur_ctx -> chain_depth != 0 ) {
608+ rb_backtrace ();
609+ exit (1 );
610+ }
596611
612+ ctx_t next_ctx = * cur_ctx ;
597613
614+ if (next_ctx .chain_depth >= UINT8_MAX ) {
615+ rb_bug ("max block version chain depth reached" );
616+ }
598617
618+ next_ctx .chain_depth += 1 ;
599619
600-
601-
602-
603-
604-
605-
606-
607- /*
608620 RUBY_ASSERT (num_branches < MAX_BRANCHES );
609621 uint32_t branch_idx = num_branches ++ ;
610622
623+ // Get the branch targets or stubs
624+ blockid_t target0 = (blockid_t ){ block -> blockid .iseq , insn_idx };
625+ uint8_t * dst_addr0 = get_branch_target (target0 , & next_ctx , branch_idx , 0 );
626+
627+ // Call the branch generation function
628+ uint32_t start_pos = cb -> write_pos ;
629+ gen_jump_branch (cb , dst_addr0 , NULL , SHAPE_DEFAULT );
630+ uint32_t end_pos = cb -> write_pos ;
631+
611632 // Register this branch entry
612633 branch_t branch_entry = {
613634 start_pos ,
614635 end_pos ,
615- *ctx ,
636+ * cur_ctx ,
616637 { target0 , BLOCKID_NULL },
617- { *ctx, *ctx },
638+ { next_ctx , next_ctx },
618639 { dst_addr0 , NULL },
619640 gen_jump_branch ,
620- branch_shape
641+ SHAPE_DEFAULT
621642 };
622643
623644 branch_entries [branch_idx ] = branch_entry ;
624- */
625-
626-
627645}
628646
629647// Remove all references to a block then free it.
0 commit comments