Commit 36690365 authored by peterwmwong's avatar peterwmwong Committed by Commit Bot

[typedarray] Port TA.p.findIndex() to CSA TFJ

This reduces the overhead of calling the builtin.
Quick measurements show >5x improvement. As the
typed array's size grows, iterating dominates
and the performance gap closes.
https://github.com/peterwmwong/v8-perf/blob/master/typedarray-findIndex/README.md

Bug: v8:5929
Change-Id: I27d67776c83cbe28f4f9f5ef479a7eeabf594654
Reviewed-on: https://chromium-review.googlesource.com/792394
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#49720}
parent 3cfc4b3a
......@@ -3033,6 +3033,8 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
Builtins::kTypedArrayPrototypeFill, 1, false);
SimpleInstallFunction(prototype, "find", Builtins::kTypedArrayPrototypeFind,
1, false);
SimpleInstallFunction(prototype, "findIndex",
Builtins::kTypedArrayPrototypeFindIndex, 1, false);
SimpleInstallFunction(prototype, "forEach",
Builtins::kTypedArrayPrototypeForEach, 1, false);
SimpleInstallFunction(prototype, "includes",
......
......@@ -44,6 +44,19 @@ class ArrayBuiltinCodeStubAssembler : public CodeStubAssembler {
return a();
}
void FindIndexResultGenerator() { a_.Bind(SmiConstant(-1)); }
Node* FindIndexProcessor(Node* k_value, Node* k) {
Node* value = CallJS(CodeFactory::Call(isolate()), context(), callbackfn(),
this_arg(), k_value, k, o());
Label false_continue(this), return_true(this);
BranchIfToBooleanIsTrue(value, &return_true, &false_continue);
BIND(&return_true);
ReturnFromBuiltin(k);
BIND(&false_continue);
return a();
}
void ForEachResultGenerator() { a_.Bind(UndefinedConstant()); }
Node* ForEachProcessor(Node* k_value, Node* k) {
......@@ -1627,6 +1640,27 @@ TF_BUILTIN(TypedArrayPrototypeFind, ArrayBuiltinCodeStubAssembler) {
&ArrayBuiltinCodeStubAssembler::NullPostLoopAction);
}
// ES #sec-get-%typedarray%.prototype.findIndex
TF_BUILTIN(TypedArrayPrototypeFindIndex, ArrayBuiltinCodeStubAssembler) {
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);
Node* this_arg = args.GetOptionalArgumentValue(1);
InitIteratingArrayBuiltinBody(context, receiver, callbackfn, this_arg,
new_target, argc);
GenerateIteratingTypedArrayBuiltinBody(
"%TypedArray%.prototype.findIndex",
&ArrayBuiltinCodeStubAssembler::FindIndexResultGenerator,
&ArrayBuiltinCodeStubAssembler::FindIndexProcessor,
&ArrayBuiltinCodeStubAssembler::NullPostLoopAction);
}
TF_BUILTIN(ArrayForEachLoopContinuation, ArrayBuiltinCodeStubAssembler) {
Node* context = Parameter(Descriptor::kContext);
Node* receiver = Parameter(Descriptor::kReceiver);
......
......@@ -1049,6 +1049,9 @@ namespace internal {
/* ES6 %TypedArray%.prototype.find */ \
TFJ(TypedArrayPrototypeFind, \
SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES6 %TypedArray%.prototype.findIndex */ \
TFJ(TypedArrayPrototypeFindIndex, \
SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES7 #sec-%typedarray%.prototype.includes */ \
CPP(TypedArrayPrototypeIncludes) \
/* ES6 #sec-%typedarray%.prototype.indexof */ \
......
......@@ -1354,7 +1354,6 @@ utils.Export(function(to) {
to.ArrayPush = ArrayPush;
to.ArrayToString = ArrayToString;
to.ArrayValues = ArrayValues;
to.InnerArrayFindIndex = InnerArrayFindIndex;
to.InnerArrayJoin = InnerArrayJoin;
to.InnerArraySort = InnerArraySort;
to.InnerArrayToLocaleString = InnerArrayToLocaleString;
......
......@@ -19,7 +19,6 @@ var GlobalArray = global.Array;
var GlobalArrayBuffer = global.ArrayBuffer;
var GlobalArrayBufferPrototype = GlobalArrayBuffer.prototype;
var GlobalObject = global.Object;
var InnerArrayFindIndex;
var InnerArrayJoin;
var InnerArraySort;
var InnerArrayToLocaleString;
......@@ -65,7 +64,6 @@ var GlobalTypedArray = %object_get_prototype_of(GlobalUint8Array);
utils.Import(function(from) {
GetIterator = from.GetIterator;
GetMethod = from.GetMethod;
InnerArrayFindIndex = from.InnerArrayFindIndex;
InnerArrayJoin = from.InnerArrayJoin;
InnerArraySort = from.InnerArraySort;
InnerArrayToLocaleString = from.InnerArrayToLocaleString;
......@@ -295,20 +293,6 @@ DEFINE_METHOD_LEN(
1 /* Set function length. */
);
// ES6 draft 07-15-13, section 22.2.3.11
DEFINE_METHOD_LEN(
GlobalTypedArray.prototype,
findIndex(predicate, thisArg) {
ValidateTypedArray(this, "%TypedArray%.prototype.findIndex");
var length = %_TypedArrayGetLength(this);
return InnerArrayFindIndex(predicate, thisArg, this, length);
},
1 /* Set function length. */
);
// ES6 draft 05-18-15, section 22.2.3.25
DEFINE_METHOD(
GlobalTypedArray.prototype,
......
......@@ -175,6 +175,12 @@ for (constructor of typedArrayConstructors) {
%ArrayBufferNeuter(ta.buffer);
ta.find(() => {});
}, "Cannot perform %TypedArray%.prototype.find on a detached ArrayBuffer", TypeError);
test(() => {
const ta = new constructor([1]);
%ArrayBufferNeuter(ta.buffer);
ta.findIndex(() => {});
}, "Cannot perform %TypedArray%.prototype.findIndex on a detached ArrayBuffer", TypeError);
}
// kFirstArgumentNotRegExp
......
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