diff options
author | normal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2018-06-06 20:57:48 +0000 |
---|---|---|
committer | normal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2018-06-06 20:57:48 +0000 |
commit | 609939f8c6cb595eaa7d36eee030e8c10c6f6ad9 (patch) | |
tree | e6847c611729466e42797fb4eff4d175d2b6a901 /compile.c | |
parent | 0dc50688926fbd424cfa75f436fc1d59b479a1e1 (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.c | 28 |
1 files changed, 21 insertions, 7 deletions
@@ -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 */ |