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

ruby-changes:59313

From: John <ko1@a...>
Date: Wed, 18 Dec 2019 02:19:24 +0900 (JST)
Subject: [ruby-changes:59313] d7a50a5cc6 (master): Avoid revisiting seen nodes clearing method cache

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

From d7a50a5cc694ab28608a9d5a2e39c2766330ffe6 Mon Sep 17 00:00:00 2001
From: John Hawthorn <john@h...>
Date: Wed, 11 Dec 2019 13:10:39 -0800
Subject: Avoid revisiting seen nodes clearing method cache

rb_clear_method_cache_by_class calls rb_class_clear_method_cache
recursively on subclasses, where it will bump the class serial and clear
some other data (callable_m_tbl, and some mjit data).

Previously this could end up taking a long time to clear all the classes
if the module was included a few levels deep and especially if there
were multiple paths to it in the dependency tree (ie. a class includes
two modules which both include the same other module) as we end up
revisiting class/iclass/module objects multiple times.

This commit avoids revisiting the same object, by short circuiting when
revisit the same object. We can check this efficiently by comparing the
class serial of each object we visit with the next class serial at the
start. We know that any objects with a higher class serial have already
been visited.

diff --git a/vm_method.c b/vm_method.c
index 1a6b1cf..2e94814 100644
--- a/vm_method.c
+++ b/vm_method.c
@@ -62,6 +62,11 @@ static struct { https://github.com/ruby/ruby/blob/trunk/vm_method.c#L62
 static void
 rb_class_clear_method_cache(VALUE klass, VALUE arg)
 {
+    VALUE old_serial = *(rb_serial_t *)arg;
+    if (RCLASS_SERIAL(klass) > old_serial) {
+        return;
+    }
+
     mjit_remove_class_serial(RCLASS_SERIAL(klass));
     RCLASS_SERIAL(klass) = rb_next_class_serial();
 
@@ -99,7 +104,8 @@ rb_clear_method_cache_by_class(VALUE klass) https://github.com/ruby/ruby/blob/trunk/vm_method.c#L104
 	    INC_GLOBAL_METHOD_STATE();
 	}
 	else {
-	    rb_class_clear_method_cache(klass, Qnil);
+	    rb_serial_t old_serial = rb_next_class_serial();
+	    rb_class_clear_method_cache(klass, (VALUE)&old_serial);
 	}
     }
 
-- 
cgit v0.10.2


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

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