Reviewers: Sven Panne,

Message:
PTAL, thx!
--Michael

Description:
The Elements pointer in a JSObject can have a filler map instead of a
valid fixed array, iff a gc occurred while allocating a fixed array as
part of array construction. Heap verification needs protection against
examining the elements object in this case.

Please review this at https://codereview.chromium.org/43383004/

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

Affected files (+31, -21 lines):
  M src/objects-debug.cc
  M src/objects-inl.h
  M src/objects.h
  M test/mjsunit/mjsunit.status


Index: src/objects-debug.cc
diff --git a/src/objects-debug.cc b/src/objects-debug.cc
index 90b01934dfec256e8e1abb081ea467f819095679..fa3c375cb499c821c65a2614578d5113206a154b 100644
--- a/src/objects-debug.cc
+++ b/src/objects-debug.cc
@@ -335,9 +335,7 @@ void JSObject::JSObjectVerify() {

   // If a GC was caused while constructing this object, the elements
   // pointer may point to a one pointer filler map.
-  if ((FLAG_use_gvn && FLAG_use_allocation_folding) ||
-      (reinterpret_cast<Map*>(elements()) !=
-      GetHeap()->one_pointer_filler_map())) {
+  if (ElementsAreSafeToExamine()) {
     CHECK_EQ((map()->has_fast_smi_or_object_elements() ||
               (elements() == GetHeap()->empty_fixed_array())),
              (elements()->map() == GetHeap()->fixed_array_map() ||
@@ -698,9 +696,7 @@ void JSArray::JSArrayVerify() {
   CHECK(length()->IsNumber() || length()->IsUndefined());
   // If a GC was caused while constructing this array, the elements
   // pointer may point to a one pointer filler map.
-  if ((FLAG_use_gvn && FLAG_use_allocation_folding) ||
-      (reinterpret_cast<Map*>(elements()) !=
-      GetHeap()->one_pointer_filler_map())) {
+  if (ElementsAreSafeToExamine()) {
     CHECK(elements()->IsUndefined() ||
           elements()->IsFixedArray() ||
           elements()->IsFixedDoubleArray());
@@ -1143,6 +1139,13 @@ void JSObject::SpillInformation::Print() {
 }


+bool JSObject::ElementsAreSafeToExamine() {
+  return (FLAG_use_gvn && FLAG_use_allocation_folding) ||
+      reinterpret_cast<Map*>(elements()) !=
+      GetHeap()->one_pointer_filler_map();
+}
+
+
 bool DescriptorArray::IsSortedNoDuplicates(int valid_entries) {
   if (valid_entries == -1) valid_entries = number_of_descriptors();
   Name* current_key = NULL;
Index: src/objects-inl.h
diff --git a/src/objects-inl.h b/src/objects-inl.h
index 006aff394c20cd517c516e0823424f3aa42c9c80..7b2ac766418d7e4dce84ee3d1d6edb2da2d75501 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -5516,19 +5516,24 @@ ElementsKind JSObject::GetElementsKind() {
 #if DEBUG
   FixedArrayBase* fixed_array =
       reinterpret_cast<FixedArrayBase*>(READ_FIELD(this, kElementsOffset));
-  Map* map = fixed_array->map();
-  ASSERT((IsFastSmiOrObjectElementsKind(kind) &&
-          (map == GetHeap()->fixed_array_map() ||
-           map == GetHeap()->fixed_cow_array_map())) ||
-         (IsFastDoubleElementsKind(kind) &&
-          (fixed_array->IsFixedDoubleArray() ||
-           fixed_array == GetHeap()->empty_fixed_array())) ||
-         (kind == DICTIONARY_ELEMENTS &&
+
+  // If a GC was caused while constructing this object, the elements
+  // pointer may point to a one pointer filler map.
+  if (ElementsAreSafeToExamine()) {
+    Map* map = fixed_array->map();
+    ASSERT((IsFastSmiOrObjectElementsKind(kind) &&
+            (map == GetHeap()->fixed_array_map() ||
+             map == GetHeap()->fixed_cow_array_map())) ||
+           (IsFastDoubleElementsKind(kind) &&
+            (fixed_array->IsFixedDoubleArray() ||
+             fixed_array == GetHeap()->empty_fixed_array())) ||
+           (kind == DICTIONARY_ELEMENTS &&
             fixed_array->IsFixedArray() &&
-          fixed_array->IsDictionary()) ||
-         (kind > DICTIONARY_ELEMENTS));
-  ASSERT((kind != NON_STRICT_ARGUMENTS_ELEMENTS) ||
-         (elements()->IsFixedArray() && elements()->length() >= 2));
+            fixed_array->IsDictionary()) ||
+           (kind > DICTIONARY_ELEMENTS));
+    ASSERT((kind != NON_STRICT_ARGUMENTS_ELEMENTS) ||
+           (elements()->IsFixedArray() && elements()->length() >= 2));
+  }
 #endif
   return kind;
 }
Index: src/objects.h
diff --git a/src/objects.h b/src/objects.h
index 267ef133abc43373b84b02fbd9c3e8e63b2ce85a..6a94edd93fc88c47d4a1a1b474072d1731dd8561 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -2590,6 +2590,11 @@ class JSObject: public JSReceiver {
   };

   void IncrementSpillStatistics(SpillInformation* info);
+
+ // If a GC was caused while constructing this object, the elements pointer
+  // may point to a one pointer filler map. The object won't be rooted, but
+  // our heap verification code could stumble across it.
+  bool ElementsAreSafeToExamine();
 #endif
   Object* SlowReverseLookup(Object* value);

Index: test/mjsunit/mjsunit.status
diff --git a/test/mjsunit/mjsunit.status b/test/mjsunit/mjsunit.status
index 0cdc6749cf588b223fca2826d70bce3928ee4c97..a24d6928de858146b29647eb42a77a8a12284062 100644
--- a/test/mjsunit/mjsunit.status
+++ b/test/mjsunit/mjsunit.status
@@ -33,9 +33,6 @@
   # TODO(mvstanton) Re-enable when the performance is bearable again.
   'regress/regress-2185-2': [SKIP],

-  # TODO(mvstanton) Re-enable when the bug is fixed.
-  'regress/regress-2612': [PASS, ['mode == debug', SKIP]],
-
##############################################################################
   # Fails.
   'regress/regress-1119': [FAIL],


--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to