summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compile.c28
-rw-r--r--eval.c1
-rw-r--r--iseq.c10
-rw-r--r--vm_core.h5
4 files changed, 28 insertions, 16 deletions
diff --git a/compile.c b/compile.c
index af4e9327ad..21971830ea 100644
--- a/compile.c
+++ b/compile.c
@@ -11,6 +11,7 @@
#include "ruby/encoding.h"
#include "ruby/re.h"
+#include "ruby/util.h"
#include "internal.h"
#include "encindex.h"
#include <math.h>
@@ -755,20 +756,33 @@ rb_iseq_translate_threaded_code(rb_iseq_t *iseq)
}
#if OPT_DIRECT_THREADED_CODE || OPT_CALL_THREADED_CODE
-int
-rb_vm_insn_addr2insn(const void *addr) /* cold path */
+static st_table *addr2insn;
+
+void
+rb_addr2insn_init(void)
{
- int insn;
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++) {
- if (table[insn] == addr) {
- return 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
+#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 da3bcadb42..aff1b9021b 100644
--- a/eval.c
+++ b/eval.c
@@ -66,6 +66,7 @@ ruby_setup(void)
#endif
Init_BareVM();
Init_heap();
+ rb_addr2insn_init();
Init_vm_objects();
EC_PUSH_TAG(GET_EC());
diff --git a/iseq.c b/iseq.c
index e03f1f2a98..e5210ca750 100644
--- a/iseq.c
+++ b/iseq.c
@@ -118,15 +118,7 @@ rb_iseq_free(const rb_iseq_t *iseq)
static VALUE
rb_vm_insn_addr2insn2(const void *addr)
{
- VALUE insn;
- const void * const *table = rb_vm_get_insns_address_table();
-
- for (insn = 0; insn < VM_INSTRUCTION_SIZE; insn++) {
- if (table[insn] == addr) {
- return insn;
- }
- }
- rb_bug("rb_vm_insn_addr2insn: invalid insn address: %p", addr);
+ return (VALUE)rb_vm_insn_addr2insn(addr);
}
#endif
diff --git a/vm_core.h b/vm_core.h
index 8e34ff14a5..0a185a6ceb 100644
--- a/vm_core.h
+++ b/vm_core.h
@@ -144,6 +144,11 @@ 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
typedef unsigned long rb_num_t;
typedef signed long rb_snum_t;