diff options
author | mame <mame@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2018-08-23 08:32:30 +0000 |
---|---|---|
committer | mame <mame@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2018-08-23 08:32:30 +0000 |
commit | d574683c40d42c1ec834c99c2717cbd8de442353 (patch) | |
tree | 1fcdc749e929fe7d036d1dd6a8e969041e669792 | |
parent | bf6e2eb7e7ca144dc8a71d87d36edb0d852519a2 (diff) |
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
-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; |