Commit 68035627 authored by danno's avatar danno Committed by Commit bot

[turbofan] Avoid going through ArgumentsAdaptorTrampoline for select CSA/C++ builtins

This CL changes certain frequently-called Array builtins to use CodeStubArguments
rather than peek at the stack frames above array builtins to determine if options
arguments have been passed into them.

BUG=v8:1956
LOG=N

Review-Url: https://codereview.chromium.org/2829093004
Cr-Commit-Position: refs/heads/master@{#44994}
parent 91d757bd
......@@ -177,7 +177,8 @@ class Genesis BASE_EMBEDDED {
#undef DECLARE_FEATURE_INITIALIZATION
void InstallOneBuiltinFunction(Handle<Object> prototype, const char* method,
Builtins::Name name);
Builtins::Name name,
int internal_formal_parameter_count);
void InitializeGlobal_experimental_fast_array_builtins();
Handle<JSFunction> InstallArrayBuffer(Handle<JSObject> target,
......@@ -3862,15 +3863,17 @@ void InstallPublicSymbol(Factory* factory, Handle<Context> native_context,
void Genesis::InstallOneBuiltinFunction(Handle<Object> prototype,
const char* method_name,
Builtins::Name builtin_name) {
Builtins::Name builtin_name,
int internal_formal_parameter_count) {
LookupIterator it(
prototype, isolate()->factory()->NewStringFromAsciiChecked(method_name),
LookupIterator::OWN_SKIP_INTERCEPTOR);
Handle<Object> function = Object::GetProperty(&it).ToHandleChecked();
Handle<JSFunction>::cast(function)->set_code(
isolate()->builtins()->builtin(builtin_name));
Handle<JSFunction>::cast(function)->shared()->set_code(
isolate()->builtins()->builtin(builtin_name));
SharedFunctionInfo* info = Handle<JSFunction>::cast(function)->shared();
info->set_code(isolate()->builtins()->builtin(builtin_name));
info->set_internal_formal_parameter_count(internal_formal_parameter_count);
}
void Genesis::InitializeGlobal_experimental_fast_array_builtins() {
......@@ -3880,13 +3883,17 @@ void Genesis::InitializeGlobal_experimental_fast_array_builtins() {
native_context()->typed_array_prototype(), isolate());
// Insert experimental fast TypedArray builtins here.
InstallOneBuiltinFunction(typed_array_prototype, "every",
Builtins::kTypedArrayPrototypeEvery);
Builtins::kTypedArrayPrototypeEvery,
SharedFunctionInfo::kDontAdaptArgumentsSentinel);
InstallOneBuiltinFunction(typed_array_prototype, "some",
Builtins::kTypedArrayPrototypeSome);
Builtins::kTypedArrayPrototypeSome,
SharedFunctionInfo::kDontAdaptArgumentsSentinel);
InstallOneBuiltinFunction(typed_array_prototype, "reduce",
Builtins::kTypedArrayPrototypeReduce);
Builtins::kTypedArrayPrototypeReduce,
SharedFunctionInfo::kDontAdaptArgumentsSentinel);
InstallOneBuiltinFunction(typed_array_prototype, "reduceRight",
Builtins::kTypedArrayPrototypeReduceRight);
Builtins::kTypedArrayPrototypeReduceRight,
SharedFunctionInfo::kDontAdaptArgumentsSentinel);
}
}
......@@ -4352,28 +4359,40 @@ bool Genesis::InstallNatives(GlobalContextType context_type) {
// Install Array.prototype.forEach
Handle<JSFunction> forEach = InstallArrayBuiltinFunction(
proto, "forEach", Builtins::kArrayForEach, 2);
proto, "forEach", Builtins::kArrayForEach,
SharedFunctionInfo::kDontAdaptArgumentsSentinel);
// Add forEach to the context.
native_context()->set_array_for_each_iterator(*forEach);
// Install Array.prototype.filter
InstallArrayBuiltinFunction(proto, "filter", Builtins::kArrayFilter, 2);
InstallArrayBuiltinFunction(
proto, "filter", Builtins::kArrayFilter,
SharedFunctionInfo::kDontAdaptArgumentsSentinel);
// Install Array.prototype.map
InstallArrayBuiltinFunction(proto, "map", Builtins::kArrayMap, 2);
InstallArrayBuiltinFunction(
proto, "map", Builtins::kArrayMap,
SharedFunctionInfo::kDontAdaptArgumentsSentinel);
// Install Array.prototype.every
InstallArrayBuiltinFunction(proto, "every", Builtins::kArrayEvery, 2);
InstallArrayBuiltinFunction(
proto, "every", Builtins::kArrayEvery,
SharedFunctionInfo::kDontAdaptArgumentsSentinel);
// Install Array.prototype.some
InstallArrayBuiltinFunction(proto, "some", Builtins::kArraySome, 2);
InstallArrayBuiltinFunction(
proto, "some", Builtins::kArraySome,
SharedFunctionInfo::kDontAdaptArgumentsSentinel);
// Install Array.prototype.reduce
InstallArrayBuiltinFunction(proto, "reduce", Builtins::kArrayReduce, 2);
InstallArrayBuiltinFunction(
proto, "reduce", Builtins::kArrayReduce,
SharedFunctionInfo::kDontAdaptArgumentsSentinel);
// Install Array.prototype.reduceRight
InstallArrayBuiltinFunction(proto, "reduceRight",
Builtins::kArrayReduceRight, 2);
InstallArrayBuiltinFunction(
proto, "reduceRight", Builtins::kArrayReduceRight,
SharedFunctionInfo::kDontAdaptArgumentsSentinel);
}
// Install InternalArray.prototype.concat
......
This diff is collapsed.
......@@ -269,33 +269,33 @@ namespace internal {
/* ES6 #sec-array.prototype.unshift */ \
CPP(ArrayUnshift) \
/* ES6 #sec-array.prototype.foreach */ \
TFJ(ArrayForEachLoopContinuation, 7, kCallbackFn, kThisArg, kArray, kObject, \
kInitialK, kLength, kTo) \
TFJ(ArrayForEach, 2, kCallbackFn, kThisArg) \
TFS(ArrayForEachLoopContinuation, kReceiver, kCallbackFn, kThisArg, kArray, \
kObject, kInitialK, kLength, kTo) \
TFJ(ArrayForEach, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES6 #sec-array.prototype.every */ \
TFJ(ArrayEveryLoopContinuation, 7, kCallbackFn, kThisArg, kArray, kObject, \
kInitialK, kLength, kTo) \
TFJ(ArrayEvery, 2, kCallbackFn, kThisArg) \
TFS(ArrayEveryLoopContinuation, kReceiver, kCallbackFn, kThisArg, kArray, \
kObject, kInitialK, kLength, kTo) \
TFJ(ArrayEvery, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES6 #sec-array.prototype.some */ \
TFJ(ArraySomeLoopContinuation, 7, kCallbackFn, kThisArg, kArray, kObject, \
kInitialK, kLength, kTo) \
TFJ(ArraySome, 2, kCallbackFn, kThisArg) \
TFS(ArraySomeLoopContinuation, kReceiver, kCallbackFn, kThisArg, kArray, \
kObject, kInitialK, kLength, kTo) \
TFJ(ArraySome, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES6 #sec-array.prototype.filter */ \
TFJ(ArrayFilterLoopContinuation, 7, kCallbackFn, kThisArg, kArray, kObject, \
kInitialK, kLength, kTo) \
TFJ(ArrayFilter, 2, kCallbackFn, kThisArg) \
TFS(ArrayFilterLoopContinuation, kReceiver, kCallbackFn, kThisArg, kArray, \
kObject, kInitialK, kLength, kTo) \
TFJ(ArrayFilter, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES6 #sec-array.prototype.foreach */ \
TFJ(ArrayMapLoopContinuation, 7, kCallbackFn, kThisArg, kArray, kObject, \
kInitialK, kLength, kTo) \
TFJ(ArrayMap, 2, kCallbackFn, kThisArg) \
/* ES6 #sec-array.prototype.reduce */ \
TFJ(ArrayReduceLoopContinuation, 7, kCallbackFn, kThisArg, kAccumulator, \
TFS(ArrayMapLoopContinuation, kReceiver, kCallbackFn, kThisArg, kArray, \
kObject, kInitialK, kLength, kTo) \
TFJ(ArrayReduce, 2, kCallbackFn, kInitialValue) \
TFJ(ArrayMap, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES6 #sec-array.prototype.reduce */ \
TFS(ArrayReduceLoopContinuation, kReceiver, kCallbackFn, kThisArg, \
kAccumulator, kObject, kInitialK, kLength, kTo) \
TFJ(ArrayReduce, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES6 #sec-array.prototype.reduceRight */ \
TFJ(ArrayReduceRightLoopContinuation, 7, kCallbackFn, kThisArg, \
TFS(ArrayReduceRightLoopContinuation, kReceiver, kCallbackFn, kThisArg, \
kAccumulator, kObject, kInitialK, kLength, kTo) \
TFJ(ArrayReduceRight, 2, kCallbackFn, kInitialValue) \
TFJ(ArrayReduceRight, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES6 #sec-array.prototype.entries */ \
TFJ(ArrayPrototypeEntries, 0) \
/* ES6 #sec-array.prototype.keys */ \
......@@ -935,13 +935,17 @@ namespace internal {
/* ES6 #sec-%typedarray%.prototype.slice */ \
CPP(TypedArrayPrototypeSlice) \
/* ES6 %TypedArray%.prototype.every */ \
TFJ(TypedArrayPrototypeEvery, 2, kCallbackFn, kThisArg) \
TFJ(TypedArrayPrototypeEvery, \
SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES6 %TypedArray%.prototype.some */ \
TFJ(TypedArrayPrototypeSome, 2, kCallbackFn, kThisArg) \
TFJ(TypedArrayPrototypeSome, \
SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES6 %TypedArray%.prototype.reduce */ \
TFJ(TypedArrayPrototypeReduce, 2, kCallbackFn, kInitialValue) \
TFJ(TypedArrayPrototypeReduce, \
SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES6 %TypedArray%.prototype.reduceRight */ \
TFJ(TypedArrayPrototypeReduceRight, 2, kCallbackFn, kInitialValue) \
TFJ(TypedArrayPrototypeReduceRight, \
SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
\
/* Wasm */ \
ASM(WasmCompileLazy) \
......
......@@ -504,48 +504,6 @@ Callable CodeFactory::ArrayPush(Isolate* isolate) {
return Callable(isolate->builtins()->ArrayPush(), BuiltinDescriptor(isolate));
}
// static
Callable CodeFactory::ArrayFilterLoopContinuation(Isolate* isolate) {
return Callable(isolate->builtins()->ArrayFilterLoopContinuation(),
IteratingArrayBuiltinLoopContinuationDescriptor(isolate));
}
// static
Callable CodeFactory::ArrayMapLoopContinuation(Isolate* isolate) {
return Callable(isolate->builtins()->ArrayMapLoopContinuation(),
IteratingArrayBuiltinLoopContinuationDescriptor(isolate));
}
// static
Callable CodeFactory::ArrayForEachLoopContinuation(Isolate* isolate) {
return Callable(isolate->builtins()->ArrayForEachLoopContinuation(),
IteratingArrayBuiltinLoopContinuationDescriptor(isolate));
}
// static
Callable CodeFactory::ArraySomeLoopContinuation(Isolate* isolate) {
return Callable(isolate->builtins()->ArraySomeLoopContinuation(),
IteratingArrayBuiltinLoopContinuationDescriptor(isolate));
}
// static
Callable CodeFactory::ArrayEveryLoopContinuation(Isolate* isolate) {
return Callable(isolate->builtins()->ArrayEveryLoopContinuation(),
IteratingArrayBuiltinLoopContinuationDescriptor(isolate));
}
// static
Callable CodeFactory::ArrayReduceLoopContinuation(Isolate* isolate) {
return Callable(isolate->builtins()->ArrayReduceLoopContinuation(),
IteratingArrayBuiltinLoopContinuationDescriptor(isolate));
}
// static
Callable CodeFactory::ArrayReduceRightLoopContinuation(Isolate* isolate) {
return Callable(isolate->builtins()->ArrayReduceRightLoopContinuation(),
IteratingArrayBuiltinLoopContinuationDescriptor(isolate));
}
// static
Callable CodeFactory::FunctionPrototypeBind(Isolate* isolate) {
return Callable(isolate->builtins()->FunctionPrototypeBind(),
......
......@@ -183,13 +183,6 @@ class V8_EXPORT_PRIVATE CodeFactory final {
static Callable ArrayConstructor(Isolate* isolate);
static Callable ArrayPush(Isolate* isolate);
static Callable ArrayFilterLoopContinuation(Isolate* isolate);
static Callable ArrayMapLoopContinuation(Isolate* isolate);
static Callable ArrayForEachLoopContinuation(Isolate* isolate);
static Callable ArraySomeLoopContinuation(Isolate* isolate);
static Callable ArrayEveryLoopContinuation(Isolate* isolate);
static Callable ArrayReduceLoopContinuation(Isolate* isolate);
static Callable ArrayReduceRightLoopContinuation(Isolate* isolate);
static Callable FunctionPrototypeBind(Isolate* isolate);
static Callable PromiseHandleReject(Isolate* isolate);
......
......@@ -8706,6 +8706,28 @@ Node* CodeStubArguments::AtIndex(int index) const {
return AtIndex(assembler_->IntPtrConstant(index));
}
Node* CodeStubArguments::GetOptionalArgumentValue(int index,
Node* default_value) {
typedef CodeStubAssembler::Variable Variable;
Variable result(assembler_, MachineRepresentation::kTagged);
CodeStubAssembler::Label argument_missing(assembler_),
argument_done(assembler_, &result);
assembler_->GotoIf(assembler_->UintPtrOrSmiGreaterThanOrEqual(
assembler_->IntPtrOrSmiConstant(index, argc_mode_),
argc_, argc_mode_),
&argument_missing);
result.Bind(AtIndex(index));
assembler_->Goto(&argument_done);
assembler_->BIND(&argument_missing);
result.Bind(default_value);
assembler_->Goto(&argument_done);
assembler_->BIND(&argument_done);
return result.value();
}
void CodeStubArguments::ForEach(
const CodeStubAssembler::VariableList& vars,
const CodeStubArguments::ForEachBodyFunction& body, Node* first, Node* last,
......
......@@ -1468,11 +1468,12 @@ class CodeStubArguments {
public:
typedef compiler::Node Node;
// |argc| is an uint32 value which specifies the number of arguments passed
// |argc| is an intptr value which specifies the number of arguments passed
// to the builtin excluding the receiver.
CodeStubArguments(CodeStubAssembler* assembler, Node* argc)
: CodeStubArguments(assembler, argc, nullptr,
CodeStubAssembler::INTPTR_PARAMETERS) {}
// |argc| is either a smi or intptr depending on |param_mode|
CodeStubArguments(CodeStubAssembler* assembler, Node* argc, Node* fp,
CodeStubAssembler::ParameterMode param_mode);
......@@ -1487,6 +1488,8 @@ class CodeStubArguments {
Node* AtIndex(int index) const;
Node* GetOptionalArgumentValue(int index, Node* default_value);
Node* GetLength() const { return argc_; }
typedef std::function<void(Node* arg)> ForEachBodyFunction;
......
......@@ -639,7 +639,7 @@ Node* CodeAssembler::CallStubR(const CallInterfaceDescriptor& descriptor,
#define INSTANTIATE(...) \
template V8_EXPORT_PRIVATE Node* CodeAssembler::CallStubR( \
const CallInterfaceDescriptor& descriptor, size_t, Node*, __VA_ARGS__);
REPEAT_1_TO_8(INSTANTIATE, Node*)
REPEAT_1_TO_11(INSTANTIATE, Node*)
#undef INSTANTIATE
Node* CodeAssembler::CallStubN(const CallInterfaceDescriptor& descriptor,
......
......@@ -54,7 +54,6 @@ class PlatformInterfaceDescriptor;
V(Builtin) \
V(ArrayConstructor) \
V(IteratingArrayBuiltin) \
V(IteratingArrayBuiltinLoopContinuation) \
V(ArrayNoArgumentConstructor) \
V(ArraySingleArgumentConstructor) \
V(ArrayNArgumentsConstructor) \
......@@ -226,15 +225,25 @@ class V8_EXPORT_PRIVATE CallInterfaceDescriptor {
} \
static inline CallDescriptors::Key key();
#define DECLARE_DEFAULT_DESCRIPTOR(name, base, parameter_count) \
DECLARE_DESCRIPTOR_WITH_BASE(name, base) \
protected: \
void InitializePlatformSpecific(CallInterfaceDescriptorData* data) \
override { \
DefaultInitializePlatformSpecific(data, parameter_count); \
} \
name(Isolate* isolate, CallDescriptors::Key key) : base(isolate, key) {} \
\
static const int kMaxBuiltinRegisterParams = 5;
#define DECLARE_DEFAULT_DESCRIPTOR(name, base, parameter_count) \
DECLARE_DESCRIPTOR_WITH_BASE(name, base) \
protected: \
static const int kRegisterParams = \
parameter_count > kMaxBuiltinRegisterParams ? kMaxBuiltinRegisterParams \
: parameter_count; \
static const int kStackParams = parameter_count - kRegisterParams; \
void InitializePlatformSpecific(CallInterfaceDescriptorData* data) \
override { \
DefaultInitializePlatformSpecific(data, kRegisterParams); \
} \
void InitializePlatformIndependent(CallInterfaceDescriptorData* data) \
override { \
data->InitializePlatformIndependent(kRegisterParams, kStackParams, NULL); \
} \
name(Isolate* isolate, CallDescriptors::Key key) : base(isolate, key) {} \
\
public:
#define DECLARE_DESCRIPTOR(name, base) \
......@@ -642,14 +651,6 @@ class IteratingArrayBuiltinDescriptor : public BuiltinDescriptor {
DECLARE_BUILTIN_DESCRIPTOR(IteratingArrayBuiltinDescriptor)
};
class IteratingArrayBuiltinLoopContinuationDescriptor
: public BuiltinDescriptor {
public:
DEFINE_BUILTIN_PARAMETERS(kCallback, kThisArg, kArray, kObject, kInitialK,
kLength, kTo)
DECLARE_BUILTIN_DESCRIPTOR(IteratingArrayBuiltinLoopContinuationDescriptor)
};
class ArrayConstructorDescriptor : public CallInterfaceDescriptor {
public:
DEFINE_PARAMETERS(kTarget, kNewTarget, kActualArgumentsCount, kAllocationSite)
......
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax
var a = [0];
function bar(x) { return x; }
function foo() { return a.reduce(bar); }
assertEquals(0, foo());
assertEquals(0, foo());
%OptimizeFunctionOnNextCall(foo);
assertEquals(0, foo());
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment