Title: [183291] trunk/Source/_javascript_Core
- Revision
- 183291
- Author
- [email protected]
- Date
- 2015-04-24 16:29:32 -0700 (Fri, 24 Apr 2015)
Log Message
[JSC] When inserting a NaN into a Int32 array, we convert it to DoubleArray then to ContiguousArray
https://bugs.webkit.org/show_bug.cgi?id=144169
Patch by Benjamin Poulain <[email protected]> on 2015-04-24
Reviewed by Geoffrey Garen.
* runtime/JSObject.cpp:
(JSC::JSObject::convertInt32ForValue):
DoubleArray do not store NaN, they are used for holes.
What happened was:
1) We fail to insert the NaN in the Int32 array because it is a double.
2) We were converting the array to DoubleArray.
3) We were trying to insert the value again. We would fail again because
DoubleArray does not store NaN.
4) We would convert the DoubleArrayt to Contiguous Array, converting the values
to boxed values.
* tests/stress/int32array-transition-on-nan.js: Added.
The behavior is not really observable. This only test nothing crashes in those
cases.
(insertNaNWhileFilling):
(testInsertNaNWhileFilling):
(insertNaNAfterFilling):
(testInsertNaNAfterFilling):
(pushNaNWhileFilling):
(testPushNaNWhileFilling):
Modified Paths
Added Paths
Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (183290 => 183291)
--- trunk/Source/_javascript_Core/ChangeLog 2015-04-24 23:11:07 UTC (rev 183290)
+++ trunk/Source/_javascript_Core/ChangeLog 2015-04-24 23:29:32 UTC (rev 183291)
@@ -1,3 +1,32 @@
+2015-04-24 Benjamin Poulain <[email protected]>
+
+ [JSC] When inserting a NaN into a Int32 array, we convert it to DoubleArray then to ContiguousArray
+ https://bugs.webkit.org/show_bug.cgi?id=144169
+
+ Reviewed by Geoffrey Garen.
+
+ * runtime/JSObject.cpp:
+ (JSC::JSObject::convertInt32ForValue):
+ DoubleArray do not store NaN, they are used for holes.
+ What happened was:
+ 1) We fail to insert the NaN in the Int32 array because it is a double.
+ 2) We were converting the array to DoubleArray.
+ 3) We were trying to insert the value again. We would fail again because
+ DoubleArray does not store NaN.
+ 4) We would convert the DoubleArrayt to Contiguous Array, converting the values
+ to boxed values.
+
+ * tests/stress/int32array-transition-on-nan.js: Added.
+ The behavior is not really observable. This only test nothing crashes in those
+ cases.
+
+ (insertNaNWhileFilling):
+ (testInsertNaNWhileFilling):
+ (insertNaNAfterFilling):
+ (testInsertNaNAfterFilling):
+ (pushNaNWhileFilling):
+ (testPushNaNWhileFilling):
+
2015-04-21 Geoffrey Garen <[email protected]>
It shouldn't take 1846 lines of code and 5 FIXMEs to sort an array.
Modified: trunk/Source/_javascript_Core/runtime/JSObject.cpp (183290 => 183291)
--- trunk/Source/_javascript_Core/runtime/JSObject.cpp 2015-04-24 23:11:07 UTC (rev 183290)
+++ trunk/Source/_javascript_Core/runtime/JSObject.cpp 2015-04-24 23:29:32 UTC (rev 183291)
@@ -969,7 +969,7 @@
{
ASSERT(!value.isInt32());
- if (value.isDouble()) {
+ if (value.isDouble() && !std::isnan(value.asDouble())) {
convertInt32ToDouble(vm);
return;
}
Added: trunk/Source/_javascript_Core/tests/stress/int32array-transition-on-nan.js (0 => 183291)
--- trunk/Source/_javascript_Core/tests/stress/int32array-transition-on-nan.js (rev 0)
+++ trunk/Source/_javascript_Core/tests/stress/int32array-transition-on-nan.js 2015-04-24 23:29:32 UTC (rev 183291)
@@ -0,0 +1,88 @@
+function insertNaNWhileFilling()
+{
+ var array = new Array(6);
+ for (var i = 0; i < 4; ++i)
+ array[i] = i;
+ array[5] = NaN;
+ return array;
+}
+noInline(insertNaNWhileFilling);
+
+function testInsertNaNWhileFilling()
+{
+ var array = insertNaNWhileFilling();
+ for (var i = 0; i < 4; ++i) {
+ var value = array[i];
+ if (value !== i) {
+ throw "Failed testInsertNaNWhileFilling, value = " + value + " instead of " + i;
+ }
+ }
+ var nan = array[5];
+ if (!Number.isNaN(nan))
+ throw "Failed testInsertNaNWhileFilling, array[5] is " + nan + " instead of NaN";
+}
+noInline(testInsertNaNWhileFilling);
+
+for (var i = 0; i < 1e4; ++i) {
+ testInsertNaNWhileFilling();
+}
+
+
+function insertNaNAfterFilling()
+{
+ var array = new Array(6);
+ for (var i = 0; i < 5; ++i)
+ array[i] = i;
+ array[5] = NaN;
+ return array;
+}
+noInline(insertNaNAfterFilling);
+
+function testInsertNaNAfterFilling()
+{
+ var array = insertNaNAfterFilling();
+ for (var i = 0; i < 4; ++i) {
+ var value = array[i];
+ if (value !== i) {
+ throw "Failed testInsertNaNAfterFilling, value = " + value + " instead of " + i;
+ }
+ }
+ var nan = array[5];
+ if (!Number.isNaN(nan))
+ throw "Failed testInsertNaNAfterFilling, array[5] is " + nan + " instead of NaN";
+}
+noInline(testInsertNaNAfterFilling);
+
+for (var i = 0; i < 1e4; ++i) {
+ testInsertNaNAfterFilling();
+}
+
+
+function pushNaNWhileFilling()
+{
+ var array = [];
+ for (var i = 0; i < 5; ++i)
+ array.push(i);
+ array.push(NaN);
+ return array;
+}
+noInline(pushNaNWhileFilling);
+
+function testPushNaNWhileFilling()
+{
+ var array = pushNaNWhileFilling();
+ for (var i = 0; i < 4; ++i) {
+ var value = array[i];
+ if (value !== i) {
+ throw "Failed testPushNaNWhileFilling, value = " + value + " instead of " + i;
+ }
+ }
+ var nan = array[5];
+ if (!Number.isNaN(nan))
+ throw "Failed testPushNaNWhileFilling, array[5] is " + nan + " instead of NaN";
+}
+noInline(testPushNaNWhileFilling);
+
+for (var i = 0; i < 1e4; ++i) {
+ testPushNaNWhileFilling();
+}
\ No newline at end of file
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes