[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]