aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--benchmark/bm_vm2_poly_singleton.rb14
-rw-r--r--class.c2
3 files changed, 22 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index 83800b1b8a..7eabe4460e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+Tue Sep 13 00:39:47 2016 Aaron Patterson <tenderlove@ruby-lang.org>
+
+ * class.c (singleton_class_of): Copy superclass serial number to
+ singleton class. This improves singleton class IMC hit rates.
+ [Feature #12364] [ruby-core:75425]
+
Mon Sep 12 13:46:23 2016 Anton Davydov <mail@davydovanton.com>
* lib/uri/mailto.rb: Removed needless `return` and use `.`` instead of `::`
diff --git a/benchmark/bm_vm2_poly_singleton.rb b/benchmark/bm_vm2_poly_singleton.rb
new file mode 100644
index 0000000000..0dba4320c4
--- /dev/null
+++ b/benchmark/bm_vm2_poly_singleton.rb
@@ -0,0 +1,14 @@
+class C1
+ def m; 1; end
+end
+
+o1 = C1.new
+o2 = C1.new
+o2.singleton_class
+
+i = 0
+while i<6_000_000 # benchmark loop 2
+ o = (i % 2 == 0) ? o1 : o2
+ o.m; o.m; o.m; o.m; o.m; o.m; o.m; o.m
+ i += 1
+end
diff --git a/class.c b/class.c
index 6c7dfa5c17..ce2ede5c2b 100644
--- a/class.c
+++ b/class.c
@@ -1591,7 +1591,9 @@ singleton_class_of(VALUE obj)
klass = RBASIC(obj)->klass;
if (!(FL_TEST(klass, FL_SINGLETON) &&
rb_ivar_get(klass, id_attached) == obj)) {
+ rb_serial_t serial = RCLASS_SERIAL(klass);
klass = rb_make_metaclass(obj, klass);
+ RCLASS_SERIAL(klass) = serial;
}
if (OBJ_TAINTED(obj)) {