Commit ab6e48de authored by littledan's avatar littledan Committed by Commit bot

Optimize new TypedArray(typedArray) constructor

A previous spec compliance fix for TypedArrays caused a ~4x performance
regression. This patch removes the regression by calling out
to a path within the runtime which implements array copying more
efficiently.

BUG=chromium:592007
R=adamk
LOG=Y

Review URL: https://codereview.chromium.org/1767893002

Cr-Commit-Position: refs/heads/master@{#34601}
parent d61a0c5a
...@@ -200,8 +200,7 @@ function NAMEConstructByLength(obj, length) { ...@@ -200,8 +200,7 @@ function NAMEConstructByLength(obj, length) {
} }
} }
function NAMEConstructByArrayLike(obj, arrayLike) { function NAMEConstructByArrayLike(obj, arrayLike, length) {
var length = arrayLike.length;
var l = ToPositiveInteger(length, kInvalidTypedArrayLength); var l = ToPositiveInteger(length, kInvalidTypedArrayLength);
if (l > %_MaxSmi()) { if (l > %_MaxSmi()) {
...@@ -241,7 +240,7 @@ function NAMEConstructByIterable(obj, iterable, iteratorFn) { ...@@ -241,7 +240,7 @@ function NAMEConstructByIterable(obj, iterable, iteratorFn) {
for (var value of newIterable) { for (var value of newIterable) {
list.push(value); list.push(value);
} }
NAMEConstructByArrayLike(obj, list); NAMEConstructByArrayLike(obj, list, list.length);
} }
// ES#sec-typedarray-typedarray TypedArray ( typedArray ) // ES#sec-typedarray-typedarray TypedArray ( typedArray )
...@@ -251,20 +250,12 @@ function NAMEConstructByTypedArray(obj, typedArray) { ...@@ -251,20 +250,12 @@ function NAMEConstructByTypedArray(obj, typedArray) {
var length = %_TypedArrayGetLength(typedArray); var length = %_TypedArrayGetLength(typedArray);
var byteLength = %_ArrayBufferViewGetByteLength(typedArray); var byteLength = %_ArrayBufferViewGetByteLength(typedArray);
var newByteLength = length * ELEMENT_SIZE; var newByteLength = length * ELEMENT_SIZE;
NAMEConstructByArrayLike(obj, typedArray, length);
var bufferConstructor = SpeciesConstructor(srcData, GlobalArrayBuffer); var bufferConstructor = SpeciesConstructor(srcData, GlobalArrayBuffer);
var data = new GlobalArrayBuffer(newByteLength);
var prototype = bufferConstructor.prototype; var prototype = bufferConstructor.prototype;
// TODO(littledan): Use the right prototype based on bufferConstructor's realm // TODO(littledan): Use the right prototype based on bufferConstructor's realm
if (IS_RECEIVER(prototype) && prototype !== GlobalArrayBufferPrototype) { if (IS_RECEIVER(prototype) && prototype !== GlobalArrayBufferPrototype) {
%InternalSetPrototype(data, prototype); %InternalSetPrototype(%TypedArrayGetBuffer(obj), prototype);
}
%_TypedArrayInitialize(obj, ARRAY_ID, data, 0, newByteLength, true);
// Note: The separate CloneArrayBuffer path in the spec ensures
// that NaNs are not canonicalized, but because V8 does not
// canonicalize NaNs, we do not have to do anything different.
// TODO(littledan): Make a fastpath based on memcpy
for (var i = 0; i < length; i++) {
obj[i] = typedArray[i];
} }
} }
...@@ -279,8 +270,8 @@ function NAMEConstructor(arg1, arg2, arg3) { ...@@ -279,8 +270,8 @@ function NAMEConstructor(arg1, arg2, arg3) {
NAMEConstructByTypedArray(this, arg1); NAMEConstructByTypedArray(this, arg1);
} else { } else {
var iteratorFn = arg1[iteratorSymbol]; var iteratorFn = arg1[iteratorSymbol];
if (IS_UNDEFINED(iteratorFn) || iteratorFn === ArrayValues) { if (IS_UNDEFINED(iteratorFn)) {
NAMEConstructByArrayLike(this, arg1); NAMEConstructByArrayLike(this, arg1, arg1.length);
} else { } else {
NAMEConstructByIterable(this, arg1, iteratorFn); NAMEConstructByIterable(this, arg1, iteratorFn);
} }
......
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