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
......
......@@ -46,7 +46,7 @@ class ArrayBuiltinCodeStubAssembler : public CodeStubAssembler {
Label false_continue(this), return_true(this);
BranchIfToBooleanIsTrue(value, &return_true, &false_continue);
BIND(&return_true);
Return(TrueConstant());
ReturnFromBuiltin(TrueConstant());
BIND(&false_continue);
return a();
}
......@@ -59,44 +59,12 @@ class ArrayBuiltinCodeStubAssembler : public CodeStubAssembler {
Label true_continue(this), return_false(this);
BranchIfToBooleanIsTrue(value, &true_continue, &return_false);
BIND(&return_false);
Return(FalseConstant());
ReturnFromBuiltin(FalseConstant());
BIND(&true_continue);
return a();
}
Node* ReduceResultGenerator() {
VARIABLE(a, MachineRepresentation::kTagged, UndefinedConstant());
Label no_initial_value(this), has_initial_value(this), done(this, {&a});
// 8. If initialValue is present, then
Node* parent_frame_ptr = LoadParentFramePointer();
Node* marker_or_function = LoadBufferObject(
parent_frame_ptr, CommonFrameConstants::kContextOrFrameTypeOffset);
GotoIf(
MarkerIsNotFrameType(marker_or_function, StackFrame::ARGUMENTS_ADAPTOR),
&has_initial_value);
// Has arguments adapter, check count.
Node* adapted_parameter_count = LoadBufferObject(
parent_frame_ptr, ArgumentsAdaptorFrameConstants::kLengthOffset);
Branch(SmiLessThan(adapted_parameter_count,
SmiConstant(IteratingArrayBuiltinDescriptor::kThisArg)),
&no_initial_value, &has_initial_value);
// a. Set accumulator to initialValue.
BIND(&has_initial_value);
a.Bind(this_arg());
Goto(&done);
// 9. Else initialValue is not present,
BIND(&no_initial_value);
// a. Let kPresent be false.
a.Bind(TheHoleConstant());
Goto(&done);
BIND(&done);
return a.value();
}
Node* ReduceResultGenerator() { return this_arg(); }
Node* ReduceProcessor(Node* k_value, Node* k) {
VARIABLE(result, MachineRepresentation::kTagged);
......@@ -266,6 +234,7 @@ class ArrayBuiltinCodeStubAssembler : public CodeStubAssembler {
Node* context() { return context_; }
Node* receiver() { return receiver_; }
Node* new_target() { return new_target_; }
Node* argc() { return argc_; }
Node* o() { return o_; }
Node* len() { return len_; }
Node* callbackfn() { return callbackfn_; }
......@@ -273,14 +242,25 @@ class ArrayBuiltinCodeStubAssembler : public CodeStubAssembler {
Node* k() { return k_.value(); }
Node* a() { return a_.value(); }
void ReturnFromBuiltin(Node* value) {
if (argc_ == nullptr) {
Return(value);
} else {
// argc_ doesn't include the receiver, so it has to be added back in
// manually.
PopAndReturn(IntPtrAdd(argc_, IntPtrConstant(1)), value);
}
}
void InitIteratingArrayBuiltinBody(Node* context, Node* receiver,
Node* callbackfn, Node* this_arg,
Node* new_target) {
Node* new_target, Node* argc) {
context_ = context;
receiver_ = receiver;
new_target_ = new_target;
callbackfn_ = callbackfn;
this_arg_ = this_arg;
argc_ = argc;
}
void GenerateIteratingArrayBuiltinBody(
......@@ -362,13 +342,10 @@ class ArrayBuiltinCodeStubAssembler : public CodeStubAssembler {
BIND(&slow);
Node* target = LoadFromFrame(StandardFrameConstants::kFunctionOffset,
MachineType::TaggedPointer());
TailCallStub(
slow_case_continuation, context(), target, new_target(),
Int32Constant(IteratingArrayBuiltinLoopContinuationDescriptor::kArity),
receiver(), callbackfn(), this_arg(), a_.value(), o(), k_.value(),
len(), to_.value());
Node* result =
CallStub(slow_case_continuation, context(), receiver(), callbackfn(),
this_arg(), a_.value(), o(), k_.value(), len(), to_.value());
ReturnFromBuiltin(result);
}
void InitIteratingArrayBuiltinLoopContinuation(Node* context, Node* receiver,
......@@ -379,6 +356,7 @@ class ArrayBuiltinCodeStubAssembler : public CodeStubAssembler {
context_ = context;
this_arg_ = this_arg;
callbackfn_ = callbackfn;
argc_ = nullptr;
a_.Bind(a);
k_.Bind(initial_k);
o_ = o;
......@@ -480,7 +458,7 @@ class ArrayBuiltinCodeStubAssembler : public CodeStubAssembler {
// No exception, return success
BIND(&done);
action(this);
Return(a_.value());
ReturnFromBuiltin(a_.value());
}
}
......@@ -682,7 +660,7 @@ class ArrayBuiltinCodeStubAssembler : public CodeStubAssembler {
action(this);
// No exception, return success
Return(a_.value());
ReturnFromBuiltin(a_.value());
}
BIND(&maybe_double_elements);
......@@ -697,7 +675,7 @@ class ArrayBuiltinCodeStubAssembler : public CodeStubAssembler {
action(this);
// No exception, return success
Return(a_.value());
ReturnFromBuiltin(a_.value());
}
}
......@@ -708,6 +686,7 @@ class ArrayBuiltinCodeStubAssembler : public CodeStubAssembler {
Node* context_ = nullptr;
Node* receiver_ = nullptr;
Node* new_target_ = nullptr;
Node* argc_ = nullptr;
Variable k_;
Variable a_;
Variable to_;
......@@ -863,21 +842,25 @@ TF_BUILTIN(ArrayForEachLoopContinuation, ArrayBuiltinCodeStubAssembler) {
}
TF_BUILTIN(ArrayForEach, ArrayBuiltinCodeStubAssembler) {
Node* context = Parameter(Descriptor::kContext);
Node* receiver = Parameter(Descriptor::kReceiver);
Node* callbackfn = Parameter(Descriptor::kCallbackFn);
Node* this_arg = Parameter(Descriptor::kThisArg);
Node* new_target = Parameter(Descriptor::kNewTarget);
Node* argc =
ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount));
CodeStubArguments args(this, argc);
Node* context = Parameter(BuiltinDescriptor::kContext);
Node* new_target = Parameter(BuiltinDescriptor::kNewTarget);
Node* receiver = args.GetReceiver();
Node* callbackfn = args.GetOptionalArgumentValue(0, UndefinedConstant());
Node* this_arg = args.GetOptionalArgumentValue(1, UndefinedConstant());
InitIteratingArrayBuiltinBody(context, receiver, callbackfn, this_arg,
new_target);
new_target, argc);
GenerateIteratingArrayBuiltinBody(
"Array.prototype.forEach",
&ArrayBuiltinCodeStubAssembler::ForEachResultGenerator,
&ArrayBuiltinCodeStubAssembler::ForEachProcessor,
&ArrayBuiltinCodeStubAssembler::NullPostLoopAction,
CodeFactory::ArrayForEachLoopContinuation(isolate()));
Builtins::CallableFor(isolate(),
Builtins::kArrayForEachLoopContinuation));
}
TF_BUILTIN(ArraySomeLoopContinuation, ArrayBuiltinCodeStubAssembler) {
......@@ -901,32 +884,38 @@ TF_BUILTIN(ArraySomeLoopContinuation, ArrayBuiltinCodeStubAssembler) {
}
TF_BUILTIN(ArraySome, ArrayBuiltinCodeStubAssembler) {
Node* context = Parameter(Descriptor::kContext);
Node* receiver = Parameter(Descriptor::kReceiver);
Node* callbackfn = Parameter(Descriptor::kCallbackFn);
Node* this_arg = Parameter(Descriptor::kThisArg);
Node* new_target = Parameter(Descriptor::kNewTarget);
Node* argc =
ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount));
CodeStubArguments args(this, argc);
Node* context = Parameter(BuiltinDescriptor::kContext);
Node* new_target = Parameter(BuiltinDescriptor::kNewTarget);
Node* receiver = args.GetReceiver();
Node* callbackfn = args.GetOptionalArgumentValue(0, UndefinedConstant());
Node* this_arg = args.GetOptionalArgumentValue(1, UndefinedConstant());
InitIteratingArrayBuiltinBody(context, receiver, callbackfn, this_arg,
new_target);
new_target, argc);
GenerateIteratingArrayBuiltinBody(
"Array.prototype.some",
&ArrayBuiltinCodeStubAssembler::SomeResultGenerator,
&ArrayBuiltinCodeStubAssembler::SomeProcessor,
&ArrayBuiltinCodeStubAssembler::NullPostLoopAction,
CodeFactory::ArraySomeLoopContinuation(isolate()));
Builtins::CallableFor(isolate(), Builtins::kArraySomeLoopContinuation));
}
TF_BUILTIN(TypedArrayPrototypeSome, ArrayBuiltinCodeStubAssembler) {
Node* context = Parameter(Descriptor::kContext);
Node* receiver = Parameter(Descriptor::kReceiver);
Node* callbackfn = Parameter(Descriptor::kCallbackFn);
Node* this_arg = Parameter(Descriptor::kThisArg);
Node* new_target = Parameter(Descriptor::kNewTarget);
Node* argc =
ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount));
CodeStubArguments args(this, argc);
Node* context = Parameter(BuiltinDescriptor::kContext);
Node* new_target = Parameter(BuiltinDescriptor::kNewTarget);
Node* receiver = args.GetReceiver();
Node* callbackfn = args.GetOptionalArgumentValue(0, UndefinedConstant());
Node* this_arg = args.GetOptionalArgumentValue(1, UndefinedConstant());
InitIteratingArrayBuiltinBody(context, receiver, callbackfn, this_arg,
new_target);
new_target, argc);
GenerateIteratingTypedArrayBuiltinBody(
"%TypedArray%.prototype.some",
......@@ -956,32 +945,38 @@ TF_BUILTIN(ArrayEveryLoopContinuation, ArrayBuiltinCodeStubAssembler) {
}
TF_BUILTIN(ArrayEvery, ArrayBuiltinCodeStubAssembler) {
Node* context = Parameter(Descriptor::kContext);
Node* receiver = Parameter(Descriptor::kReceiver);
Node* callbackfn = Parameter(Descriptor::kCallbackFn);
Node* this_arg = Parameter(Descriptor::kThisArg);
Node* new_target = Parameter(Descriptor::kNewTarget);
Node* argc =
ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount));
CodeStubArguments args(this, argc);
Node* context = Parameter(BuiltinDescriptor::kContext);
Node* new_target = Parameter(BuiltinDescriptor::kNewTarget);
Node* receiver = args.GetReceiver();
Node* callbackfn = args.GetOptionalArgumentValue(0, UndefinedConstant());
Node* this_arg = args.GetOptionalArgumentValue(1, UndefinedConstant());
InitIteratingArrayBuiltinBody(context, receiver, callbackfn, this_arg,
new_target);
new_target, argc);
GenerateIteratingArrayBuiltinBody(
"Array.prototype.every",
&ArrayBuiltinCodeStubAssembler::EveryResultGenerator,
&ArrayBuiltinCodeStubAssembler::EveryProcessor,
&ArrayBuiltinCodeStubAssembler::NullPostLoopAction,
CodeFactory::ArrayEveryLoopContinuation(isolate()));
Builtins::CallableFor(isolate(), Builtins::kArrayEveryLoopContinuation));
}
TF_BUILTIN(TypedArrayPrototypeEvery, ArrayBuiltinCodeStubAssembler) {
Node* context = Parameter(Descriptor::kContext);
Node* receiver = Parameter(Descriptor::kReceiver);
Node* callbackfn = Parameter(Descriptor::kCallbackFn);
Node* this_arg = Parameter(Descriptor::kThisArg);
Node* new_target = Parameter(Descriptor::kNewTarget);
Node* argc =
ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount));
CodeStubArguments args(this, argc);
Node* context = Parameter(BuiltinDescriptor::kContext);
Node* new_target = Parameter(BuiltinDescriptor::kNewTarget);
Node* receiver = args.GetReceiver();
Node* callbackfn = args.GetOptionalArgumentValue(0, UndefinedConstant());
Node* this_arg = args.GetOptionalArgumentValue(1, UndefinedConstant());
InitIteratingArrayBuiltinBody(context, receiver, callbackfn, this_arg,
new_target);
new_target, argc);
GenerateIteratingTypedArrayBuiltinBody(
"%TypedArray%.prototype.every",
......@@ -1011,32 +1006,38 @@ TF_BUILTIN(ArrayReduceLoopContinuation, ArrayBuiltinCodeStubAssembler) {
}
TF_BUILTIN(ArrayReduce, ArrayBuiltinCodeStubAssembler) {
Node* context = Parameter(Descriptor::kContext);
Node* receiver = Parameter(Descriptor::kReceiver);
Node* callbackfn = Parameter(Descriptor::kCallbackFn);
Node* initial_value = Parameter(Descriptor::kInitialValue);
Node* new_target = Parameter(Descriptor::kNewTarget);
Node* argc =
ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount));
CodeStubArguments args(this, argc);
Node* context = Parameter(BuiltinDescriptor::kContext);
Node* new_target = Parameter(BuiltinDescriptor::kNewTarget);
Node* receiver = args.GetReceiver();
Node* callbackfn = args.GetOptionalArgumentValue(0, UndefinedConstant());
Node* initial_value = args.GetOptionalArgumentValue(1, TheHoleConstant());
InitIteratingArrayBuiltinBody(context, receiver, callbackfn, initial_value,
new_target);
new_target, argc);
GenerateIteratingArrayBuiltinBody(
"Array.prototype.reduce",
&ArrayBuiltinCodeStubAssembler::ReduceResultGenerator,
&ArrayBuiltinCodeStubAssembler::ReduceProcessor,
&ArrayBuiltinCodeStubAssembler::ReducePostLoopAction,
CodeFactory::ArrayReduceLoopContinuation(isolate()));
Builtins::CallableFor(isolate(), Builtins::kArrayReduceLoopContinuation));
}
TF_BUILTIN(TypedArrayPrototypeReduce, ArrayBuiltinCodeStubAssembler) {
Node* context = Parameter(Descriptor::kContext);
Node* receiver = Parameter(Descriptor::kReceiver);
Node* callbackfn = Parameter(Descriptor::kCallbackFn);
Node* initial_value = Parameter(Descriptor::kInitialValue);
Node* new_target = Parameter(Descriptor::kNewTarget);
Node* argc =
ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount));
CodeStubArguments args(this, argc);
Node* context = Parameter(BuiltinDescriptor::kContext);
Node* new_target = Parameter(BuiltinDescriptor::kNewTarget);
Node* receiver = args.GetReceiver();
Node* callbackfn = args.GetOptionalArgumentValue(0, UndefinedConstant());
Node* initial_value = args.GetOptionalArgumentValue(1, TheHoleConstant());
InitIteratingArrayBuiltinBody(context, receiver, callbackfn, initial_value,
new_target);
new_target, argc);
GenerateIteratingTypedArrayBuiltinBody(
"%TypedArray%.prototype.reduce",
......@@ -1067,33 +1068,40 @@ TF_BUILTIN(ArrayReduceRightLoopContinuation, ArrayBuiltinCodeStubAssembler) {
}
TF_BUILTIN(ArrayReduceRight, ArrayBuiltinCodeStubAssembler) {
Node* context = Parameter(Descriptor::kContext);
Node* receiver = Parameter(Descriptor::kReceiver);
Node* callbackfn = Parameter(Descriptor::kCallbackFn);
Node* initial_value = Parameter(Descriptor::kInitialValue);
Node* new_target = Parameter(Descriptor::kNewTarget);
Node* argc =
ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount));
CodeStubArguments args(this, argc);
Node* context = Parameter(BuiltinDescriptor::kContext);
Node* new_target = Parameter(BuiltinDescriptor::kNewTarget);
Node* receiver = args.GetReceiver();
Node* callbackfn = args.GetOptionalArgumentValue(0, UndefinedConstant());
Node* initial_value = args.GetOptionalArgumentValue(1, TheHoleConstant());
InitIteratingArrayBuiltinBody(context, receiver, callbackfn, initial_value,
new_target);
new_target, argc);
GenerateIteratingArrayBuiltinBody(
"Array.prototype.reduceRight",
&ArrayBuiltinCodeStubAssembler::ReduceResultGenerator,
&ArrayBuiltinCodeStubAssembler::ReduceProcessor,
&ArrayBuiltinCodeStubAssembler::ReducePostLoopAction,
CodeFactory::ArrayReduceRightLoopContinuation(isolate()),
Builtins::CallableFor(isolate(),
Builtins::kArrayReduceRightLoopContinuation),
ForEachDirection::kReverse);
}
TF_BUILTIN(TypedArrayPrototypeReduceRight, ArrayBuiltinCodeStubAssembler) {
Node* context = Parameter(Descriptor::kContext);
Node* receiver = Parameter(Descriptor::kReceiver);
Node* callbackfn = Parameter(Descriptor::kCallbackFn);
Node* initial_value = Parameter(Descriptor::kInitialValue);
Node* new_target = Parameter(Descriptor::kNewTarget);
Node* argc =
ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount));
CodeStubArguments args(this, argc);
Node* context = Parameter(BuiltinDescriptor::kContext);
Node* new_target = Parameter(BuiltinDescriptor::kNewTarget);
Node* receiver = args.GetReceiver();
Node* callbackfn = args.GetOptionalArgumentValue(0, UndefinedConstant());
Node* initial_value = args.GetOptionalArgumentValue(1, TheHoleConstant());
InitIteratingArrayBuiltinBody(context, receiver, callbackfn, initial_value,
new_target);
new_target, argc);
GenerateIteratingTypedArrayBuiltinBody(
"%TypedArray%.prototype.reduceRight",
......@@ -1124,21 +1132,24 @@ TF_BUILTIN(ArrayFilterLoopContinuation, ArrayBuiltinCodeStubAssembler) {
}
TF_BUILTIN(ArrayFilter, ArrayBuiltinCodeStubAssembler) {
Node* context = Parameter(Descriptor::kContext);
Node* receiver = Parameter(Descriptor::kReceiver);
Node* callbackfn = Parameter(Descriptor::kCallbackFn);
Node* this_arg = Parameter(Descriptor::kThisArg);
Node* new_target = Parameter(Descriptor::kNewTarget);
Node* argc =
ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount));
CodeStubArguments args(this, argc);
Node* context = Parameter(BuiltinDescriptor::kContext);
Node* new_target = Parameter(BuiltinDescriptor::kNewTarget);
Node* receiver = args.GetReceiver();
Node* callbackfn = args.GetOptionalArgumentValue(0, UndefinedConstant());
Node* this_arg = args.GetOptionalArgumentValue(1, UndefinedConstant());
InitIteratingArrayBuiltinBody(context, receiver, callbackfn, this_arg,
new_target);
new_target, argc);
GenerateIteratingArrayBuiltinBody(
"Array.prototype.filter",
&ArrayBuiltinCodeStubAssembler::FilterResultGenerator,
&ArrayBuiltinCodeStubAssembler::FilterProcessor,
&ArrayBuiltinCodeStubAssembler::NullPostLoopAction,
CodeFactory::ArrayFilterLoopContinuation(isolate()));
Builtins::CallableFor(isolate(), Builtins::kArrayFilterLoopContinuation));
}
TF_BUILTIN(ArrayMapLoopContinuation, ArrayBuiltinCodeStubAssembler) {
......@@ -1162,20 +1173,23 @@ TF_BUILTIN(ArrayMapLoopContinuation, ArrayBuiltinCodeStubAssembler) {
}
TF_BUILTIN(ArrayMap, ArrayBuiltinCodeStubAssembler) {
Node* context = Parameter(Descriptor::kContext);
Node* receiver = Parameter(Descriptor::kReceiver);
Node* callbackfn = Parameter(Descriptor::kCallbackFn);
Node* this_arg = Parameter(Descriptor::kThisArg);
Node* new_target = Parameter(Descriptor::kNewTarget);
Node* argc =
ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount));
CodeStubArguments args(this, argc);
Node* context = Parameter(BuiltinDescriptor::kContext);
Node* new_target = Parameter(BuiltinDescriptor::kNewTarget);
Node* receiver = args.GetReceiver();
Node* callbackfn = args.GetOptionalArgumentValue(0, UndefinedConstant());
Node* this_arg = args.GetOptionalArgumentValue(1, UndefinedConstant());
InitIteratingArrayBuiltinBody(context, receiver, callbackfn, this_arg,
new_target);
new_target, argc);
GenerateIteratingArrayBuiltinBody(
"Array.prototype.map", &ArrayBuiltinCodeStubAssembler::MapResultGenerator,
&ArrayBuiltinCodeStubAssembler::MapProcessor,
&ArrayBuiltinCodeStubAssembler::NullPostLoopAction,
CodeFactory::ArrayMapLoopContinuation(isolate()));
Builtins::CallableFor(isolate(), Builtins::kArrayMapLoopContinuation));
}
TF_BUILTIN(ArrayIsArray, CodeStubAssembler) {
......
......@@ -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