Fix EnsureCanContainElements to properly handle double values.
authordanno@chromium.org <danno@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 11 Jun 2012 08:41:48 +0000 (08:41 +0000)
committerdanno@chromium.org <danno@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 11 Jun 2012 08:41:48 +0000 (08:41 +0000)
R=jkummerow@chromium.org
BUG=v8:2170
TEST=test/mjsunit/regress/regress-2170.js

Review URL: https://chromiumcodereview.appspot.com/10542084

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@11751 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/objects-inl.h
test/mjsunit/regress/regress-2170.js [new file with mode: 0644]

index 567f26b9915c6b9eb565754cee4d4dcd344cd148..475a0f49ce9b8c315cba4e200b97468f4851dac5 100644 (file)
@@ -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;
       }
     }
   }
diff --git a/test/mjsunit/regress/regress-2170.js b/test/mjsunit/regress/regress-2170.js
new file mode 100644 (file)
index 0000000..01cb1ea
--- /dev/null
@@ -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();
+}
+