Revision: 5513
Author: [email protected]
Date: Thu Sep 23 05:23:35 2010
Log: Fix copy-on-write assert by setting the new array map early.

BUG=876

Review URL: http://codereview.chromium.org/3466013
http://code.google.com/p/v8/source/detail?r=5513

Added:
 /branches/bleeding_edge/test/mjsunit/copy-on-write-assert.js
Modified:
 /branches/bleeding_edge/src/heap-inl.h
 /branches/bleeding_edge/src/heap.cc
 /branches/bleeding_edge/src/heap.h
 /branches/bleeding_edge/src/objects-inl.h

=======================================
--- /dev/null
+++ /branches/bleeding_edge/test/mjsunit/copy-on-write-assert.js Thu Sep 23 05:23:35 2010
@@ -0,0 +1,42 @@
+// Copyright 2010 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.
+
+function createLargeCOWArray() {
+  var s = "[0";
+  // The constant below depends on the max object size in new space.
+  for (var i = 0; i < (128 << 10); i++) {
+    s += ",0";
+  }
+  s += "]";
+  return eval(s);
+}
+
+var large_cow_array = createLargeCOWArray();
+
+// Force copy. Because the array is large it will test the slow array
+// cloning in large object space.
+large_cow_array[17] = 42;
=======================================
--- /branches/bleeding_edge/src/heap-inl.h      Tue Sep 14 10:48:56 2010
+++ /branches/bleeding_edge/src/heap-inl.h      Thu Sep 23 05:23:35 2010
@@ -57,6 +57,11 @@
                                     static_cast<unsigned>(str.length()));
   return AllocateInternalSymbol(&buffer, chars, hash_field);
 }
+
+
+Object* Heap::CopyFixedArray(FixedArray* src) {
+  return CopyFixedArrayWithMap(src, src->map());
+}


 Object* Heap::AllocateRaw(int size_in_bytes,
=======================================
--- /branches/bleeding_edge/src/heap.cc Thu Sep 23 02:15:26 2010
+++ /branches/bleeding_edge/src/heap.cc Thu Sep 23 05:23:35 2010
@@ -3205,16 +3205,19 @@
 }


-Object* Heap::CopyFixedArray(FixedArray* src) {
+Object* Heap::CopyFixedArrayWithMap(FixedArray* src, Map* map) {
   int len = src->length();
   Object* obj = AllocateRawFixedArray(len);
   if (obj->IsFailure()) return obj;
   if (Heap::InNewSpace(obj)) {
     HeapObject* dst = HeapObject::cast(obj);
-    CopyBlock(dst->address(), src->address(), FixedArray::SizeFor(len));
+    dst->set_map(map);
+    CopyBlock(dst->address() + kPointerSize,
+              src->address() + kPointerSize,
+              FixedArray::SizeFor(len) - kPointerSize);
     return obj;
   }
-  HeapObject::cast(obj)->set_map(src->map());
+  HeapObject::cast(obj)->set_map(map);
   FixedArray* result = FixedArray::cast(obj);
   result->set_length(len);

=======================================
--- /branches/bleeding_edge/src/heap.h  Tue Sep 14 10:48:56 2010
+++ /branches/bleeding_edge/src/heap.h  Thu Sep 23 05:23:35 2010
@@ -498,7 +498,12 @@

   // Make a copy of src and return it. Returns
// Failure::RetryAfterGC(requested_bytes, space) if the allocation failed.
-  MUST_USE_RESULT static Object* CopyFixedArray(FixedArray* src);
+  MUST_USE_RESULT static inline Object* CopyFixedArray(FixedArray* src);
+
+  // Make a copy of src, set the map, and return the copy. Returns
+ // Failure::RetryAfterGC(requested_bytes, space) if the allocation failed.
+  MUST_USE_RESULT static Object* CopyFixedArrayWithMap(FixedArray* src,
+                                                       Map* map);

   // Allocates a fixed array initialized with the hole values.
// Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
=======================================
--- /branches/bleeding_edge/src/objects-inl.h   Thu Sep 23 02:15:26 2010
+++ /branches/bleeding_edge/src/objects-inl.h   Thu Sep 23 05:23:35 2010
@@ -3187,9 +3187,9 @@
   ASSERT(HasFastElements());
   FixedArray* elems = FixedArray::cast(elements());
   if (elems->map() != Heap::fixed_cow_array_map()) return elems;
-  Object* writable_elems = Heap::CopyFixedArray(elems);
+  Object* writable_elems = Heap::CopyFixedArrayWithMap(elems,
+ Heap::fixed_array_map());
   if (writable_elems->IsFailure()) return writable_elems;
-  FixedArray::cast(writable_elems)->set_map(Heap::fixed_array_map());
   set_elements(FixedArray::cast(writable_elems));
   Counters::cow_arrays_converted.Increment();
   return writable_elems;

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

Reply via email to