Last active
January 2, 2016 21:09
-
-
Save headius/8361960 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
BEFORE interpreted: | |
user system total real | |
control, 1 and :to_ary 0.070000 0.000000 0.070000 ( 0.068000) | |
1m 1.respond_to?(:to_ary) 0.130000 0.000000 0.130000 ( 0.126000) | |
1m 1.respond_to?(:to_ary,true) 0.120000 0.000000 0.120000 ( 0.122000) | |
1m 1.respond_to?(:next) 0.100000 0.000000 0.100000 ( 0.093000) | |
1m redefined obj.respond_to? 0.130000 0.000000 0.130000 ( 0.135000) | |
1m varying name respond_to? 0.280000 0.010000 0.290000 ( 0.272000) | |
BEFORE compiled: | |
user system total real | |
control, 1 and :to_ary 0.040000 0.000000 0.040000 ( 0.037000) | |
1m 1.respond_to?(:to_ary) 0.110000 0.000000 0.110000 ( 0.108000) | |
1m 1.respond_to?(:to_ary,true) 0.110000 0.000000 0.110000 ( 0.109000) | |
1m 1.respond_to?(:next) 0.070000 0.000000 0.070000 ( 0.072000) | |
1m redefined obj.respond_to? 0.060000 0.000000 0.060000 ( 0.059000) | |
1m varying name respond_to? 0.060000 0.000000 0.060000 ( 0.059000) | |
AFTER interpreted: | |
user system total real | |
control, 1 and :to_ary 0.070000 0.000000 0.070000 ( 0.069000) | |
1m 1.respond_to?(:to_ary) 0.060000 0.000000 0.060000 ( 0.063000) | |
1m 1.respond_to?(:to_ary,true) 0.070000 0.000000 0.070000 ( 0.061000) | |
1m 1.respond_to?(:next) 0.060000 0.000000 0.060000 ( 0.065000) | |
1m redefined obj.respond_to? 0.130000 0.000000 0.130000 ( 0.131000) | |
1m varying name respond_to? 0.250000 0.000000 0.250000 ( 0.250000) | |
AFTER compiled: | |
user system total real | |
control, 1 and :to_ary 0.040000 0.000000 0.040000 ( 0.035000) | |
1m 1.respond_to?(:to_ary) 0.050000 0.000000 0.050000 ( 0.050000) | |
1m 1.respond_to?(:to_ary,true) 0.050000 0.000000 0.050000 ( 0.050000) | |
1m 1.respond_to?(:next) 0.050000 0.000000 0.050000 ( 0.045000) | |
1m redefined obj.respond_to? 0.060000 0.000000 0.060000 ( 0.063000) | |
1m varying name respond_to? 0.070000 0.000000 0.070000 ( 0.071000) | |
1m varying name respond_to? 0.060000 0.000000 0.060000 ( 0.058000) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/core/src/main/java/org/jruby/Ruby.java b/core/src/main/java/org/jruby/Ruby.java | |
index f780f2c..3f5a16b 100644 | |
--- a/core/src/main/java/org/jruby/Ruby.java | |
+++ b/core/src/main/java/org/jruby/Ruby.java | |
@@ -1849,6 +1849,14 @@ public final class Ruby { | |
public void setRespondToMethod(DynamicMethod rtm) { | |
this.respondTo = rtm; | |
} | |
+ | |
+ public DynamicMethod getRespondToMissingMethod() { | |
+ return respondToMissing; | |
+ } | |
+ | |
+ public void setRespondToMissingMethod(DynamicMethod rtmm) { | |
+ this.respondToMissing = rtmm; | |
+ } | |
public RubyClass getDummy() { | |
return dummyClass; | |
@@ -4695,7 +4703,7 @@ public final class Ruby { | |
procSysModule, precisionModule, errnoModule; | |
private DynamicMethod privateMethodMissing, protectedMethodMissing, variableMethodMissing, | |
- superMethodMissing, normalMethodMissing, defaultMethodMissing, respondTo; | |
+ superMethodMissing, normalMethodMissing, defaultMethodMissing, respondTo, respondToMissing; | |
// record separator var, to speed up io ops that use it | |
private GlobalVariable recordSeparatorVar; | |
diff --git a/core/src/main/java/org/jruby/RubyKernel.java b/core/src/main/java/org/jruby/RubyKernel.java | |
index 31bf0b8..0c4f15b 100644 | |
--- a/core/src/main/java/org/jruby/RubyKernel.java | |
+++ b/core/src/main/java/org/jruby/RubyKernel.java | |
@@ -164,6 +164,7 @@ public class RubyKernel { | |
RubyModule module = runtime.getKernel(); | |
runtime.setRespondToMethod(module.searchMethod("respond_to?")); | |
+ runtime.setRespondToMissingMethod(module.searchMethod("respond_to_missing?")); | |
} | |
@JRubyMethod(module = true, visibility = PRIVATE) | |
diff --git a/core/src/main/java/org/jruby/compiler/impl/InvokeDynamicInvocationCompiler.java b/core/src/main/java/org/jruby/compiler/impl/InvokeDynamicInvocationCompiler.java | |
index 15f0bd9..51762ba 100644 | |
--- a/core/src/main/java/org/jruby/compiler/impl/InvokeDynamicInvocationCompiler.java | |
+++ b/core/src/main/java/org/jruby/compiler/impl/InvokeDynamicInvocationCompiler.java | |
@@ -98,10 +98,17 @@ public class InvokeDynamicInvocationCompiler extends StandardInvocationCompiler | |
@Override | |
public void invokeDynamic(String name, CompilerCallback receiverCallback, ArgumentsCallback argsCallback, CallType callType, CompilerCallback closureArg, boolean iterator) { | |
+ // super calls do not optimize in indy right now | |
if (callType == CallType.SUPER) { | |
super.invokeDynamic(name, receiverCallback, argsCallback, callType, closureArg, iterator); | |
return; | |
} | |
+ | |
+ // respond_to? calls do not optimize in indy right now | |
+ if (name.equals("respond_to?")) { | |
+ super.invokeDynamic(name, receiverCallback, argsCallback, callType, closureArg, iterator); | |
+ return; | |
+ } | |
methodCompiler.loadThreadContext(); // [adapter, tc] | |
diff --git a/core/src/main/java/org/jruby/runtime/callsite/RespondToCallSite.java b/core/src/main/java/org/jruby/runtime/callsite/RespondToCallSite.java | |
index 202a6ac..ba61e75 100644 | |
--- a/core/src/main/java/org/jruby/runtime/callsite/RespondToCallSite.java | |
+++ b/core/src/main/java/org/jruby/runtime/callsite/RespondToCallSite.java | |
@@ -68,13 +68,16 @@ public class RespondToCallSite extends NormalCachingCallSite { | |
} | |
// alternate logic to cache the result of respond_to if it's the standard one | |
- // FIXME: 1.9's respond_to_missing breaks this, so we have to bail out | |
- if (false && | |
- entry.method.equals(context.runtime.getRespondToMethod())) { | |
+ if (entry.method.equals(context.runtime.getRespondToMethod())) { | |
String name = arg.asJavaString(); | |
RespondToTuple tuple = recacheRespondsTo(entry, name, selfType, true, context); | |
- respondToTuple = tuple; | |
- return tuple.respondsTo; | |
+ | |
+ // only cache if it does respond_to? or there's no custom respond_to_missing? logic | |
+ if (tuple.respondsTo.isTrue() || | |
+ selfType.searchWithCache("respond_to_missing?").method == context.runtime.getRespondToMissingMethod()) { | |
+ respondToTuple = tuple; | |
+ return tuple.respondsTo; | |
+ } | |
} | |
// normal logic if it's not the builtin respond_to? method | |
@@ -91,14 +94,16 @@ public class RespondToCallSite extends NormalCachingCallSite { | |
} | |
// alternate logic to cache the result of respond_to if it's the standard one | |
- // FIXME: 1.9's respond_to_missing breaks this, so we have to bail out | |
- // FIXME: 1.9's respond_to_missing breaks this, so we have to bail out | |
- if (false && | |
- entry.method.equals(context.runtime.getRespondToMethod())) { | |
+ if (entry.method.equals(context.runtime.getRespondToMethod())) { | |
String name = arg0.asJavaString(); | |
RespondToTuple tuple = recacheRespondsTo(entry, name, selfType, !arg1.isTrue(), context); | |
- respondToTuple = tuple; | |
- return tuple.respondsTo; | |
+ | |
+ // only cache if it does respond_to? or there's no custom respond_to_missing? logic | |
+ if (tuple.respondsTo.isTrue() || | |
+ selfType.searchWithCache("respond_to_missing?").method == context.runtime.getRespondToMissingMethod()) { | |
+ respondToTuple = tuple; | |
+ return tuple.respondsTo; | |
+ } | |
} | |
// normal logic if it's not the builtin respond_to? method |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment