From 4929ba0a5ce2ea697bad4b8a33ce6047e99da04a Mon Sep 17 00:00:00 2001 From: Alan Wu Date: Fri, 11 Sep 2020 14:58:32 -0400 Subject: [PATCH] Generate multiple copies of native code for `pop` Insert generated addresses into st_table for mapping native code addresses back to info about VM instructions. Export `encoded_insn_data` to do this. Also some style fixes. --- compile.c | 2 +- iseq.c | 12 ++++++------ ujit_compile.c | 29 +++++++++++++++++++++-------- 3 files changed, 28 insertions(+), 15 deletions(-) diff --git a/compile.c b/compile.c index dd19fe2736..192a1a3026 100644 --- a/compile.c +++ b/compile.c @@ -875,7 +875,7 @@ rb_iseq_translate_threaded_code(rb_iseq_t *iseq) if (native_code_ptr) encoded[i] = (VALUE)native_code_ptr; else - encoded[i] = (VALUE)table[insn]; + encoded[i] = (VALUE)table[insn]; i += len; } diff --git a/iseq.c b/iseq.c index 51d923cf8e..15e888670a 100644 --- a/iseq.c +++ b/iseq.c @@ -3169,7 +3169,7 @@ rb_iseq_defined_string(enum defined_type type) /* A map from encoded_insn to insn_data: decoded insn number, its len, * non-trace version of encoded insn, and trace version. */ -static st_table *encoded_insn_data; +st_table *rb_encoded_insn_data; typedef struct insn_data_struct { int insn; int insn_len; @@ -3196,7 +3196,7 @@ rb_vm_encoded_insn_data_table_init(void) #define INSN_CODE(insn) (insn) #endif st_data_t insn; - encoded_insn_data = st_init_numtable_with_size(VM_INSTRUCTION_SIZE / 2); + rb_encoded_insn_data = st_init_numtable_with_size(VM_INSTRUCTION_SIZE / 2); for (insn = 0; insn < VM_INSTRUCTION_SIZE/2; insn++) { st_data_t key1 = (st_data_t)INSN_CODE(insn); @@ -3214,8 +3214,8 @@ rb_vm_encoded_insn_data_table_init(void) insn_data[insn].trace_encoded_insn = (void *) INSN_CODE(BIN(opt_invokebuiltin_delegate) + VM_INSTRUCTION_SIZE/2); } - st_add_direct(encoded_insn_data, key1, (st_data_t)&insn_data[insn]); - st_add_direct(encoded_insn_data, key2, (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]); } @@ -3271,7 +3271,7 @@ rb_vm_insn_addr2insn(const void *addr) st_data_t key = (st_data_t)addr; st_data_t val; - if (st_lookup(encoded_insn_data, key, &val)) { + if (st_lookup(rb_encoded_insn_data, key, &val)) { insn_data_t *e = (insn_data_t *)val; return (int)e->insn; } @@ -3303,7 +3303,7 @@ encoded_iseq_trace_instrument(VALUE *iseq_encoded_insn, rb_event_flag_t turnon, st_data_t key = (st_data_t)*iseq_encoded_insn; st_data_t val; - if (st_lookup(encoded_insn_data, key, &val)) { + if (st_lookup(rb_encoded_insn_data, key, &val)) { insn_data_t *e = (insn_data_t *)val; if (remain_current_trace && key == (st_data_t)e->trace_encoded_insn) { turnon = 1; diff --git a/ujit_compile.c b/ujit_compile.c index 9ed2cc7727..d34d45fea1 100644 --- a/ujit_compile.c +++ b/ujit_compile.c @@ -16,10 +16,27 @@ 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 +static void +addr2insn_bookkeeping(void *code_ptr, int insn) +{ + const void * const *table = rb_vm_get_insns_address_table(); + const void * const translated_address = table[insn]; + st_data_t encoded_insn_data; + if (st_lookup(rb_encoded_insn_data, (st_data_t)translated_address, &encoded_insn_data)) { + 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"); + } +} // 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) +uint8_t * +ujit_compile_insn(rb_iseq_t *iseq, size_t insn_idx) { // Allocate the code block if not previously allocated if (!cb) @@ -29,18 +46,13 @@ uint8_t* ujit_compile_insn(rb_iseq_t *iseq, size_t insn_idx) cb_init(cb, 4000000); } - int insn = (int)iseq->body->iseq_encoded[insn_idx]; + 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]; @@ -55,8 +67,9 @@ uint8_t* ujit_compile_insn(rb_iseq_t *iseq, size_t insn_idx) // Write the post call bytes cb_write_epilogue(cb); + addr2insn_bookkeeping(code_ptr, insn); + return code_ptr; - */ } return 0;