summaryrefslogtreecommitdiff
path: root/compile.c
diff options
context:
space:
mode:
authornormal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-06-06 20:57:48 (GMT)
committernormal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-06-06 20:57:48 (GMT)
commit609939f8c6cb595eaa7d36eee030e8c10c6f6ad9 (patch)
treee6847c611729466e42797fb4eff4d175d2b6a901 /compile.c
parent0dc50688926fbd424cfa75f436fc1d59b479a1e1 (diff)
rb_vm_insn_addr2insn: use st to perform addr2insn mapping
The current VM_INSTRUCTION_SIZE is 198, so the linear search painful during a major GC phase. I noticed rb_vm_insn_addr2insn2 showing up at the top of some profiles while working on some malloc-related stuff, so I decided to attack it. Most notably, the benchmark/bm_vm3_gc.rb improves by over 40%: https://80x24.org/spew/20180602220554.GA9991@whir/raw [ruby-core:87361] [Feature #14814] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63594 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'compile.c')
-rw-r--r--compile.c28
1 files changed, 21 insertions, 7 deletions
diff --git a/compile.c b/compile.c
index af4e932..2197183 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 */