diff options
-rw-r--r-- | iseq.c | 61 | ||||
-rw-r--r-- | ujit_asm.c | 12 | ||||
-rw-r--r-- | ujit_asm.h | 1 | ||||
-rw-r--r-- | ujit_asm_tests.c | 13 | ||||
-rw-r--r-- | ujit_compile.c | 12 |
5 files changed, 18 insertions, 81 deletions
@@ -43,9 +43,6 @@ #include "insns.inc" #include "insns_info.inc" #include <sys/mman.h> -#include "ujit_examples.h" - -uint8_t *native_pop_code; // TODO: hack. see addr2insn VALUE rb_cISeq; static VALUE iseqw_new(const rb_iseq_t *iseq); @@ -3217,52 +3214,6 @@ rb_vm_encoded_insn_data_table_init(void) st_add_direct(rb_encoded_insn_data, key1, (st_data_t)&insn_data[insn]); st_add_direct(rb_encoded_insn_data, key2, (st_data_t)&insn_data[insn]); } - - - /* - native_pop_code = mmap(0, 4096, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, 0, 0); - if (native_pop_code == MAP_FAILED) rb_bug("mmap failed"); - uint8_t *head = native_pop_code; - memcpy(head, ujit_pre_call_bytes, sizeof(ujit_pre_call_bytes)); - head += sizeof(ujit_pre_call_bytes); - const uint8_t handmade_pop[] = { // TODO assmeble this from a separate file - 0x48, 0x83, 0x6f, 0x08, 0x08, // subq $8, 8(%rdi) - 0x48, 0x83, 0xc6, 0x08, // addq $8, %rsi - 0x48, 0x89, 0x37, // movq %rsi, (%rdi) - 0x48, 0x89, 0xf0 // movq %rsi, %rax - }; - memcpy(head, handmade_pop, sizeof(handmade_pop)); - head += sizeof(handmade_pop); - memcpy(head, ujit_post_call_bytes, sizeof(ujit_post_call_bytes)); - // TODO this is small enough to fit in the page we allocated but that can change - */ - - - - // I decided to start by replicating Alan's code above using the new assembler - codeblock_t block; - codeblock_t* cb = █ - cb_init(cb, 4096); - - // 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); - - native_pop_code = cb_get_ptr(cb, 0); - - - - - - - } int @@ -3276,12 +3227,6 @@ rb_vm_insn_addr2insn(const void *addr) return (int)e->insn; } - // TODO this is a hack. The proper way to do this is to refactor this so that it takes - // the iseq body. - if (addr && addr == native_pop_code) { - return BIN(pop); - } - rb_bug("rb_vm_insn_addr2insn: invalid insn address: %p", addr); } @@ -3312,12 +3257,6 @@ encoded_iseq_trace_instrument(VALUE *iseq_encoded_insn, rb_event_flag_t turnon, return e->insn_len; } - // TODO this is a hack. The proper way to do this is to refactor this so that it takes - // the iseq body. - if (key && (uint8_t *)key == native_pop_code) { - return insn_len(BIN(pop)); - } - rb_bug("trace_instrument: invalid insn address: %p", (void *)*iseq_encoded_insn); } diff --git a/ujit_asm.c b/ujit_asm.c index edc0672300..b69d37e4b4 100644 --- a/ujit_asm.c +++ b/ujit_asm.c @@ -723,22 +723,20 @@ void add(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1) ); } -/* /// call - Call to label with 32-bit offset -void call(CodeBlock cb, Label label) +void call_label(codeblock_t* cb, size_t label_idx) { - cb.writeASM("call", label); + //cb.writeASM("call", label); // Write the opcode - cb.writeByte(0xE8); + cb_write_byte(cb, 0xE8); // Add a reference to the label - cb.addLabelRef(label); + cb_label_ref(cb, label_idx); // Relative 32-bit offset to be patched - cb.writeInt(0, 32); + cb_write_int(cb, 0, 32); } -*/ /// call - Indirect call with an R/M operand void call(codeblock_t* cb, x86opnd_t opnd) diff --git a/ujit_asm.h b/ujit_asm.h index 31d8ea44d3..339027d726 100644 --- a/ujit_asm.h +++ b/ujit_asm.h @@ -194,6 +194,7 @@ void cb_write_epilogue(codeblock_t* cb); // Encode individual instructions into a code block void add(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1); +void call_label(codeblock_t* cb, size_t label_idx); void call(codeblock_t* cb, x86opnd_t opnd); void ja(codeblock_t* cb, size_t label_idx); void jae(codeblock_t* cb, size_t label_idx); diff --git a/ujit_asm_tests.c b/ujit_asm_tests.c index 3dece1dc1a..8f93f8fefe 100644 --- a/ujit_asm_tests.c +++ b/ujit_asm_tests.c @@ -83,12 +83,13 @@ void run_tests() cb_set_pos(cb, 0); add(cb, ECX, imm_opnd(255)); check_bytes(cb, "81C1FF000000"); // call - /* - test( - delegate void (CodeBlock cb) { auto l = cb.label("foo"); cb.instr(CALL, l); }, - "E8FBFFFFFF" - ); - */ + { + cb_set_pos(cb, 0); + size_t fn_label = cb_new_label(cb, "foo"); + call_label(cb, fn_label); + cb_link_labels(cb); + check_bytes(cb, "E8FBFFFFFF"); + } cb_set_pos(cb, 0); call(cb, RAX); check_bytes(cb, "FFD0"); cb_set_pos(cb, 0); call(cb, mem_opnd(64, RSP, 8)); check_bytes(cb, "FF542408"); diff --git a/ujit_compile.c b/ujit_compile.c index d34d45fea1..60439e7260 100644 --- a/ujit_compile.c +++ b/ujit_compile.c @@ -8,17 +8,12 @@ #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 extern st_table *rb_encoded_insn_data; -// See coment for rb_encoded_insn_data in iseq.c +// See comment for rb_encoded_insn_data in iseq.c static void addr2insn_bookkeeping(void *code_ptr, int insn) { @@ -29,7 +24,7 @@ addr2insn_bookkeeping(void *code_ptr, int insn) st_insert(rb_encoded_insn_data, (st_data_t)code_ptr, encoded_insn_data); } else { - rb_bug("ujit: failed to find info for original instruction while dealing wiht addr2insn"); + rb_bug("ujit: failed to find info for original instruction while dealing with addr2insn"); } } @@ -51,6 +46,9 @@ ujit_compile_insn(rb_iseq_t *iseq, size_t insn_idx) //const char* name = insn_name(insn); //printf("%s\n", name); + // TODO: encode individual instructions, eg + // putnil, putobject, pop, dup, getlocal, nilp + if (insn == BIN(pop)) { // Get a pointer to the current write position in the code block |