Index: src/compiler/js-generic-lowering.cc |
diff --git a/src/compiler/js-generic-lowering.cc b/src/compiler/js-generic-lowering.cc |
index 11979ec6edc9ea800980354a4ca70521fe7bddaa..92594af8b64e67488b0f3f1782f3ee8cbff5071e 100644 |
--- a/src/compiler/js-generic-lowering.cc |
+++ b/src/compiler/js-generic-lowering.cc |
@@ -9,6 +9,7 @@ |
#include "src/compiler/js-generic-lowering.h" |
#include "src/compiler/machine-operator.h" |
#include "src/compiler/node-aux-data-inl.h" |
+#include "src/compiler/node-matchers.h" |
#include "src/compiler/node-properties-inl.h" |
#include "src/unique.h" |
@@ -405,9 +406,40 @@ void JSGenericLowering::LowerJSCallConstruct(Node* node) { |
} |
+static Node* ReuseContextIfPossible(JSGraph* jsgraph, |
+ Handle<JSFunction> function, |
+ Node* maybe_the_right_one) { |
+ // TODO(titzer): total hack to share function context constants. |
+ // Remove this when the JSGraph canonicalizes heap constants. |
+ HeapObjectMatcher<Context> context(maybe_the_right_one); |
+ if (context.HasValue() && |
+ *(context.Value().handle()) == function->context()) { |
+ return maybe_the_right_one; |
+ } |
+ return jsgraph->HeapConstant(Handle<Context>(function->context())); |
+} |
+ |
+ |
void JSGenericLowering::LowerJSCallFunction(Node* node) { |
const CallFunctionParameters& p = CallFunctionParametersOf(node->op()); |
- CallFunctionStub stub(isolate(), static_cast<int>(p.arity() - 2), p.flags()); |
+ int argument_count = static_cast<int>(p.arity() - 2); |
+ HeapObjectMatcher<JSFunction> func(node->InputAt(0)); |
+ if (func.HasValue()) { |
Michael Starzinger
2014/10/31 12:28:06
suggestion: How would you feel about moving this o
|
+ // Call to a constant JSFunction. Skip CallFunctionStub if arity matches. |
+ Handle<JSFunction> function = func.Value().handle(); |
+ if (argument_count == function->shared()->formal_parameter_count()) { |
+ int index = NodeProperties::FirstContextIndex(node); |
+ Node* context = |
+ ReuseContextIfPossible(jsgraph(), function, node->InputAt(index)); |
+ node->ReplaceInput(index, context); |
+ CallDescriptor* desc = linkage()->GetJSCallDescriptor( |
+ 1 + argument_count, jsgraph()->zone(), FlagsForNode(node)); |
+ PatchOperator(node, common()->Call(desc)); |
+ return; |
+ } |
+ } |
+ // Call to computed function; use CallFunctionStub; |
+ CallFunctionStub stub(isolate(), argument_count, p.flags()); |
CallInterfaceDescriptor d = stub.GetCallInterfaceDescriptor(); |
CallDescriptor* desc = linkage()->GetStubCallDescriptor( |
d, static_cast<int>(p.arity() - 1), FlagsForNode(node)); |