Revision: 13071
Author:   [email protected]
Date:     Wed Nov 28 00:41:45 2012
Log: Make ElementsAccessors more tolerant of varying backing store types

This avoids bogus calls to Fixed*Array::cast() when FastElements-backed objects are empty (and thus backed by empty_fixed_array).

Review URL: https://chromiumcodereview.appspot.com/11299190
Patch from Adam Klein <[email protected]>.
http://code.google.com/p/v8/source/detail?r=13071

Added:
/branches/bleeding_edge/test/mjsunit/regress/regress-observe-empty-double-array.js
Modified:
 /branches/bleeding_edge/src/elements.cc

=======================================
--- /dev/null
+++ /branches/bleeding_edge/test/mjsunit/regress/regress-observe-empty-double-array.js Wed Nov 28 00:41:45 2012
@@ -0,0 +1,37 @@
+// 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: --harmony-observation --allow-natives-syntax
+//
+// Test passes if it does not crash.
+
+arr = [1.1];
+Object.observe(arr, function(){});
+arr.length = 0;
+assertTrue(%HasFastDoubleElements(arr));
+// Should not crash
+arr.push(1.1);
=======================================
--- /branches/bleeding_edge/src/elements.cc     Tue Nov 27 04:01:14 2012
+++ /branches/bleeding_edge/src/elements.cc     Wed Nov 28 00:41:45 2012
@@ -528,7 +528,7 @@
   static bool HasElementImpl(Object* receiver,
                              JSObject* holder,
                              uint32_t key,
-                             BackingStore* backing_store) {
+                             FixedArrayBase* backing_store) {
     return ElementsAccessorSubclass::GetAttributesImpl(
         receiver, holder, key, backing_store) != ABSENT;
   }
@@ -573,18 +573,18 @@
       backing_store = holder->elements();
     }
     return ElementsAccessorSubclass::GetAttributesImpl(
-        receiver, holder, key, BackingStore::cast(backing_store));
+        receiver, holder, key, backing_store);
   }

   MUST_USE_RESULT static PropertyAttributes GetAttributesImpl(
         Object* receiver,
         JSObject* obj,
         uint32_t key,
-        BackingStore* backing_store) {
+        FixedArrayBase* backing_store) {
     if (key >= ElementsAccessorSubclass::GetCapacityImpl(backing_store)) {
       return ABSENT;
     }
-    return backing_store->is_the_hole(key) ? ABSENT : NONE;
+ return BackingStore::cast(backing_store)->is_the_hole(key) ? ABSENT : NONE;
   }

   MUST_USE_RESULT virtual PropertyType GetType(
@@ -784,13 +784,12 @@
   }

  protected:
-  static uint32_t GetCapacityImpl(BackingStore* backing_store) {
+  static uint32_t GetCapacityImpl(FixedArrayBase* backing_store) {
     return backing_store->length();
   }

   virtual uint32_t GetCapacity(FixedArrayBase* backing_store) {
-    return ElementsAccessorSubclass::GetCapacityImpl(
-        BackingStore::cast(backing_store));
+    return ElementsAccessorSubclass::GetCapacityImpl(backing_store);
   }

   static uint32_t GetKeyForIndexImpl(BackingStore* backing_store,
@@ -1210,7 +1209,7 @@
       Object* receiver,
       JSObject* obj,
       uint32_t key,
-      BackingStore* backing_store) {
+      FixedArrayBase* backing_store) {
     return
key < ExternalElementsAccessorSubclass::GetCapacityImpl(backing_store)
           ? NONE : ABSENT;
@@ -1519,10 +1518,12 @@
       Object* receiver,
       JSObject* obj,
       uint32_t key,
-      SeededNumberDictionary* backing_store) {
-    int entry = backing_store->FindEntry(key);
+      FixedArrayBase* backing_store) {
+    SeededNumberDictionary* dictionary =
+        SeededNumberDictionary::cast(backing_store);
+    int entry = dictionary->FindEntry(key);
     if (entry != SeededNumberDictionary::kNotFound) {
-      return backing_store->DetailsAt(entry).attributes();
+      return dictionary->DetailsAt(entry).attributes();
     }
     return ABSENT;
   }
@@ -1616,7 +1617,8 @@
       Object* receiver,
       JSObject* obj,
       uint32_t key,
-      FixedArray* parameter_map) {
+      FixedArrayBase* backing_store) {
+    FixedArray* parameter_map = FixedArray::cast(backing_store);
     Object* probe = GetParameterMapArg(obj, parameter_map, key);
     if (!probe->IsTheHole()) {
       return NONE;
@@ -1708,7 +1710,8 @@
                                   to_start, copy_size, arguments);
   }

-  static uint32_t GetCapacityImpl(FixedArray* parameter_map) {
+  static uint32_t GetCapacityImpl(FixedArrayBase* backing_store) {
+    FixedArray* parameter_map = FixedArray::cast(backing_store);
FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1));
     return Max(static_cast<uint32_t>(parameter_map->length() - 2),
                ForArray(arguments)->GetCapacity(arguments));

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

Reply via email to