Reviewers: Jakob,

Description:
Fix EnsureCanContainElements to properly handle double values.

[email protected]
BUG=v8:2170
TEST=test/mjsunit/regress/regress-2170.js


Please review this at https://chromiumcodereview.appspot.com/10542084/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files:
  M src/objects-inl.h
  A test/mjsunit/regress/regress-2170.js


Index: src/objects-inl.h
diff --git a/src/objects-inl.h b/src/objects-inl.h
index 5edf7cd560050ab2c884aa408832f943bd0d614e..d1fc4c924534e17059b8ce72e7ea7ee6a649faf6 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -1267,30 +1267,25 @@ MaybeObject* JSObject::EnsureCanContainElements(Object** objects,
   if (current_kind == FAST_HOLEY_ELEMENTS) return this;
   Heap* heap = GetHeap();
   Object* the_hole = heap->the_hole_value();
-  Object* heap_number_map = heap->heap_number_map();
   for (uint32_t i = 0; i < count; ++i) {
     Object* current = *objects++;
     if (current == the_hole) {
       is_holey = true;
       target_kind = GetHoleyElementsKind(target_kind);
     } else if (!current->IsSmi()) {
-      if (mode == ALLOW_CONVERTED_DOUBLE_ELEMENTS &&
-          HeapObject::cast(current)->map() == heap_number_map &&
-          IsFastSmiElementsKind(target_kind)) {
-        if (is_holey) {
-          target_kind = FAST_HOLEY_DOUBLE_ELEMENTS;
-        } else {
-          target_kind = FAST_DOUBLE_ELEMENTS;
-        }
-      } else {
-        if (!current->IsNumber()) {
+      if (mode == ALLOW_CONVERTED_DOUBLE_ELEMENTS && current->IsNumber()) {
+        if (IsFastSmiElementsKind(target_kind)) {
           if (is_holey) {
-            target_kind = FAST_HOLEY_ELEMENTS;
-            break;
+            target_kind = FAST_HOLEY_DOUBLE_ELEMENTS;
           } else {
-            target_kind = FAST_ELEMENTS;
+            target_kind = FAST_DOUBLE_ELEMENTS;
           }
         }
+      } else if (is_holey) {
+        target_kind = FAST_HOLEY_ELEMENTS;
+        break;
+      } else {
+        target_kind = FAST_ELEMENTS;
       }
     }
   }
Index: test/mjsunit/regress/regress-2170.js
diff --git a/test/mjsunit/regress/regress-2170.js b/test/mjsunit/regress/regress-2170.js
new file mode 100644
index 0000000000000000000000000000000000000000..01cb1eaf8f7b812429d4f36dee28b70f4af0b66d
--- /dev/null
+++ b/test/mjsunit/regress/regress-2170.js
@@ -0,0 +1,58 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax
+
+function array_fun() {
+  for (var i = 0; i < 2; i++) {
+    var a = [1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8];
+    var x = new Array();
+    x.fixed$length = true;
+    for (var j = 0; j < a.length; j++) {
+      x.push(a[j]);
+    }
+    for(var j = 0; j < x.length; j++) {
+      if (typeof x[j] != 'number') {
+        throw "foo";
+      }
+      x[j] = x[j];
+    }
+  }
+}
+
+try {
+  for (var i = 0; i < 10; ++i) {
+    array_fun();
+  }
+  %OptimizeFunctionOnNextCall(array_fun);
+  for (var i = 0; i < 10; ++i) {
+    array_fun();
+  }
+} catch (e) {
+  assertUnreachable();
+}
+


--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to