@@ -633,162 +633,6 @@ jit_jump_to_next_insn(jitstate_t *jit, const ctx_t *current_context)
633633 );
634634}
635635
636- // Compile a sequence of bytecode instructions for a given basic block version.
637- // Part of gen_block_version().
638- static block_t *
639- gen_single_block (blockid_t blockid , const ctx_t * start_ctx , rb_execution_context_t * ec )
640- {
641- RUBY_ASSERT (cb != NULL );
642- verify_blockid (blockid );
643-
644- // Allocate the new block
645- block_t * block = calloc (1 , sizeof (block_t ));
646- if (!block ) {
647- return NULL ;
648- }
649-
650- // Copy the starting context to avoid mutating it
651- ctx_t ctx_copy = * start_ctx ;
652- ctx_t * ctx = & ctx_copy ;
653-
654- // Limit the number of specialized versions for this block
655- * ctx = limit_block_versions (blockid , ctx );
656-
657- // Save the starting context on the block.
658- block -> blockid = blockid ;
659- block -> ctx = * ctx ;
660-
661- RUBY_ASSERT (!(blockid .idx == 0 && start_ctx -> stack_size > 0 ));
662-
663- const rb_iseq_t * iseq = block -> blockid .iseq ;
664- const unsigned int iseq_size = iseq -> body -> iseq_size ;
665- uint32_t insn_idx = block -> blockid .idx ;
666- const uint32_t starting_insn_idx = insn_idx ;
667-
668- // Initialize a JIT state object
669- jitstate_t jit = {
670- .cb = cb ,
671- .ocb = ocb ,
672- .block = block ,
673- .iseq = iseq ,
674- .ec = ec
675- };
676-
677- // Mark the start position of the block
678- block -> start_addr = cb_get_write_ptr (cb );
679-
680- // For each instruction to compile
681- while (insn_idx < iseq_size ) {
682- // Get the current pc and opcode
683- VALUE * pc = yjit_iseq_pc_at_idx (iseq , insn_idx );
684- int opcode = yjit_opcode_at_pc (iseq , pc );
685- RUBY_ASSERT (opcode >= 0 && opcode < VM_INSTRUCTION_SIZE );
686-
687- // opt_getinlinecache wants to be in a block all on its own. Cut the block short
688- // if we run into it. See gen_opt_getinlinecache() for details.
689- if (opcode == BIN (opt_getinlinecache ) && insn_idx > starting_insn_idx ) {
690- jit_jump_to_next_insn (& jit , ctx );
691- break ;
692- }
693-
694- // Set the current instruction
695- jit .insn_idx = insn_idx ;
696- jit .opcode = opcode ;
697- jit .pc = pc ;
698- jit .side_exit_for_pc = NULL ;
699-
700- // If previous instruction requested to record the boundary
701- if (jit .record_boundary_patch_point ) {
702- // Generate an exit to this instruction and record it
703- uint32_t exit_pos = yjit_gen_exit (jit .pc , ctx , ocb );
704- record_global_inval_patch (cb , exit_pos );
705- jit .record_boundary_patch_point = false;
706- }
707-
708- // Verify our existing assumption (DEBUG)
709- if (jit_at_current_insn (& jit )) {
710- verify_ctx (& jit , ctx );
711- }
712-
713- // Lookup the codegen function for this instruction
714- codegen_fn gen_fn = gen_fns [opcode ];
715- codegen_status_t status = YJIT_CANT_COMPILE ;
716- if (gen_fn ) {
717- if (0 ) {
718- fprintf (stderr , "compiling %d: %s\n" , insn_idx , insn_name (opcode ));
719- print_str (cb , insn_name (opcode ));
720- }
721-
722- // :count-placement:
723- // Count bytecode instructions that execute in generated code.
724- // Note that the increment happens even when the output takes side exit.
725- GEN_COUNTER_INC (cb , exec_instruction );
726-
727- // Add a comment for the name of the YARV instruction
728- ADD_COMMENT (cb , insn_name (opcode ));
729-
730- // Call the code generation function
731- status = gen_fn (& jit , ctx , cb );
732- }
733-
734- // If we can't compile this instruction
735- // exit to the interpreter and stop compiling
736- if (status == YJIT_CANT_COMPILE ) {
737- // TODO: if the codegen function makes changes to ctx and then return YJIT_CANT_COMPILE,
738- // the exit this generates would be wrong. We could save a copy of the entry context
739- // and assert that ctx is the same here.
740- uint32_t exit_off = yjit_gen_exit (jit .pc , ctx , cb );
741-
742- // If this is the first instruction in the block, then we can use
743- // the exit for block->entry_exit.
744- if (insn_idx == block -> blockid .idx ) {
745- block -> entry_exit = cb_get_ptr (cb , exit_off );
746- }
747- break ;
748- }
749-
750- // For now, reset the chain depth after each instruction as only the
751- // first instruction in the block can concern itself with the depth.
752- ctx -> chain_depth = 0 ;
753-
754- // Move to the next instruction to compile
755- insn_idx += insn_len (opcode );
756-
757- // If the instruction terminates this block
758- if (status == YJIT_END_BLOCK ) {
759- break ;
760- }
761- }
762-
763- // Mark the end position of the block
764- block -> end_addr = cb_get_write_ptr (cb );
765-
766- // Store the index of the last instruction in the block
767- block -> end_idx = insn_idx ;
768-
769- // We currently can't handle cases where the request is for a block that
770- // doesn't go to the next instruction.
771- RUBY_ASSERT (!jit .record_boundary_patch_point );
772-
773- // If code for the block doesn't fit, free the block and fail.
774- if (cb -> dropped_bytes || ocb -> dropped_bytes ) {
775- yjit_free_block (block );
776- return NULL ;
777- }
778-
779- if (YJIT_DUMP_MODE >= 2 ) {
780- // Dump list of compiled instrutions
781- fprintf (stderr , "Compiled the following for iseq=%p:\n" , (void * )iseq );
782- for (uint32_t idx = block -> blockid .idx ; idx < insn_idx ; ) {
783- int opcode = yjit_opcode_at_pc (iseq , yjit_iseq_pc_at_idx (iseq , idx ));
784- fprintf (stderr , " %04d %s\n" , idx , insn_name (opcode ));
785- idx += insn_len (opcode );
786- }
787- }
788-
789- return block ;
790- }
791-
792636static codegen_status_t gen_opt_send_without_block (jitstate_t * jit , ctx_t * ctx , codeblock_t * cb );
793637
794638static codegen_status_t
0 commit comments