diff --git a/gen_ujit_examples.rb b/gen_ujit_examples.rb index f521cd8d4f..dc400bc920 100644 --- a/gen_ujit_examples.rb +++ b/gen_ujit_examples.rb @@ -1,5 +1,5 @@ def get_example_instruction_id - # TODO we could get this from the script that generates vm.inc instead of dothings this song and dance + # TODO we could get this from the script that generates vm.inc instead of doing this song and dance `dwarfdump --name='YARVINSN_ujit_call_example' vm.o`.each_line do |line| if (id = line[/DW_AT_const_value\s\((\d+\))/, 1]) p [__method__, line] if $DEBUG @@ -108,4 +108,3 @@ p offset_to_insn_in_tc_table if $DEBUG offset_to_handler_code_from_vm_exec_core = readint8b(offset_to_insn_in_tc_table) p offset_to_handler_code_from_vm_exec_core if $DEBUG disassemble(vm_exec_core_offset + offset_to_handler_code_from_vm_exec_core) - diff --git a/iseq.c b/iseq.c index cb2ce7787e..6834f0cd26 100644 --- a/iseq.c +++ b/iseq.c @@ -3344,7 +3344,7 @@ trace_set_i(void *vstart, void *vend, size_t stride, void *data) } VALUE * -rb_ujit_empty_func(rb_control_frame_t *cfp, const VALUE *pc) +rb_ujit_empty_func(rb_control_frame_t *cfp) { // okay, not really empty, so maybe think of another name. // it's put in this file instead of say, compile.c to dodge long C compile time. diff --git a/iseq.h b/iseq.h index d10104e355..e83c7e80bd 100644 --- a/iseq.h +++ b/iseq.h @@ -299,7 +299,7 @@ VALUE rb_iseq_defined_string(enum defined_type type); /* vm.c */ VALUE rb_iseq_local_variables(const rb_iseq_t *iseq); -NOINLINE(VALUE *rb_ujit_empty_func(rb_control_frame_t *cfp, const VALUE *pc)); +NOINLINE(VALUE *rb_ujit_empty_func(rb_control_frame_t *cfp)); RUBY_SYMBOL_EXPORT_END diff --git a/tool/ruby_vm/views/vm.inc.erb b/tool/ruby_vm/views/vm.inc.erb index 49d6fc2e16..7942a3ef87 100644 --- a/tool/ruby_vm/views/vm.inc.erb +++ b/tool/ruby_vm/views/vm.inc.erb @@ -34,7 +34,7 @@ INSN_ENTRY(<%= insn.name %>) START_OF_ORIGINAL_INSN(<%= insn.name %>); // assumes USE_MACHINE_REGS, aka reg_pc setup, // aka #define SET_PC(x) (reg_cfp->pc = reg_pc = (x)) - reg_pc = rb_ujit_empty_func(GET_CFP(), reg_pc); + reg_pc = rb_ujit_empty_func(GET_CFP()); END_INSN(<%= insn.name %>); } % end diff --git a/ujit_asm.c b/ujit_asm.c index dcf1be07f1..67e739f8ad 100644 --- a/ujit_asm.c +++ b/ujit_asm.c @@ -97,6 +97,17 @@ x86opnd_t imm_opnd(int64_t imm) return opnd; } +x86opnd_t const_ptr_opnd(void* ptr) +{ + x86opnd_t opnd = { + OPND_IMM, + 64, + .unsig_imm = (uint64_t)ptr + }; + + return opnd; +} + void cb_init(codeblock_t* cb, size_t mem_size) { // Map the memory as executable diff --git a/ujit_asm.h b/ujit_asm.h index a977dd9478..af8f0d7fc7 100644 --- a/ujit_asm.h +++ b/ujit_asm.h @@ -127,7 +127,7 @@ typedef struct X86Opnd int64_t imm; // Unsigned immediate value - uint64_t unsigImm; + uint64_t unsig_imm; }; } x86opnd_t; @@ -177,6 +177,9 @@ x86opnd_t mem_opnd(size_t num_bits, x86opnd_t base_reg, int32_t disp); // Immediate number operand x86opnd_t imm_opnd(int64_t val); +// Constant pointer operand +x86opnd_t const_ptr_opnd(void* ptr); + void cb_init(codeblock_t* cb, size_t mem_size); void cb_set_pos(codeblock_t* cb, size_t pos); uint8_t* cb_get_ptr(codeblock_t* cb, size_t index); diff --git a/ujit_compile.c b/ujit_compile.c index 3f3f8fd2c6..19b2b35c12 100644 --- a/ujit_compile.c +++ b/ujit_compile.c @@ -63,9 +63,13 @@ ujit_compile_insn(rb_iseq_t *iseq, size_t insn_idx) } int insn = (int)iseq->body->iseq_encoded[insn_idx]; + int len = insn_len(insn); //const char* name = insn_name(insn); //printf("%s\n", name); + // Compute the address of the next instruction + void* next_pc = &iseq->body->iseq_encoded[insn_idx + len]; + // Get a pointer to the current write position in the code block uint8_t* code_ptr = &cb->mem_block[cb->write_pos]; //printf("write pos: %ld\n", cb->write_pos); @@ -80,9 +84,12 @@ ujit_compile_insn(rb_iseq_t *iseq, size_t insn_idx) // Write the pre call bytes 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 + //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 + + // Directly return the next PC, which is a constant + mov(cb, RAX, const_ptr_opnd(next_pc)); // Write the post call bytes ujit_instr_exit(cb); @@ -98,9 +105,9 @@ ujit_compile_insn(rb_iseq_t *iseq, size_t insn_idx) ujit_instr_entry(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 + + // Directly return the next PC, which is a constant + mov(cb, RAX, const_ptr_opnd(next_pc)); // Write the post call bytes ujit_instr_exit(cb);