use createUninitialized when creating TypedArray from another array
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 27 Jul 2012 23:32:19 +0000 (23:32 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 27 Jul 2012 23:32:19 +0000 (23:32 +0000)
https://bugs.webkit.org/show_bug.cgi?id=92518

Patch by Arnaud Renevier <a.renevier@sisa.samsung.com> on 2012-07-27
Reviewed by Kenneth Russell.

PerformanceTests:

* Bindings/typed-array-construct-from-array.html: Added.

Source/WebCore:

When creating a Typed Array from another array, we fill it with values
from the source array. So, we can create it uninitialized. This is
make constructor about 35% faster when constructed with another typed
array.

Test: fast/canvas/webgl/array-constructor.html

* bindings/js/JSArrayBufferViewHelper.h:
(WebCore::constructArrayBufferViewWithTypedArrayArgument):
(WebCore::constructArrayBufferView):

Source/WTF:

Expose a createUninitialized static method on TypedArray classes.

* wtf/Float32Array.h:
(Float32Array):
(WTF::Float32Array::createUninitialized):
(WTF):
* wtf/Float64Array.h:
(Float64Array):
(WTF::Float64Array::createUninitialized):
(WTF):
* wtf/Int16Array.h:
(Int16Array):
(WTF::Int16Array::createUninitialized):
(WTF):
* wtf/Int32Array.h:
(Int32Array):
(WTF::Int32Array::createUninitialized):
(WTF):
* wtf/Int8Array.h:
(Int8Array):
(WTF::Int8Array::createUninitialized):
(WTF):
* wtf/Uint16Array.h:
(Uint16Array):
(WTF::Uint16Array::createUninitialized):
(WTF):
* wtf/Uint32Array.h:
(Uint32Array):
(WTF::Uint32Array::createUninitialized):
(WTF):
* wtf/Uint8Array.h:
(Uint8Array):
(WTF::Uint8Array::createUninitialized):
(WTF):
* wtf/Uint8ClampedArray.h:
(Uint8ClampedArray):

LayoutTests:

Add test to check that constructing a Typed Array with nan values does
not result in random values.

* fast/canvas/webgl/array-constructor-expected.txt: Added.
* fast/canvas/webgl/array-constructor.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@123935 268f45cc-cd09-0410-ab3c-d52691b4dbfc

17 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/canvas/webgl/array-constructor-expected.txt [new file with mode: 0644]
LayoutTests/fast/canvas/webgl/array-constructor.html [new file with mode: 0644]
PerformanceTests/Bindings/typed-array-construct-from-array.html [new file with mode: 0644]
PerformanceTests/ChangeLog
Source/WTF/ChangeLog
Source/WTF/wtf/Float32Array.h
Source/WTF/wtf/Float64Array.h
Source/WTF/wtf/Int16Array.h
Source/WTF/wtf/Int32Array.h
Source/WTF/wtf/Int8Array.h
Source/WTF/wtf/Uint16Array.h
Source/WTF/wtf/Uint32Array.h
Source/WTF/wtf/Uint8Array.h
Source/WTF/wtf/Uint8ClampedArray.h
Source/WebCore/ChangeLog
Source/WebCore/bindings/js/JSArrayBufferViewHelper.h

index c37a854..77f62d1 100644 (file)
@@ -1,3 +1,16 @@
+2012-07-27  Arnaud Renevier  <a.renevier@sisa.samsung.com>
+
+        use createUninitialized when creating TypedArray from another array
+        https://bugs.webkit.org/show_bug.cgi?id=92518
+
+        Reviewed by Kenneth Russell.
+
+        Add test to check that constructing a Typed Array with nan values does
+        not result in random values.
+
+        * fast/canvas/webgl/array-constructor-expected.txt: Added.
+        * fast/canvas/webgl/array-constructor.html: Added.
+
 2012-07-27  Caio Marcelo de Oliveira Filho  <caio.oliveira@openbossa.org>
 
         [Qt] Remaining rebaselines after new test fonts
diff --git a/LayoutTests/fast/canvas/webgl/array-constructor-expected.txt b/LayoutTests/fast/canvas/webgl/array-constructor-expected.txt
new file mode 100644 (file)
index 0000000..47db915
--- /dev/null
@@ -0,0 +1,30 @@
+Verifies that when constructing WebGLArray with nan values, it results in a 0
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+PASS 10 is 10
+PASS 0 is 0
+PASS 0 is 0
+PASS 0 is 0
+PASS 0 is 0
+PASS 0 is 0
+PASS 0 is 0
+PASS 0 is 0
+PASS 0 is 0
+PASS 0 is 0
+PASS 0 is 0
+PASS 10 is 10
+PASS 0 is 0
+PASS 0 is 0
+PASS 0 is 0
+PASS 0 is 0
+PASS 0 is 0
+PASS 0 is 0
+PASS 0 is 0
+PASS 0 is 0
+PASS 0 is 0
+PASS 0 is 0
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/canvas/webgl/array-constructor.html b/LayoutTests/fast/canvas/webgl/array-constructor.html
new file mode 100644 (file)
index 0000000..f379e64
--- /dev/null
@@ -0,0 +1,36 @@
+<html>
+<head>
+<script src="../../js/resources/js-test-pre.js"></script>
+<script src="resources/webgl-test.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+
+<script>
+
+description("Verifies that when constructing WebGLArray with nan values, it results in a 0");
+
+var source, target, idx;
+
+source = new Array(10);
+
+target = new Uint8Array(source);
+shouldBe(target.length.toString(), source.length.toString())
+for (idx = 0; idx < target.length; idx++) {
+    shouldBeZero(target[idx].toString());
+}
+
+source = {length: 10};
+target = new Uint8Array(source);
+shouldBe(target.length.toString(), source.length.toString())
+for (idx = 0; idx < target.length; idx++) {
+    shouldBeZero(target[idx].toString());
+}
+
+</script>
+
+<script src="../../js/resources/js-test-post.js"></script>
+</body>
+</html>
+
diff --git a/PerformanceTests/Bindings/typed-array-construct-from-array.html b/PerformanceTests/Bindings/typed-array-construct-from-array.html
new file mode 100644 (file)
index 0000000..4a8e893
--- /dev/null
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<body>
+<script src="../resources/runner.js"></script>
+<script>
+
+var length = 10000000;
+var source = new Array(length);
+for (var i = 0; i < length; i++) {
+    source[i] = i;
+}
+
+PerfTestRunner.run(function() {
+    var target = new Uint8Array(source);
+});
+</script>
+</body>
+
index c8d1c88..fd5b502 100644 (file)
@@ -1,3 +1,12 @@
+2012-07-27  Arnaud Renevier  <a.renevier@sisa.samsung.com>
+
+        use createUninitialized when creating TypedArray from another array
+        https://bugs.webkit.org/show_bug.cgi?id=92518
+
+        Reviewed by Kenneth Russell.
+
+        * Bindings/typed-array-construct-from-array.html: Added.
+
 2012-07-27  Ryosuke Niwa  <rniwa@webkit.org>
 
         Add more Russian replay performance tests
index ed8e80e..ccd1325 100644 (file)
@@ -1,3 +1,47 @@
+2012-07-27  Arnaud Renevier  <a.renevier@sisa.samsung.com>
+
+        use createUninitialized when creating TypedArray from another array
+        https://bugs.webkit.org/show_bug.cgi?id=92518
+
+        Reviewed by Kenneth Russell.
+
+        Expose a createUninitialized static method on TypedArray classes.
+
+        * wtf/Float32Array.h:
+        (Float32Array):
+        (WTF::Float32Array::createUninitialized):
+        (WTF):
+        * wtf/Float64Array.h:
+        (Float64Array):
+        (WTF::Float64Array::createUninitialized):
+        (WTF):
+        * wtf/Int16Array.h:
+        (Int16Array):
+        (WTF::Int16Array::createUninitialized):
+        (WTF):
+        * wtf/Int32Array.h:
+        (Int32Array):
+        (WTF::Int32Array::createUninitialized):
+        (WTF):
+        * wtf/Int8Array.h:
+        (Int8Array):
+        (WTF::Int8Array::createUninitialized):
+        (WTF):
+        * wtf/Uint16Array.h:
+        (Uint16Array):
+        (WTF::Uint16Array::createUninitialized):
+        (WTF):
+        * wtf/Uint32Array.h:
+        (Uint32Array):
+        (WTF::Uint32Array::createUninitialized):
+        (WTF):
+        * wtf/Uint8Array.h:
+        (Uint8Array):
+        (WTF::Uint8Array::createUninitialized):
+        (WTF):
+        * wtf/Uint8ClampedArray.h:
+        (Uint8ClampedArray):
+
 2012-07-27  Patrick Gansterer  <paroga@webkit.org>
 
         [WINCE] Use macros from ICU instead of defining the same functionality again
index ebf79ae..47204ec 100644 (file)
@@ -38,6 +38,10 @@ public:
     static inline PassRefPtr<Float32Array> create(const float* array, unsigned length);
     static inline PassRefPtr<Float32Array> create(PassRefPtr<ArrayBuffer>, unsigned byteOffset, unsigned length);
 
+    // Should only be used when it is known the entire array will be filled. Do
+    // not return these results directly to JavaScript without filling first.
+    static inline PassRefPtr<Float32Array> createUninitialized(unsigned length);
+
     // Can’t use "using" here due to a bug in the RVCT compiler.
     bool set(TypedArrayBase<float>* array, unsigned offset) { return TypedArrayBase<float>::set(array, offset); }
 
@@ -79,6 +83,11 @@ PassRefPtr<Float32Array> Float32Array::create(PassRefPtr<ArrayBuffer> buffer, un
     return TypedArrayBase<float>::create<Float32Array>(buffer, byteOffset, length);
 }
 
+PassRefPtr<Float32Array> Float32Array::createUninitialized(unsigned length)
+{
+    return TypedArrayBase<float>::createUninitialized<Float32Array>(length);
+}
+
 Float32Array::Float32Array(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length)
     : TypedArrayBase<float>(buffer, byteOffset, length)
 {
index 15af161..1d9a9c8 100644 (file)
@@ -38,6 +38,10 @@ public:
     static inline PassRefPtr<Float64Array> create(const double* array, unsigned length);
     static inline PassRefPtr<Float64Array> create(PassRefPtr<ArrayBuffer>, unsigned byteOffset, unsigned length);
 
+    // Should only be used when it is known the entire array will be filled. Do
+    // not return these results directly to JavaScript without filling first.
+    static inline PassRefPtr<Float64Array> createUninitialized(unsigned length);
+
     // Can’t use "using" here due to a bug in the RVCT compiler.
     bool set(TypedArrayBase<double>* array, unsigned offset) { return TypedArrayBase<double>::set(array, offset); }
 
@@ -79,6 +83,11 @@ PassRefPtr<Float64Array> Float64Array::create(PassRefPtr<ArrayBuffer> buffer, un
     return TypedArrayBase<double>::create<Float64Array>(buffer, byteOffset, length);
 }
 
+PassRefPtr<Float64Array> Float64Array::createUninitialized(unsigned length)
+{
+    return TypedArrayBase<double>::createUninitialized<Float64Array>(length);
+}
+
 Float64Array::Float64Array(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length)
     : TypedArrayBase<double>(buffer, byteOffset, length)
 {
index 50e9aa3..be98583 100644 (file)
@@ -38,6 +38,10 @@ public:
     static inline PassRefPtr<Int16Array> create(const short* array, unsigned length);
     static inline PassRefPtr<Int16Array> create(PassRefPtr<ArrayBuffer>, unsigned byteOffset, unsigned length);
 
+    // Should only be used when it is known the entire array will be filled. Do
+    // not return these results directly to JavaScript without filling first.
+    static inline PassRefPtr<Int16Array> createUninitialized(unsigned length);
+
     // Can’t use "using" here due to a bug in the RVCT compiler.
     bool set(TypedArrayBase<short>* array, unsigned offset) { return TypedArrayBase<short>::set(array, offset); }
     void set(unsigned index, double value) { IntegralTypedArrayBase<short>::set(index, value); }
@@ -73,6 +77,11 @@ PassRefPtr<Int16Array> Int16Array::create(PassRefPtr<ArrayBuffer> buffer, unsign
     return TypedArrayBase<short>::create<Int16Array>(buffer, byteOffset, length);
 }
 
+PassRefPtr<Int16Array> Int16Array::createUninitialized(unsigned length)
+{
+    return TypedArrayBase<short>::createUninitialized<Int16Array>(length);
+}
+
 Int16Array::Int16Array(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length)
     : IntegralTypedArrayBase<short>(buffer, byteOffset, length)
 {
index c2624c8..99bce1a 100644 (file)
@@ -37,6 +37,10 @@ public:
     static inline PassRefPtr<Int32Array> create(const int* array, unsigned length);
     static inline PassRefPtr<Int32Array> create(PassRefPtr<ArrayBuffer>, unsigned byteOffset, unsigned length);
 
+    // Should only be used when it is known the entire array will be filled. Do
+    // not return these results directly to JavaScript without filling first.
+    static inline PassRefPtr<Int32Array> createUninitialized(unsigned length);
+
     // Can’t use "using" here due to a bug in the RVCT compiler.
     bool set(TypedArrayBase<int>* array, unsigned offset) { return TypedArrayBase<int>::set(array, offset); }
     void set(unsigned index, double value) { IntegralTypedArrayBase<int>::set(index, value); }
@@ -72,6 +76,11 @@ PassRefPtr<Int32Array> Int32Array::create(PassRefPtr<ArrayBuffer> buffer, unsign
     return TypedArrayBase<int>::create<Int32Array>(buffer, byteOffset, length);
 }
 
+PassRefPtr<Int32Array> Int32Array::createUninitialized(unsigned length)
+{
+    return TypedArrayBase<int>::createUninitialized<Int32Array>(length);
+}
+
 Int32Array::Int32Array(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length)
     : IntegralTypedArrayBase<int>(buffer, byteOffset, length)
 {
index ed8ba6f..bb3e37e 100644 (file)
@@ -39,6 +39,10 @@ public:
     static inline PassRefPtr<Int8Array> create(const signed char* array, unsigned length);
     static inline PassRefPtr<Int8Array> create(PassRefPtr<ArrayBuffer>, unsigned byteOffset, unsigned length);
 
+    // Should only be used when it is known the entire array will be filled. Do
+    // not return these results directly to JavaScript without filling first.
+    static inline PassRefPtr<Int8Array> createUninitialized(unsigned length);
+
     // Can’t use "using" here due to a bug in the RVCT compiler.
     bool set(TypedArrayBase<signed char>* array, unsigned offset) { return TypedArrayBase<signed char>::set(array, offset); }
     void set(unsigned index, double value) { IntegralTypedArrayBase<signed char>::set(index, value); }
@@ -74,6 +78,11 @@ PassRefPtr<Int8Array> Int8Array::create(PassRefPtr<ArrayBuffer> buffer, unsigned
     return TypedArrayBase<signed char>::create<Int8Array>(buffer, byteOffset, length);
 }
 
+PassRefPtr<Int8Array> Int8Array::createUninitialized(unsigned length)
+{
+    return TypedArrayBase<signed char>::createUninitialized<Int8Array>(length);
+}
+
 Int8Array::Int8Array(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length)
     : IntegralTypedArrayBase<signed char>(buffer, byteOffset, length)
 {
index f0044f6..1444693 100644 (file)
@@ -39,6 +39,10 @@ public:
     static inline PassRefPtr<Uint16Array> create(const unsigned short* array, unsigned length);
     static inline PassRefPtr<Uint16Array> create(PassRefPtr<ArrayBuffer>, unsigned byteOffset, unsigned length);
 
+    // Should only be used when it is known the entire array will be filled. Do
+    // not return these results directly to JavaScript without filling first.
+    static inline PassRefPtr<Uint16Array> createUninitialized(unsigned length);
+
     // Can’t use "using" here due to a bug in the RVCT compiler.
     bool set(TypedArrayBase<unsigned short>* array, unsigned offset) { return TypedArrayBase<unsigned short>::set(array, offset); }
     void set(unsigned index, double value) { IntegralTypedArrayBase<unsigned short>::set(index, value); }
@@ -74,6 +78,11 @@ PassRefPtr<Uint16Array> Uint16Array::create(PassRefPtr<ArrayBuffer> buffer, unsi
     return TypedArrayBase<unsigned short>::create<Uint16Array>(buffer, byteOffset, length);
 }
 
+PassRefPtr<Uint16Array> Uint16Array::createUninitialized(unsigned length)
+{
+    return TypedArrayBase<unsigned short>::createUninitialized<Uint16Array>(length);
+}
+
 Uint16Array::Uint16Array(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length)
     : IntegralTypedArrayBase<unsigned short>(buffer, byteOffset, length)
 {
index 0e35546..1e5b028 100644 (file)
@@ -39,6 +39,10 @@ public:
     static inline PassRefPtr<Uint32Array> create(const unsigned int* array, unsigned length);
     static inline PassRefPtr<Uint32Array> create(PassRefPtr<ArrayBuffer>, unsigned byteOffset, unsigned length);
 
+    // Should only be used when it is known the entire array will be filled. Do
+    // not return these results directly to JavaScript without filling first.
+    static inline PassRefPtr<Uint32Array> createUninitialized(unsigned length);
+
     // Can’t use "using" here due to a bug in the RVCT compiler.
     bool set(TypedArrayBase<unsigned int>* array, unsigned offset) { return TypedArrayBase<unsigned int>::set(array, offset); }
     void set(unsigned index, double value) { IntegralTypedArrayBase<unsigned int>::set(index, value); }
@@ -74,6 +78,11 @@ PassRefPtr<Uint32Array> Uint32Array::create(PassRefPtr<ArrayBuffer> buffer, unsi
     return TypedArrayBase<unsigned int>::create<Uint32Array>(buffer, byteOffset, length);
 }
 
+PassRefPtr<Uint32Array> Uint32Array::createUninitialized(unsigned length)
+{
+    return TypedArrayBase<unsigned int>::createUninitialized<Uint32Array>(length);
+}
+
 Uint32Array::Uint32Array(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length)
     : IntegralTypedArrayBase<unsigned int>(buffer, byteOffset, length)
 {
index fc4417d..a23d1eb 100644 (file)
@@ -39,6 +39,10 @@ public:
     static inline PassRefPtr<Uint8Array> create(const unsigned char* array, unsigned length);
     static inline PassRefPtr<Uint8Array> create(PassRefPtr<ArrayBuffer>, unsigned byteOffset, unsigned length);
 
+    // Should only be used when it is known the entire array will be filled. Do
+    // not return these results directly to JavaScript without filling first.
+    static inline PassRefPtr<Uint8Array> createUninitialized(unsigned length);
+
     // Can’t use "using" here due to a bug in the RVCT compiler.
     bool set(TypedArrayBase<unsigned char>* array, unsigned offset) { return TypedArrayBase<unsigned char>::set(array, offset); }
     void set(unsigned index, double value) { IntegralTypedArrayBase<unsigned char>::set(index, value); }
@@ -74,6 +78,11 @@ PassRefPtr<Uint8Array> Uint8Array::create(PassRefPtr<ArrayBuffer> buffer, unsign
     return TypedArrayBase<unsigned char>::create<Uint8Array>(buffer, byteOffset, length);
 }
 
+PassRefPtr<Uint8Array> Uint8Array::createUninitialized(unsigned length)
+{
+    return TypedArrayBase<unsigned char>::createUninitialized<Uint8Array>(length);
+}
+
 Uint8Array::Uint8Array(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length)
 : IntegralTypedArrayBase<unsigned char>(buffer, byteOffset, length)
 {
index 9ac1564..d63a4e6 100644 (file)
@@ -38,9 +38,8 @@ public:
     static inline PassRefPtr<Uint8ClampedArray> create(const unsigned char* array, unsigned length);
     static inline PassRefPtr<Uint8ClampedArray> create(PassRefPtr<ArrayBuffer>, unsigned byteOffset, unsigned length);
 
-    // Should only be used for WebCore-internal use (like filters and
-    // getImageData) when it is known the entire array will be filled.
-    // Do not return these results directly to JavaScript.
+    // Should only be used when it is known the entire array will be filled. Do
+    // not return these results directly to JavaScript without filling first.
     static inline PassRefPtr<Uint8ClampedArray> createUninitialized(unsigned length);
 
     // It's only needed to potentially call this method if the array
index 8effbbd..9dad18c 100644 (file)
@@ -1,3 +1,21 @@
+2012-07-27  Arnaud Renevier  <a.renevier@sisa.samsung.com>
+
+        use createUninitialized when creating TypedArray from another array
+        https://bugs.webkit.org/show_bug.cgi?id=92518
+
+        Reviewed by Kenneth Russell.
+
+        When creating a Typed Array from another array, we fill it with values
+        from the source array. So, we can create it uninitialized. This is
+        make constructor about 35% faster when constructed with another typed
+        array.
+
+        Test: fast/canvas/webgl/array-constructor.html
+
+        * bindings/js/JSArrayBufferViewHelper.h:
+        (WebCore::constructArrayBufferViewWithTypedArrayArgument):
+        (WebCore::constructArrayBufferView):
+
 2012-07-27  Eli Fidler  <efidler@rim.com>
 
         [BlackBerry] Adapt to change in the FontInfo platform API.
index 76e6116..8c6f426 100644 (file)
@@ -99,7 +99,7 @@ PassRefPtr<C> constructArrayBufferViewWithTypedArrayArgument(JSC::ExecState* exe
         return 0;
 
     uint32_t length = asObject(exec->argument(0))->get(exec, JSC::Identifier(exec, "length")).toUInt32(exec);
-    RefPtr<C> array = C::create(length);
+    RefPtr<C> array = C::createUninitialized(length);
     if (!array) {
         setDOMException(exec, INDEX_SIZE_ERR);
         return array;
@@ -212,7 +212,7 @@ PassRefPtr<C> constructArrayBufferView(JSC::ExecState* exec)
 
         JSC::JSObject* srcArray = asObject(exec->argument(0));
         uint32_t length = srcArray->get(exec, JSC::Identifier(exec, "length")).toUInt32(exec);
-        RefPtr<C> array = C::create(length);
+        RefPtr<C> array = C::createUninitialized(length);
         if (!array) {
             setDOMException(exec, INDEX_SIZE_ERR);
             return array;