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

ruby-changes:59317

From: John <ko1@a...>
Date: Wed, 18 Dec 2019 04:47:25 +0900 (JST)
Subject: [ruby-changes:59317] 254477248c (master): Skip optimized method check for most method IDs

https://git.ruby-lang.org/ruby.git/commit/?id=254477248c

From 254477248cde5bf82c4f256dca05b13d01c9774c Mon Sep 17 00:00:00 2001
From: John Hawthorn <john@h...>
Date: Thu, 12 Dec 2019 15:47:59 -0800
Subject: Skip optimized method check for most method IDs

Previously every time a method was defined on a module, we would
recursively walk all subclasses to see if the module was included in a
class which the VM optimizes for (such as Integer#+).

For most method definitions we can tell immediately that this won't be
the case based on the method's name. To do this we just keep a hash with
method IDs of optimized methods and if our new method isn't in that list
we don't need to check subclasses at all.

diff --git a/internal.h b/internal.h
index 3bd95c2..fe2b028 100644
--- a/internal.h
+++ b/internal.h
@@ -2282,6 +2282,7 @@ const char *rb_source_location_cstr(int *pline); https://github.com/ruby/ruby/blob/trunk/internal.h#L2282
 MJIT_STATIC void rb_vm_pop_cfunc_frame(void);
 int rb_vm_add_root_module(ID id, VALUE module);
 void rb_vm_check_redefinition_by_prepend(VALUE klass);
+int rb_vm_check_optimizable_mid(VALUE mid);
 VALUE rb_yield_refine_block(VALUE refinement, VALUE refinements);
 MJIT_STATIC VALUE ruby_vm_special_exception_copy(VALUE);
 PUREFUNC(st_table *rb_vm_fstring_table(void));
diff --git a/vm.c b/vm.c
index 9a4147a..8c0f05b 100644
--- a/vm.c
+++ b/vm.c
@@ -1557,6 +1557,7 @@ rb_iter_break_value(VALUE val) https://github.com/ruby/ruby/blob/trunk/vm.c#L1557
 /* optimization: redefine management */
 
 static st_table *vm_opt_method_table = 0;
+static st_table *vm_opt_mid_table = 0;
 
 static int
 vm_redefinition_check_flag(VALUE klass)
@@ -1576,6 +1577,16 @@ vm_redefinition_check_flag(VALUE klass) https://github.com/ruby/ruby/blob/trunk/vm.c#L1577
     return 0;
 }
 
+int
+rb_vm_check_optimizable_mid(VALUE mid)
+{
+    if (!vm_opt_mid_table) {
+      return FALSE;
+    }
+
+    return st_lookup(vm_opt_mid_table, mid, NULL);
+}
+
 static int
 vm_redefinition_check_method_type(const rb_method_definition_t *def)
 {
@@ -1630,6 +1641,7 @@ add_opt_method(VALUE klass, ID mid, VALUE bop) https://github.com/ruby/ruby/blob/trunk/vm.c#L1641
 
     if (me && vm_redefinition_check_method_type(me->def)) {
 	st_insert(vm_opt_method_table, (st_data_t)me, (st_data_t)bop);
+	st_insert(vm_opt_mid_table, (st_data_t)mid, (st_data_t)Qtrue);
     }
     else {
 	rb_bug("undefined optimized method: %s", rb_id2name(mid));
@@ -1643,6 +1655,7 @@ vm_init_redefined_flag(void) https://github.com/ruby/ruby/blob/trunk/vm.c#L1655
     VALUE bop;
 
     vm_opt_method_table = st_init_numtable();
+    vm_opt_mid_table = st_init_numtable();
 
 #define OP(mid_, bop_) (mid = id##mid_, bop = BOP_##bop_, ruby_vm_redefined_flag[bop] = 0)
 #define C(k) add_opt_method(rb_c##k, mid, bop)
diff --git a/vm_method.c b/vm_method.c
index bcf6b0b..d2bd677 100644
--- a/vm_method.c
+++ b/vm_method.c
@@ -500,7 +500,7 @@ rb_add_refined_method_entry(VALUE refined_class, ID mid) https://github.com/ruby/ruby/blob/trunk/vm_method.c#L500
 }
 
 static void
-check_override_opt_method(VALUE klass, VALUE arg)
+check_override_opt_method_i(VALUE klass, VALUE arg)
 {
     ID mid = (ID)arg;
     const rb_method_entry_t *me, *newme;
@@ -512,7 +512,15 @@ check_override_opt_method(VALUE klass, VALUE arg) https://github.com/ruby/ruby/blob/trunk/vm_method.c#L512
 	    if (newme != me) rb_vm_check_redefinition_opt_method(me, me->owner);
 	}
     }
-    rb_class_foreach_subclass(klass, check_override_opt_method, (VALUE)mid);
+    rb_class_foreach_subclass(klass, check_override_opt_method_i, (VALUE)mid);
+}
+
+static void
+check_override_opt_method(VALUE klass, VALUE mid)
+{
+    if (rb_vm_check_optimizable_mid(mid)) {
+        check_override_opt_method_i(klass, mid);
+    }
 }
 
 /*
-- 
cgit v0.10.2


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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