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