Skip to content

Instantly share code, notes, and snippets.

@bmeurer
Last active April 22, 2019 20:11
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save bmeurer/4916fc2b983acc9ee1d33f5ee1ada1d3 to your computer and use it in GitHub Desktop.
Save bmeurer/4916fc2b983acc9ee1d33f5ee1ada1d3 to your computer and use it in GitHub Desktop.
if (typeof console === 'undefined') console = {log:print};
const TESTS = [];
function foo(x) {
"use strict";
return x;
}
(function() {
TESTS.push(
function callUnderApplication() {
foo();
foo();
foo();
foo();
foo();
foo();
foo();
foo();
},
function callOverApplication1() {
foo(null, null);
foo(null, null);
foo(null, null);
foo(null, null);
foo(null, null);
foo(null, null);
foo(null, null);
foo(null, null);
},
function callOverApplication2() {
foo(null, null, null);
foo(null, null, null);
foo(null, null, null);
foo(null, null, null);
foo(null, null, null);
foo(null, null, null);
foo(null, null, null);
foo(null, null, null);
}
);
})();
const N = 1e7;
function test(fn) {
var result;
for (var i = 0; i < N; ++i) {
result = fn();
}
return result;
}
test(x => x); // Pollute call feedback early on.
for (var j = 0; j < TESTS.length; ++j) {
test(TESTS[j]);
}
for (var j = 0; j < TESTS.length; ++j) {
var startTime = Date.now();
test(TESTS[j]);
console.log(`${TESTS[j].name}: ${Date.now() - startTime} ms.`);
}
// Copyright 2013-2019 Benedikt Meurer
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// <https://www.apache.org/licenses/LICENSE-2.0>
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
if (typeof console === 'undefined') console = {log:print};
const TESTS = [];
function foo(x) {
"use strict";
return x;
}
(function() {
TESTS.push(
function callUnderApplication() {
foo();
foo();
foo();
foo();
foo();
foo();
foo();
foo();
},
function callProperApplication() {
foo(null);
foo(null);
foo(null);
foo(null);
foo(null);
foo(null);
foo(null);
foo(null);
},
function callOverApplication1() {
foo(null, null);
foo(null, null);
foo(null, null);
foo(null, null);
foo(null, null);
foo(null, null);
foo(null, null);
foo(null, null);
},
function callOverApplication2() {
foo(null, null, null);
foo(null, null, null);
foo(null, null, null);
foo(null, null, null);
foo(null, null, null);
foo(null, null, null);
foo(null, null, null);
foo(null, null, null);
}
);
})();
const N = 1e7;
function test(fn) {
var result;
for (var i = 0; i < N; ++i) {
result = fn();
}
return result;
}
test(x => x); // Pollute call feedback early on.
for (var j = 0; j < TESTS.length; ++j) {
test(TESTS[j]);
}
for (var j = 0; j < TESTS.length; ++j) {
var startTime = Date.now();
test(TESTS[j]);
console.log(`${TESTS[j].name}: ${Date.now() - startTime} ms.`);
}
diff --git a/src/compiler/js-typed-lowering.cc b/src/compiler/js-typed-lowering.cc
index 22139d941c..273f22bf79 100644
--- a/src/compiler/js-typed-lowering.cc
+++ b/src/compiler/js-typed-lowering.cc
@@ -1612,7 +1612,7 @@ Reduction JSTypedLowering::ReduceJSCallForwardVarargs(Node* node) {
Reduction JSTypedLowering::ReduceJSCall(Node* node) {
DCHECK_EQ(IrOpcode::kJSCall, node->opcode());
CallParameters const& p = CallParametersOf(node->op());
- int const arity = static_cast<int>(p.arity() - 2);
+ int arity = static_cast<int>(p.arity() - 2);
ConvertReceiverMode convert_mode = p.convert_mode();
Node* target = NodeProperties::GetValueInput(node, 0);
Type target_type = NodeProperties::GetType(target);
@@ -1673,18 +1673,28 @@ Reduction JSTypedLowering::ReduceJSCall(Node* node) {
Node* argument_count = jsgraph()->Constant(arity);
if (NeedsArgumentAdaptorFrame(shared, arity)) {
- // Patch {node} to an indirect call via the ArgumentsAdaptorTrampoline.
- Callable callable = CodeFactory::ArgumentAdaptor(isolate());
- node->InsertInput(graph()->zone(), 0,
- jsgraph()->HeapConstant(callable.code()));
- node->InsertInput(graph()->zone(), 2, new_target);
- node->InsertInput(graph()->zone(), 3, argument_count);
- node->InsertInput(
- graph()->zone(), 4,
- jsgraph()->Constant(shared.internal_formal_parameter_count()));
- NodeProperties::ChangeOp(
- node, common()->Call(Linkage::GetStubCallDescriptor(
- graph()->zone(), callable.descriptor(), 1 + arity, flags)));
+ const int num_decl_parms = shared.internal_formal_parameter_count();
+ if (arity > num_decl_parms) {
+ while (arity > num_decl_parms) {
+ node->RemoveInput(arity + 1);
+ arity--;
+ }
+ } else {
+ while (arity < num_decl_parms) {
+ node->InsertInput(graph()->zone(), arity + 2,
+ jsgraph()->UndefinedConstant());
+ arity++;
+ }
+ }
+
+ // Patch {node} to a direct call.
+ node->InsertInput(graph()->zone(), arity + 2, new_target);
+ node->InsertInput(graph()->zone(), arity + 3, argument_count);
+ NodeProperties::ChangeOp(node,
+ common()->Call(Linkage::GetJSCallDescriptor(
+ graph()->zone(), false, 1 + arity,
+ flags | CallDescriptor::kCanUseRoots)));
+
} else if (shared.HasBuiltinId() &&
Builtins::HasCppImplementation(shared.builtin_id())) {
// Patch {node} to a direct CEntry call.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment