diff options
author | Maxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com> | 2020-09-16 13:52:35 -0400 |
---|---|---|
committer | Alan Wu <XrXr@users.noreply.github.com> | 2021-10-20 18:19:23 -0400 |
commit | 8a5ced8eb5ed96ba3d806b2a30790c87c453a9a0 (patch) | |
tree | 05b8cacdf3452c132c2e1070308db1ecee7536e2 | |
parent | 7eb192d644996cb2c79663d34e3364adb7dface5 (diff) | |
download | ruby-8a5ced8eb5ed96ba3d806b2a30790c87c453a9a0.tar.gz |
Chain compilation of adjacent instructions
-rw-r--r-- | ujit_compile.c | 65 |
1 files changed, 43 insertions, 22 deletions
diff --git a/ujit_compile.c b/ujit_compile.c index bd2d8697eb..60dc6a0927 100644 --- a/ujit_compile.c +++ b/ujit_compile.c @@ -109,40 +109,61 @@ ujit_compile_insn(rb_iseq_t *iseq, size_t insn_idx) uint8_t *code_ptr = &cb->mem_block[cb->write_pos]; //printf("write pos: %ld\n", cb->write_pos); - int insn = (int)iseq->body->iseq_encoded[insn_idx]; - int len = insn_len(insn); - //const char* name = insn_name(insn); - //printf("%s\n", name); - - // Lookup the codegen function for this instruction - st_data_t st_gen_fn; - int found = rb_st_lookup(gen_fns, insn, &st_gen_fn); - - if (!found) - return 0; - - codegen_fn gen_fn = (codegen_fn)st_gen_fn; - - // Write the pre call bytes - ujit_instr_entry(cb); + // Get the first opcode in the sequence + int first_opcode = (int)iseq->body->iseq_encoded[insn_idx]; // Create codegen context ctx_t ctx; - // Set the current PC - ctx.pc = &iseq->body->iseq_encoded[insn_idx]; + // For each instruction to compile + size_t num_instrs; + for (num_instrs = 0;; ++num_instrs) + { + // Set the current PC + ctx.pc = &iseq->body->iseq_encoded[insn_idx]; + + // Get the current opcode + int opcode = ctx_get_opcode(&ctx); + //const char* name = insn_name(insn); + //printf("%s\n", name); + + // Lookup the codegen function for this instruction + st_data_t st_gen_fn; + int found = rb_st_lookup(gen_fns, opcode, &st_gen_fn); + + if (!found) + { + break; + } + + // Write the pre call bytes before the first instruction + if (num_instrs == 0) + { + ujit_instr_entry(cb); + } + + // Call the code generation function + codegen_fn gen_fn = (codegen_fn)st_gen_fn; + gen_fn(cb, &ctx); + + // Move to the next instruction + insn_idx += insn_len(opcode); + } - // Call the code generation function - gen_fn(cb, &ctx); + // If no instructions were compiled + if (num_instrs == 0) + { + return NULL; + } // Directly return the next PC, which is a constant - void *next_pc = &iseq->body->iseq_encoded[insn_idx + len]; + void *next_pc = &iseq->body->iseq_encoded[insn_idx]; mov(cb, RAX, const_ptr_opnd(next_pc)); // Write the post call bytes ujit_instr_exit(cb); - addr2insn_bookkeeping(code_ptr, insn); + addr2insn_bookkeeping(code_ptr, first_opcode); return code_ptr; } |