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;
|
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 *
|
VALUE *
|
||||||
rb_iseq_original_iseq(const rb_iseq_t *iseq) /* cold path */
|
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
|
#endif
|
||||||
Init_BareVM();
|
Init_BareVM();
|
||||||
Init_heap();
|
Init_heap();
|
||||||
rb_addr2insn_init();
|
rb_vm_encoded_insn_data_table_init();
|
||||||
Init_vm_objects();
|
Init_vm_objects();
|
||||||
|
|
||||||
EC_PUSH_TAG(GET_EC());
|
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;
|
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)
|
#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_STACK_CACHING */
|
||||||
#endif /* OPT_CALL_THREADED_CODE */
|
#endif /* OPT_CALL_THREADED_CODE */
|
||||||
|
|
||||||
#if OPT_DIRECT_THREADED_CODE || OPT_CALL_THREADED_CODE
|
void rb_vm_encoded_insn_data_table_init(void);
|
||||||
void rb_addr2insn_init(void);
|
|
||||||
#else
|
|
||||||
static inline void rb_addr2insn_init(void) { }
|
|
||||||
#endif
|
|
||||||
typedef unsigned long rb_num_t;
|
typedef unsigned long rb_num_t;
|
||||||
typedef signed long rb_snum_t;
|
typedef signed long rb_snum_t;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user