summaryrefslogtreecommitdiff
path: root/ujit_compile.c
diff options
context:
space:
mode:
authorMaxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com>2020-09-14 13:31:34 -0400
committerAlan Wu <XrXr@users.noreply.github.com>2021-10-20 18:19:23 -0400
commitca47899ccf9547223f4c64fc4b0837796bee09af (patch)
treec6b40971fc3c152cbaf603b7db2a774e0f613b97 /ujit_compile.c
parent1879a123caeb9caced2eeb2bb7a7a91a4a8e1930 (diff)
Small refactorings in ujit_compile.c
Diffstat (limited to 'ujit_compile.c')
-rw-r--r--ujit_compile.c44
1 files changed, 36 insertions, 8 deletions
diff --git a/ujit_compile.c b/ujit_compile.c
index 82ea7291f8..3f3f8fd2c6 100644
--- a/ujit_compile.c
+++ b/ujit_compile.c
@@ -8,11 +8,34 @@
#include "ujit_compile.h"
#include "ujit_asm.h"
+// TODO: give ujit_examples.h some more meaningful file name
+#include "ujit_examples.h"
+
static codeblock_t block;
static codeblock_t* cb = NULL;
+// Hash table of encoded instructions
extern st_table *rb_encoded_insn_data;
+static void ujit_init();
+
+// Ruby instruction entry
+static void
+ujit_instr_entry(codeblock_t* cb)
+{
+ for (size_t i = 0; i < sizeof(ujit_pre_call_bytes); ++i)
+ cb_write_byte(cb, ujit_pre_call_bytes[i]);
+}
+
+// Ruby instruction exit
+static void
+ujit_instr_exit(codeblock_t* cb)
+{
+ for (size_t i = 0; i < sizeof(ujit_post_call_bytes); ++i)
+ cb_write_byte(cb, ujit_post_call_bytes[i]);
+}
+
+// Keep track of mapping from instructions to generated code
// See comment for rb_encoded_insn_data in iseq.c
static void
addr2insn_bookkeeping(void *code_ptr, int insn)
@@ -33,12 +56,10 @@ addr2insn_bookkeeping(void *code_ptr, int insn)
uint8_t *
ujit_compile_insn(rb_iseq_t *iseq, size_t insn_idx)
{
- // Allocate the code block if not previously allocated
+ // If not previously done, initialize ujit
if (!cb)
{
- // 4MB ought to be enough for anybody
- cb = &block;
- cb_init(cb, 4000000);
+ ujit_init();
}
int insn = (int)iseq->body->iseq_encoded[insn_idx];
@@ -57,14 +78,14 @@ ujit_compile_insn(rb_iseq_t *iseq, size_t insn_idx)
if (insn == BIN(nop))
{
// Write the pre call bytes
- cb_write_prologue(cb);
+ ujit_instr_entry(cb);
add(cb, RSI, imm_opnd(8)); // increment PC
mov(cb, mem_opnd(64, RDI, 0), RSI); // write new PC to EC object, not necessary for nop bytecode?
mov(cb, RAX, RSI); // return new PC
// Write the post call bytes
- cb_write_epilogue(cb);
+ ujit_instr_exit(cb);
addr2insn_bookkeeping(code_ptr, insn);
@@ -74,7 +95,7 @@ ujit_compile_insn(rb_iseq_t *iseq, size_t insn_idx)
if (insn == BIN(pop))
{
// Write the pre call bytes
- cb_write_prologue(cb);
+ ujit_instr_entry(cb);
sub(cb, mem_opnd(64, RDI, 8), imm_opnd(8)); // decrement SP
add(cb, RSI, imm_opnd(8)); // increment PC
@@ -82,7 +103,7 @@ ujit_compile_insn(rb_iseq_t *iseq, size_t insn_idx)
mov(cb, RAX, RSI); // return new PC
// Write the post call bytes
- cb_write_epilogue(cb);
+ ujit_instr_exit(cb);
addr2insn_bookkeeping(code_ptr, insn);
@@ -91,3 +112,10 @@ ujit_compile_insn(rb_iseq_t *iseq, size_t insn_idx)
return 0;
}
+
+static void ujit_init()
+{
+ // 4MB ought to be enough for anybody
+ cb = &block;
+ cb_init(cb, 4000000);
+}