Revision: 11683
Author:   [email protected]
Date:     Wed May 30 08:15:17 2012
Log: Decoupling MarkDescriptorArray as much as possible from the ContentArray.

Review URL: https://chromiumcodereview.appspot.com/10417030
http://code.google.com/p/v8/source/detail?r=11683

Modified:
 /branches/bleeding_edge/src/mark-compact.cc
 /branches/bleeding_edge/src/objects-inl.h
 /branches/bleeding_edge/src/objects.cc
 /branches/bleeding_edge/src/objects.h

=======================================
--- /branches/bleeding_edge/src/mark-compact.cc Wed May 23 04:40:38 2012
+++ /branches/bleeding_edge/src/mark-compact.cc Wed May 30 08:15:17 2012
@@ -1872,17 +1872,16 @@
   if (!base_marker()->MarkObjectAndPush(descriptors)) return;
   FixedArray* contents = FixedArray::cast(
       descriptors->get(DescriptorArray::kContentArrayIndex));
-  ASSERT(contents->length() >= 2);
   ASSERT(Marking::IsWhite(Marking::MarkBitFrom(contents)));
   base_marker()->MarkObjectWithoutPush(contents);

- // Contents contains (value, details) pairs. If the descriptor contains a - // transition (value is a Map), we don't mark the value as live. It might
-  // be set to the NULL_DESCRIPTOR in ClearNonLiveTransitions later.
-  for (int i = 0; i < contents->length(); i += 2) {
-    PropertyDetails details(Smi::cast(contents->get(i + 1)));
-
-    Object** slot = contents->data_start() + i;
+ // If the descriptor contains a transition (value is a Map), we don't mark the
+  // value as live. It might be set to the NULL_DESCRIPTOR in
+  // ClearNonLiveTransitions later.
+  for (int i = 0; i < descriptors->number_of_descriptors(); ++i) {
+    PropertyDetails details(descriptors->GetDetails(i));
+    Object** slot = descriptors->GetValueSlot(i);
+
     if (!(*slot)->IsHeapObject()) continue;
     HeapObject* value = HeapObject::cast(*slot);

=======================================
--- /branches/bleeding_edge/src/objects-inl.h   Wed May 30 07:40:57 2012
+++ /branches/bleeding_edge/src/objects-inl.h   Wed May 30 08:15:17 2012
@@ -1937,6 +1937,12 @@
   ASSERT(descriptor_number < number_of_descriptors());
   return String::cast(get(ToKeyIndex(descriptor_number)));
 }
+
+
+Object** DescriptorArray::GetValueSlot(int descriptor_number) {
+  ASSERT(descriptor_number < number_of_descriptors());
+  return GetContentArray()->data_start() + ToValueIndex(descriptor_number);
+}


 Object* DescriptorArray::GetValue(int descriptor_number) {
=======================================
--- /branches/bleeding_edge/src/objects.cc      Wed May 30 07:54:00 2012
+++ /branches/bleeding_edge/src/objects.cc      Wed May 30 08:15:17 2012
@@ -6069,7 +6069,10 @@
   return new_descriptors;
 }

-
+// We need the whiteness witness since sort will reshuffle the entries in the +// descriptor array. If the descriptor array were to be black, the shuffling +// would move a slot that was already recorded as pointing into an evacuation
+// candidate. This would result in missing updates upon evacuation.
 void DescriptorArray::SortUnchecked(const WhitenessWitness& witness) {
   // In-place heap sort.
   int len = number_of_descriptors();
=======================================
--- /branches/bleeding_edge/src/objects.h       Wed May 30 07:54:00 2012
+++ /branches/bleeding_edge/src/objects.h       Wed May 30 08:15:17 2012
@@ -2453,6 +2453,7 @@
   // Accessors for fetching instance descriptor at descriptor number.
   inline String* GetKey(int descriptor_number);
   inline Object* GetValue(int descriptor_number);
+  inline Object** GetValueSlot(int descriptor_number);
   inline PropertyDetails GetDetails(int descriptor_number);
   inline PropertyType GetType(int descriptor_number);
   inline int GetFieldIndex(int descriptor_number);
@@ -2463,6 +2464,14 @@
   inline bool IsTransitionOnly(int descriptor_number);
   inline bool IsNullDescriptor(int descriptor_number);

+ // WhitenessWitness is used to prove that a specific descriptor array is white
+  // (unmarked), so incremental write barriers can be skipped because the
+  // marking invariant cannot be broken and slots pointing into evacuation
+  // candidates will be discovered when the object is scanned. A witness is
+  // always stack-allocated right after creating a descriptor array. By
+ // allocating a witness, incremental marking is globally disabled. The witness
+  // is then passed along wherever needed to statically prove that the
+  // descriptor array is known to be white.
   class WhitenessWitness {
    public:
     inline explicit WhitenessWitness(DescriptorArray* array);

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

Reply via email to