Diff
Modified: trunk/JSTests/ChangeLog (286638 => 286639)
--- trunk/JSTests/ChangeLog 2021-12-08 02:49:51 UTC (rev 286638)
+++ trunk/JSTests/ChangeLog 2021-12-08 03:59:13 UTC (rev 286639)
@@ -1,3 +1,14 @@
+2021-12-07 Saam Barati <[email protected]>
+
+ TypedArray prototype set should go down the fast path when using non clamped integer types of the same byte size
+ https://bugs.webkit.org/show_bug.cgi?id=233905
+
+ Reviewed by Keith Miller.
+
+ * microbenchmarks/typed-array-prototype-set.js: Added.
+ * microbenchmarks/typed-array-prototype-set-order.js: Added.
+ * stress/typed-array-prototype-set.js: Added.
+
2021-12-02 Yusuke Suzuki <[email protected]>
[JSC] shell's $.globalObjectFor is not safe for non object cells
Added: trunk/JSTests/microbenchmarks/typed-array-prototype-set.js (0 => 286639)
--- trunk/JSTests/microbenchmarks/typed-array-prototype-set.js (rev 0)
+++ trunk/JSTests/microbenchmarks/typed-array-prototype-set.js 2021-12-08 03:59:13 UTC (rev 286639)
@@ -0,0 +1,46 @@
+function test() {
+ let x = new Int8Array(10000);
+ let y = new Uint8Array(10000);
+ for (let i = 0; i < x.length; ++i)
+ x[i] = i;
+ for (let i = 0; i < 500; ++i)
+ y.set(x);
+ for (let i = 0; i < 500; ++i)
+ x.set(y);
+}
+
+function test2() {
+ let x = new Int16Array(10000);
+ let y = new Uint16Array(10000);
+ for (let i = 0; i < x.length; ++i)
+ x[i] = i;
+ for (let i = 0; i < 500; ++i)
+ y.set(x);
+ for (let i = 0; i < 500; ++i)
+ x.set(y);
+}
+
+function test3() {
+ let x = new Int32Array(10000);
+ let y = new Uint32Array(10000);
+ for (let i = 0; i < x.length; ++i)
+ x[i] = i;
+ for (let i = 0; i < 500; ++i)
+ y.set(x);
+ for (let i = 0; i < 500; ++i)
+ x.set(y);
+}
+
+function test4() {
+ let x = new Uint8ClampedArray(10000);
+ let y = new Int8Array(10000);
+ for (let i = 0; i < x.length; ++i)
+ x[i] = i;
+ for (let i = 0; i < 500; ++i)
+ y.set(x);
+}
+
+test();
+test2();
+test3();
+test4();
Added: trunk/JSTests/stress/typed-array-prototype-set-order.js (0 => 286639)
--- trunk/JSTests/stress/typed-array-prototype-set-order.js (rev 0)
+++ trunk/JSTests/stress/typed-array-prototype-set-order.js 2021-12-08 03:59:13 UTC (rev 286639)
@@ -0,0 +1,13 @@
+function assert(b) {
+ if (!b)
+ throw new Error;
+}
+
+function foo(n) {
+ var array = new Uint8ClampedArray(n + 1);
+ for (var i = 0; i < n; ++i)
+ array[i] = 42 + i;
+ array.set(new Int8Array(array.buffer, 0, n), 1);
+ return array;
+}
+assert(foo(10).toString() === "42,42,43,44,45,46,47,48,49,50,51");
Added: trunk/JSTests/stress/typed-array-prototype-set.js (0 => 286639)
--- trunk/JSTests/stress/typed-array-prototype-set.js (rev 0)
+++ trunk/JSTests/stress/typed-array-prototype-set.js 2021-12-08 03:59:13 UTC (rev 286639)
@@ -0,0 +1,67 @@
+function assert(b) {
+ if (!b)
+ throw new Error;
+}
+
+function test1() {
+ let x = new Int8Array(1);
+ let y = new Uint8Array(1);
+ x[0] = -1;
+ y.set(x);
+ assert(y[0] === 255);
+}
+test1();
+
+function test2() {
+ let x = new Int8Array(1);
+ let y = new Uint8Array(1);
+ y[0] = 255;
+ x.set(y);
+ assert(x[0] === -1);
+}
+test2();
+
+function test3() {
+ let x = new Int16Array(1);
+ let y = new Uint16Array(1);
+ x[0] = -1;
+ y.set(x);
+ assert(y[0] === 65535);
+}
+test3();
+
+function test4() {
+ let x = new Int16Array(1);
+ let y = new Uint16Array(1);
+ y[0] = 65535;
+ x.set(y);
+ assert(x[0] === -1);
+}
+test4();
+
+function test5() {
+ let x = new Int32Array(1);
+ let y = new Uint32Array(1);
+ x[0] = -1;
+ y.set(x);
+ assert(y[0] === 4294967295);
+}
+test5();
+
+function test6() {
+ let x = new Int32Array(1);
+ let y = new Uint32Array(1);
+ y[0] = 4294967295;
+ x.set(y);
+ assert(x[0] === -1);
+}
+test6();
+
+function test7() {
+ let x = new Uint8ClampedArray(1);
+ let y = new Int8Array(1);
+ x[0] = 255;
+ y.set(x);
+ assert(y[0] === -1);
+}
+test7();
Modified: trunk/LayoutTests/ChangeLog (286638 => 286639)
--- trunk/LayoutTests/ChangeLog 2021-12-08 02:49:51 UTC (rev 286638)
+++ trunk/LayoutTests/ChangeLog 2021-12-08 03:59:13 UTC (rev 286639)
@@ -1,3 +1,13 @@
+2021-12-07 Saam Barati <[email protected]>
+
+ TypedArray prototype set should go down the fast path when using non clamped integer types of the same byte size
+ https://bugs.webkit.org/show_bug.cgi?id=233905
+
+ Reviewed by Keith Miller.
+
+ * js/script-tests/typedarray-set-overlapping-elements-of-same-size.js:
+ * js/typedarray-set-overlapping-elements-of-same-size-expected.txt:
+
2021-12-07 Yoshiaki Jitsukawa <[email protected]>
Support Animated JPEG-XL images
Modified: trunk/LayoutTests/js/script-tests/typedarray-set-overlapping-elements-of-same-size.js (286638 => 286639)
--- trunk/LayoutTests/js/script-tests/typedarray-set-overlapping-elements-of-same-size.js 2021-12-08 02:49:51 UTC (rev 286638)
+++ trunk/LayoutTests/js/script-tests/typedarray-set-overlapping-elements-of-same-size.js 2021-12-08 03:59:13 UTC (rev 286639)
@@ -18,6 +18,6 @@
return array;
}
-shouldBe("foo(10)", "[42,42,42,42,42,42,42,42,42,42,42]");
+shouldBe("foo(10)", "[42,42,43,44,45,46,47,48,49,50,51]");
shouldBe("bar(10)", "[42,43,44,45,46,47,48,49,50,51,51]");
Modified: trunk/LayoutTests/js/typedarray-set-overlapping-elements-of-same-size-expected.txt (286638 => 286639)
--- trunk/LayoutTests/js/typedarray-set-overlapping-elements-of-same-size-expected.txt 2021-12-08 02:49:51 UTC (rev 286638)
+++ trunk/LayoutTests/js/typedarray-set-overlapping-elements-of-same-size-expected.txt 2021-12-08 03:59:13 UTC (rev 286639)
@@ -3,7 +3,7 @@
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-PASS foo(10) is [42,42,42,42,42,42,42,42,42,42,42]
+PASS foo(10) is [42,42,43,44,45,46,47,48,49,50,51]
PASS bar(10) is [42,43,44,45,46,47,48,49,50,51,51]
PASS successfullyParsed is true
Modified: trunk/Source/_javascript_Core/ChangeLog (286638 => 286639)
--- trunk/Source/_javascript_Core/ChangeLog 2021-12-08 02:49:51 UTC (rev 286638)
+++ trunk/Source/_javascript_Core/ChangeLog 2021-12-08 03:59:13 UTC (rev 286639)
@@ -1,3 +1,20 @@
+2021-12-07 Saam Barati <[email protected]>
+
+ TypedArray prototype set should go down the fast path when using non clamped integer types of the same byte size
+ https://bugs.webkit.org/show_bug.cgi?id=233905
+
+ Reviewed by Keith Miller.
+
+ We can use memmove in this scenario because the bitpattern of the
+ data between the signed and unsigned values will be the same.
+
+ This patch also fixes a bug where we were looking at the wrong
+ pointer when determining to do a forward or backwards loop in
+ our memmove. We were looking at the vector instead of vector+offset.
+
+ * runtime/JSGenericTypedArrayViewInlines.h:
+ (JSC::JSGenericTypedArrayView<Adaptor>::set):
+
2021-12-07 Ross Kirsling <[email protected]>
[JSC] Add LLInt IC for try_get_by_id of own cacheable value
Modified: trunk/Source/_javascript_Core/runtime/JSGenericTypedArrayViewInlines.h (286638 => 286639)
--- trunk/Source/_javascript_Core/runtime/JSGenericTypedArrayViewInlines.h 2021-12-08 02:49:51 UTC (rev 286638)
+++ trunk/Source/_javascript_Core/runtime/JSGenericTypedArrayViewInlines.h 2021-12-08 03:59:13 UTC (rev 286639)
@@ -216,7 +216,7 @@
// Handle cases (1) and (2A).
if (!hasArrayBuffer() || !other->hasArrayBuffer()
|| existingBuffer() != other->existingBuffer()
- || (elementSize == otherElementSize && vector() <= other->vector())
+ || (elementSize == otherElementSize && (static_cast<void*>(typedVector() + offset) <= static_cast<void*>(other->typedVector() + otherOffset)))
|| type == CopyType::LeftToRight) {
for (size_t i = 0; i < length; ++i) {
setIndexQuicklyToNativeValue(
@@ -255,34 +255,34 @@
VM& vm = globalObject->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
- auto memmoveFastPath = [&] (auto* other) {
+ auto memmoveFastPath = [&] (JSArrayBufferView* other) {
// The super fast case: we can just memmove since we're the same underlying storage type.
length = std::min(length, other->length());
- RELEASE_ASSERT(other->canAccessRangeQuickly(objectOffset, length));
bool success = validateRange(globalObject, offset, length);
EXCEPTION_ASSERT(!scope.exception() == success);
if (!success)
return false;
- RELEASE_ASSERT((std::is_same_v<decltype(typedVector()), decltype(other->typedVector())>));
- memmove(typedVector() + offset, other->typedVector() + objectOffset, length * elementSize);
+ RELEASE_ASSERT(JSC::elementSize(Adaptor::typeValue) == JSC::elementSize(other->classInfo(vm)->typedArrayStorageType));
+ memmove(typedVector() + offset, bitwise_cast<typename Adaptor::Type*>(other->vector()) + objectOffset, length * elementSize);
return true;
};
const ClassInfo* ci = object->classInfo(vm);
if (ci->typedArrayStorageType == Adaptor::typeValue)
- return memmoveFastPath(jsCast<JSGenericTypedArrayView*>(object));
+ return memmoveFastPath(jsCast<JSArrayBufferView*>(object));
auto isSomeUint8 = [] (TypedArrayType type) {
return type == TypedArrayType::TypeUint8 || type == TypedArrayType::TypeUint8Clamped;
};
- if (isSomeUint8(ci->typedArrayStorageType) && isSomeUint8(Adaptor::typeValue)) {
- if (ci->typedArrayStorageType == TypedArrayType::TypeUint8)
- return memmoveFastPath(jsCast<JSGenericTypedArrayView<Uint8Adaptor>*>(object));
- return memmoveFastPath(jsCast<JSGenericTypedArrayView<Uint8ClampedAdaptor>*>(object));
- }
-
+
+ if (isSomeUint8(ci->typedArrayStorageType) && isSomeUint8(Adaptor::typeValue))
+ return memmoveFastPath(jsCast<JSArrayBufferView*>(object));
+
+ if (isInt(Adaptor::typeValue) && isInt(ci->typedArrayStorageType) && !isClamped(Adaptor::typeValue) && JSC::elementSize(Adaptor::typeValue) == JSC::elementSize(ci->typedArrayStorageType))
+ return memmoveFastPath(jsCast<JSArrayBufferView*>(object));
+
switch (ci->typedArrayStorageType) {
case TypeInt8:
RELEASE_AND_RETURN(scope, setWithSpecificType<Int8Adaptor>(