summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com>2020-09-10 17:20:46 -0400
committerAlan Wu <XrXr@users.noreply.github.com>2021-10-20 18:19:23 -0400
commit1c8fb90f6bde0c630f5dc532dfe198218bc9f910 (patch)
treeb6e0cbb41043040d397b7eca230c7a100fb9cd88
parent566d4abee5e8e59ce6e080f28a25b7c3431c5b3b (diff)
Add new files, ujit_compile.c, ujit_compile.h
-rw-r--r--common.mk1
-rw-r--r--compile.c15
-rw-r--r--ujit_compile.c63
-rw-r--r--ujit_compile.h14
4 files changed, 85 insertions, 8 deletions
diff --git a/common.mk b/common.mk
index 1c62cc000c..5c8a8e1cce 100644
--- a/common.mk
+++ b/common.mk
@@ -151,6 +151,7 @@ COMMONOBJS = array.$(OBJEXT) \
vm_sync.$(OBJEXT) \
vm_trace.$(OBJEXT) \
ujit_asm.$(OBJEXT) \
+ ujit_compile.$(OBJEXT) \
$(COROUTINE_OBJ) \
$(DTRACE_OBJ) \
$(BUILTIN_ENCOBJS) \
diff --git a/compile.c b/compile.c
index a1983eaecb..dd19fe2736 100644
--- a/compile.c
+++ b/compile.c
@@ -43,6 +43,7 @@
#include "builtin.h"
#include "insns.inc"
#include "insns_info.inc"
+#include "ujit_compile.h"
#undef RUBY_UNTYPED_DATA_WARNING
#define RUBY_UNTYPED_DATA_WARNING 0
@@ -856,8 +857,6 @@ rb_iseq_compile_node(rb_iseq_t *iseq, const NODE *node)
return iseq_setup(iseq, ret);
}
-extern uint8_t *native_pop_code; // TODO global hack
-
static int
rb_iseq_translate_threaded_code(rb_iseq_t *iseq)
{
@@ -870,17 +869,17 @@ rb_iseq_translate_threaded_code(rb_iseq_t *iseq)
{
int insn = (int)iseq->body->iseq_encoded[i];
int len = insn_len(insn);
- encoded[i] = (VALUE)table[insn];
-
- if (insn == BIN(pop))
- encoded[i] = (VALUE)native_pop_code;
- const char* name = insn_name(insn);
- printf("%s\n", name);
+ uint8_t* native_code_ptr = ujit_compile_insn(iseq, i);
+ if (native_code_ptr)
+ encoded[i] = (VALUE)native_code_ptr;
+ else
+ encoded[i] = (VALUE)table[insn];
i += len;
}
+
FL_SET((VALUE)iseq, ISEQ_TRANSLATED);
#endif
return COMPILE_OK;
diff --git a/ujit_compile.c b/ujit_compile.c
new file mode 100644
index 0000000000..9ed2cc7727
--- /dev/null
+++ b/ujit_compile.c
@@ -0,0 +1,63 @@
+#include <assert.h>
+#include "insns.inc"
+#include "internal.h"
+#include "vm_core.h"
+#include "vm_callinfo.h"
+#include "builtin.h"
+#include "insns_info.inc"
+#include "ujit_compile.h"
+#include "ujit_asm.h"
+
+// NOTE: do we have to deal with multiple Ruby processes/threads compiling
+// functions with the new Ractor in Ruby 3.0? If so, we need to think about
+// a strategy for handling that. What does Ruby currently do for its own
+// iseq translation?
+static codeblock_t block;
+static codeblock_t* cb = NULL;
+
+extern uint8_t* native_pop_code; // FIXME global hack
+
+// Generate a chunk of machinecode for one individual bytecode instruction
+// Eventually, this will handle multiple instructions in a sequence
+uint8_t* ujit_compile_insn(rb_iseq_t *iseq, size_t insn_idx)
+{
+ // Allocate the code block if not previously allocated
+ if (!cb)
+ {
+ // 4MB ought to be enough for anybody
+ cb = &block;
+ cb_init(cb, 4000000);
+ }
+
+ int insn = (int)iseq->body->iseq_encoded[insn_idx];
+
+ //const char* name = insn_name(insn);
+ //printf("%s\n", name);
+
+ if (insn == BIN(pop))
+ {
+ //printf("COMPILING %ld\n", cb->write_pos);
+
+ return native_pop_code;
+
+ /*
+ // Get a pointer to the current write position in the code block
+ uint8_t* code_ptr = &cb->mem_block[cb->write_pos];
+
+ // Write the pre call bytes
+ cb_write_prologue(cb);
+
+ sub(cb, mem_opnd(64, RDI, 8), imm_opnd(8)); // decrement SP
+ 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 pop bytecode?
+ mov(cb, RAX, RSI); // return new PC
+
+ // Write the post call bytes
+ cb_write_epilogue(cb);
+
+ return code_ptr;
+ */
+ }
+
+ return 0;
+}
diff --git a/ujit_compile.h b/ujit_compile.h
new file mode 100644
index 0000000000..4f00c4cb44
--- /dev/null
+++ b/ujit_compile.h
@@ -0,0 +1,14 @@
+#ifndef UJIT_COMPILE_H
+#define UJIT_COMPILE_H 1
+
+#include "stddef.h"
+#include "stdint.h"
+
+#ifndef rb_iseq_t
+typedef struct rb_iseq_struct rb_iseq_t;
+#define rb_iseq_t rb_iseq_t
+#endif
+
+uint8_t* ujit_compile_insn(rb_iseq_t* iseq, size_t insn_idx);
+
+#endif