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

Reply via email to