ruby-changes:51389
From: normal <ko1@a...>
Date: Thu, 7 Jun 2018 05:57:54 +0900 (JST)
Subject: [ruby-changes:51389] normal:r63594 (trunk): rb_vm_insn_addr2insn: use st to perform addr2insn mapping
normal 2018-06-07 05:57:48 +0900 (Thu, 07 Jun 2018) New Revision: 63594 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=63594 Log: 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] Modified files: trunk/compile.c trunk/eval.c trunk/iseq.c trunk/vm_core.h Index: vm_core.h =================================================================== --- vm_core.h (revision 63593) +++ vm_core.h (revision 63594) @@ -144,6 +144,11 @@ void *rb_register_sigaltstack(void); https://github.com/ruby/ruby/blob/trunk/vm_core.h#L144 #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; Index: iseq.c =================================================================== --- iseq.c (revision 63593) +++ iseq.c (revision 63594) @@ -118,15 +118,7 @@ rb_iseq_free(const rb_iseq_t *iseq) https://github.com/ruby/ruby/blob/trunk/iseq.c#L118 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 Index: compile.c =================================================================== --- compile.c (revision 63593) +++ compile.c (revision 63594) @@ -11,6 +11,7 @@ https://github.com/ruby/ruby/blob/trunk/compile.c#L11 #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_ https://github.com/ruby/ruby/blob/trunk/compile.c#L756 } #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 */ Index: eval.c =================================================================== --- eval.c (revision 63593) +++ eval.c (revision 63594) @@ -66,6 +66,7 @@ ruby_setup(void) https://github.com/ruby/ruby/blob/trunk/eval.c#L66 #endif Init_BareVM(); Init_heap(); + rb_addr2insn_init(); Init_vm_objects(); EC_PUSH_TAG(GET_EC()); -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/