diff options
-rw-r--r-- | compile.c | 29 | ||||
-rw-r--r-- | eval.c | 2 | ||||
-rw-r--r-- | iseq.c | 52 | ||||
-rw-r--r-- | vm_core.h | 6 |
4 files changed, 54 insertions, 35 deletions
@@ -746,35 +746,6 @@ rb_iseq_translate_threaded_code(rb_iseq_t *iseq) return COMPILE_OK; } -#if OPT_DIRECT_THREADED_CODE || OPT_CALL_THREADED_CODE -static st_table *addr2insn; - -void -rb_addr2insn_init(void) -{ - const void * const *table = rb_vm_get_insns_address_table(); - st_data_t insn; - - addr2insn = st_init_numtable_with_size(VM_INSTRUCTION_SIZE); - for (insn = 0; insn < VM_INSTRUCTION_SIZE; insn++) { - st_add_direct(addr2insn, (st_data_t)table[insn], insn); - } -} - -int -rb_vm_insn_addr2insn(const void *addr) -{ - st_data_t key = (st_data_t)addr; - st_data_t val; - - if (st_lookup(addr2insn, key, &val)) { - return (int)val; - } - - rb_bug("rb_vm_insn_addr2insn: invalid insn address: %p", addr); -} -#endif /* OPT_DIRECT_THREADED_CODE || OPT_CALL_THREADED_CODE */ - VALUE * rb_iseq_original_iseq(const rb_iseq_t *iseq) /* cold path */ { @@ -66,7 +66,7 @@ ruby_setup(void) #endif Init_BareVM(); Init_heap(); - rb_addr2insn_init(); + rb_vm_encoded_insn_data_table_init(); Init_vm_objects(); EC_PUSH_TAG(GET_EC()); @@ -2862,6 +2862,58 @@ rb_iseq_defined_string(enum defined_type type) return str; } +/* 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; +typedef struct insn_data_struct { + int insn; + int insn_len; + void *notrace_encoded_insn; + void *trace_encoded_insn; +} insn_data_t; +static insn_data_t insn_data[VM_INSTRUCTION_SIZE/2]; + +void +rb_vm_encoded_insn_data_table_init(void) +{ +#if OPT_DIRECT_THREADED_CODE || OPT_CALL_THREADED_CODE + const void * const *table = rb_vm_get_insns_address_table(); +#define INSN_CODE(insn) ((VALUE)table[insn]) +#else +#define INSN_CODE(insn) (insn) +#endif + st_data_t insn; + 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); + st_data_t key2 = (st_data_t)INSN_CODE(insn + VM_INSTRUCTION_SIZE/2); + + insn_data[insn].insn = insn; + insn_data[insn].insn_len = insn_len(insn); + insn_data[insn].notrace_encoded_insn = (void *) key1; + insn_data[insn].trace_encoded_insn = (void *) key2; + + 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]); + } +} + +int +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)) { + insn_data_t *e = (insn_data_t *)val; + return (int)e->insn; + } + + rb_bug("rb_vm_insn_addr2insn: invalid insn address: %p", addr); +} + #define TRACE_INSN_P(insn) ((insn) >= VM_INSTRUCTION_SIZE/2) @@ -164,11 +164,7 @@ void *rb_register_sigaltstack(void); #endif /* OPT_STACK_CACHING */ #endif /* OPT_CALL_THREADED_CODE */ -#if OPT_DIRECT_THREADED_CODE || OPT_CALL_THREADED_CODE -void rb_addr2insn_init(void); -#else -static inline void rb_addr2insn_init(void) { } -#endif +void rb_vm_encoded_insn_data_table_init(void); typedef unsigned long rb_num_t; typedef signed long rb_snum_t; |