mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
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
This commit is contained in:
parent
0dc5068892
commit
609939f8c6
4 changed files with 30 additions and 18 deletions
30
compile.c
30
compile.c
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
#include "ruby/encoding.h"
|
#include "ruby/encoding.h"
|
||||||
#include "ruby/re.h"
|
#include "ruby/re.h"
|
||||||
|
#include "ruby/util.h"
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
#include "encindex.h"
|
#include "encindex.h"
|
||||||
#include <math.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
|
#if OPT_DIRECT_THREADED_CODE || OPT_CALL_THREADED_CODE
|
||||||
int
|
static st_table *addr2insn;
|
||||||
rb_vm_insn_addr2insn(const void *addr) /* cold path */
|
|
||||||
{
|
|
||||||
int insn;
|
|
||||||
const void * const *table = rb_vm_get_insns_address_table();
|
|
||||||
|
|
||||||
|
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++) {
|
for (insn = 0; insn < VM_INSTRUCTION_SIZE; insn++) {
|
||||||
if (table[insn] == addr) {
|
st_add_direct(addr2insn, (st_data_t)table[insn], insn);
|
||||||
return 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);
|
rb_bug("rb_vm_insn_addr2insn: invalid insn address: %p", addr);
|
||||||
}
|
}
|
||||||
#endif
|
#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 */
|
||||||
|
|
1
eval.c
1
eval.c
|
@ -66,6 +66,7 @@ ruby_setup(void)
|
||||||
#endif
|
#endif
|
||||||
Init_BareVM();
|
Init_BareVM();
|
||||||
Init_heap();
|
Init_heap();
|
||||||
|
rb_addr2insn_init();
|
||||||
Init_vm_objects();
|
Init_vm_objects();
|
||||||
|
|
||||||
EC_PUSH_TAG(GET_EC());
|
EC_PUSH_TAG(GET_EC());
|
||||||
|
|
10
iseq.c
10
iseq.c
|
@ -118,15 +118,7 @@ rb_iseq_free(const rb_iseq_t *iseq)
|
||||||
static VALUE
|
static VALUE
|
||||||
rb_vm_insn_addr2insn2(const void *addr)
|
rb_vm_insn_addr2insn2(const void *addr)
|
||||||
{
|
{
|
||||||
VALUE insn;
|
return (VALUE)rb_vm_insn_addr2insn(addr);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -144,6 +144,11 @@ 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_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…
Add table
Add a link
Reference in a new issue