mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Removed native_pop_code, ported call with label
This commit is contained in:
parent
4929ba0a5c
commit
26fecc7236
5 changed files with 18 additions and 81 deletions
61
iseq.c
61
iseq.c
|
@ -43,9 +43,6 @@
|
||||||
#include "insns.inc"
|
#include "insns.inc"
|
||||||
#include "insns_info.inc"
|
#include "insns_info.inc"
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include "ujit_examples.h"
|
|
||||||
|
|
||||||
uint8_t *native_pop_code; // TODO: hack. see addr2insn
|
|
||||||
|
|
||||||
VALUE rb_cISeq;
|
VALUE rb_cISeq;
|
||||||
static VALUE iseqw_new(const rb_iseq_t *iseq);
|
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, key1, (st_data_t)&insn_data[insn]);
|
||||||
st_add_direct(rb_encoded_insn_data, key2, (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
|
int
|
||||||
|
@ -3276,12 +3227,6 @@ rb_vm_insn_addr2insn(const void *addr)
|
||||||
return (int)e->insn;
|
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);
|
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;
|
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);
|
rb_bug("trace_instrument: invalid insn address: %p", (void *)*iseq_encoded_insn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
12
ujit_asm.c
12
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
|
/// 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
|
// Write the opcode
|
||||||
cb.writeByte(0xE8);
|
cb_write_byte(cb, 0xE8);
|
||||||
|
|
||||||
// Add a reference to the label
|
// Add a reference to the label
|
||||||
cb.addLabelRef(label);
|
cb_label_ref(cb, label_idx);
|
||||||
|
|
||||||
// Relative 32-bit offset to be patched
|
// 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
|
/// call - Indirect call with an R/M operand
|
||||||
void call(codeblock_t* cb, x86opnd_t opnd)
|
void call(codeblock_t* cb, x86opnd_t opnd)
|
||||||
|
|
|
@ -194,6 +194,7 @@ void cb_write_epilogue(codeblock_t* cb);
|
||||||
|
|
||||||
// Encode individual instructions into a code block
|
// Encode individual instructions into a code block
|
||||||
void add(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1);
|
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 call(codeblock_t* cb, x86opnd_t opnd);
|
||||||
void ja(codeblock_t* cb, size_t label_idx);
|
void ja(codeblock_t* cb, size_t label_idx);
|
||||||
void jae(codeblock_t* cb, size_t label_idx);
|
void jae(codeblock_t* cb, size_t label_idx);
|
||||||
|
|
|
@ -83,12 +83,13 @@ void run_tests()
|
||||||
cb_set_pos(cb, 0); add(cb, ECX, imm_opnd(255)); check_bytes(cb, "81C1FF000000");
|
cb_set_pos(cb, 0); add(cb, ECX, imm_opnd(255)); check_bytes(cb, "81C1FF000000");
|
||||||
|
|
||||||
// call
|
// call
|
||||||
/*
|
{
|
||||||
test(
|
cb_set_pos(cb, 0);
|
||||||
delegate void (CodeBlock cb) { auto l = cb.label("foo"); cb.instr(CALL, l); },
|
size_t fn_label = cb_new_label(cb, "foo");
|
||||||
"E8FBFFFFFF"
|
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, RAX); check_bytes(cb, "FFD0");
|
||||||
cb_set_pos(cb, 0); call(cb, mem_opnd(64, RSP, 8)); check_bytes(cb, "FF542408");
|
cb_set_pos(cb, 0); call(cb, mem_opnd(64, RSP, 8)); check_bytes(cb, "FF542408");
|
||||||
|
|
||||||
|
|
|
@ -8,17 +8,12 @@
|
||||||
#include "ujit_compile.h"
|
#include "ujit_compile.h"
|
||||||
#include "ujit_asm.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 block;
|
||||||
static codeblock_t* cb = NULL;
|
static codeblock_t* cb = NULL;
|
||||||
|
|
||||||
extern uint8_t* native_pop_code; // FIXME global hack
|
|
||||||
extern st_table *rb_encoded_insn_data;
|
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
|
static void
|
||||||
addr2insn_bookkeeping(void *code_ptr, int insn)
|
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);
|
st_insert(rb_encoded_insn_data, (st_data_t)code_ptr, encoded_insn_data);
|
||||||
}
|
}
|
||||||
else {
|
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);
|
//const char* name = insn_name(insn);
|
||||||
//printf("%s\n", name);
|
//printf("%s\n", name);
|
||||||
|
|
||||||
|
// TODO: encode individual instructions, eg
|
||||||
|
// putnil, putobject, pop, dup, getlocal, nilp
|
||||||
|
|
||||||
if (insn == BIN(pop))
|
if (insn == BIN(pop))
|
||||||
{
|
{
|
||||||
// Get a pointer to the current write position in the code block
|
// Get a pointer to the current write position in the code block
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue