summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compile.c29
-rw-r--r--eval.c2
-rw-r--r--iseq.c52
-rw-r--r--vm_core.h6
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;