summaryrefslogtreecommitdiff
path: root/ujit_compile.c
diff options
context:
space:
mode:
authorMaxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com>2020-09-16 13:52:35 -0400
committerAlan Wu <XrXr@users.noreply.github.com>2021-10-20 18:19:23 -0400
commit8a5ced8eb5ed96ba3d806b2a30790c87c453a9a0 (patch)
tree05b8cacdf3452c132c2e1070308db1ecee7536e2 /ujit_compile.c
parent7eb192d644996cb2c79663d34e3364adb7dface5 (diff)
Chain compilation of adjacent instructions
Diffstat (limited to 'ujit_compile.c')
-rw-r--r--ujit_compile.c65
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;
}