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
This commit is contained in:
parent
bf6e2eb7e7
commit
d574683c40
29
compile.c
29
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 */
|
||||
{
|
||||
|
2
eval.c
2
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());
|
||||
|
52
iseq.c
52
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)
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user