Skip to content

Commit

Permalink
use createUninitialized when creating TypedArray from another array
Browse files Browse the repository at this point in the history
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: http://svn.webkit.org/repository/webkit/trunk@123935 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
commit-queue@webkit.org committed Jul 27, 2012
1 parent 5193ce9 commit 108c43a
Show file tree
Hide file tree
Showing 17 changed files with 243 additions and 5 deletions.
13 changes: 13 additions & 0 deletions LayoutTests/ChangeLog
Original file line number Diff line number Diff line change
@@ -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
Expand Down
30 changes: 30 additions & 0 deletions LayoutTests/fast/canvas/webgl/array-constructor-expected.txt
Original file line number Diff line number Diff line change
@@ -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

36 changes: 36 additions & 0 deletions LayoutTests/fast/canvas/webgl/array-constructor.html
Original file line number Diff line number Diff line change
@@ -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>

17 changes: 17 additions & 0 deletions PerformanceTests/Bindings/typed-array-construct-from-array.html
Original file line number Diff line number Diff line change
@@ -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>

9 changes: 9 additions & 0 deletions PerformanceTests/ChangeLog
Original file line number Diff line number Diff line change
@@ -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
Expand Down
44 changes: 44 additions & 0 deletions Source/WTF/ChangeLog
Original file line number Diff line number Diff line change
@@ -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
Expand Down
9 changes: 9 additions & 0 deletions Source/WTF/wtf/Float32Array.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ class Float32Array : public TypedArrayBase<float> {
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); }

Expand Down Expand Up @@ -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)
{
Expand Down
9 changes: 9 additions & 0 deletions Source/WTF/wtf/Float64Array.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ class Float64Array : public TypedArrayBase<double> {
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); }

Expand Down Expand Up @@ -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)
{
Expand Down
9 changes: 9 additions & 0 deletions Source/WTF/wtf/Int16Array.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ class Int16Array : public IntegralTypedArrayBase<short> {
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); }
Expand Down Expand Up @@ -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)
{
Expand Down
9 changes: 9 additions & 0 deletions Source/WTF/wtf/Int32Array.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ class Int32Array : public IntegralTypedArrayBase<int> {
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); }
Expand Down Expand Up @@ -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)
{
Expand Down
9 changes: 9 additions & 0 deletions Source/WTF/wtf/Int8Array.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ class Int8Array : public IntegralTypedArrayBase<signed char> {
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); }
Expand Down Expand Up @@ -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)
{
Expand Down
9 changes: 9 additions & 0 deletions Source/WTF/wtf/Uint16Array.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ class Uint16Array : public IntegralTypedArrayBase<unsigned short> {
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); }
Expand Down Expand Up @@ -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)
{
Expand Down
9 changes: 9 additions & 0 deletions Source/WTF/wtf/Uint32Array.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ class Uint32Array : public IntegralTypedArrayBase<unsigned int> {
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); }
Expand Down Expand Up @@ -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)
{
Expand Down
9 changes: 9 additions & 0 deletions Source/WTF/wtf/Uint8Array.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ class Uint8Array : public IntegralTypedArrayBase<unsigned char> {
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); }
Expand Down Expand Up @@ -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)
{
Expand Down
5 changes: 2 additions & 3 deletions Source/WTF/wtf/Uint8ClampedArray.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,8 @@ class Uint8ClampedArray : public Uint8Array {
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
Expand Down
18 changes: 18 additions & 0 deletions Source/WebCore/ChangeLog
Original file line number Diff line number Diff line change
@@ -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.
Expand Down
4 changes: 2 additions & 2 deletions Source/WebCore/bindings/js/JSArrayBufferViewHelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 108c43a

Please sign in to comment.