From d574683c40d42c1ec834c99c2717cbd8de442353 Mon Sep 17 00:00:00 2001 From: mame Date: Thu, 23 Aug 2018 08:32:30 +0000 Subject: iseq.c: add a map from encoded insn to insn data This enhances rb_vm_insn_addr2insn which retrieves a decoded insn number from encoded insn. The insn data table include not only decoded insn number, but also its len, trace and non-trace version of encoded insn. This table can be used to simplify trace instrumentation. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64518 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- compile.c | 29 ----------------------------- eval.c | 2 +- iseq.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ vm_core.h | 6 +----- 4 files changed, 54 insertions(+), 35 deletions(-) diff --git a/compile.c b/compile.c index 0e7153f6e7..71fecf1069 100644 --- a/compile.c +++ b/compile.c @@ -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 */ { diff --git a/eval.c b/eval.c index 2aa7de46ed..35255e0975 100644 --- a/eval.c +++ b/eval.c @@ -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()); diff --git a/iseq.c b/iseq.c index cbd216089e..424771c738 100644 --- a/iseq.c +++ b/iseq.c @@ -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) diff --git a/vm_core.h b/vm_core.h index 1e27e7f839..bb6409719b 100644 --- a/vm_core.h +++ b/vm_core.h @@ -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; -- cgit v1.2.3