Decoupling MarkDescriptorArray as much as possible from the ContentArray.

Review URL: https://chromiumcodereview.appspot.com/10417030

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@11683 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
verwaest@chromium.org 2012-05-30 15:15:17 +00:00
parent 3a2d4c88f4
commit 75f35d3fe1
4 changed files with 25 additions and 8 deletions

View File

@ -1872,17 +1872,16 @@ void Marker<T>::MarkDescriptorArray(DescriptorArray* descriptors) {
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)));
// 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);
Object** slot = contents->data_start() + i;
if (!(*slot)->IsHeapObject()) continue;
HeapObject* value = HeapObject::cast(*slot);

View File

@ -1939,6 +1939,12 @@ String* DescriptorArray::GetKey(int 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) {
ASSERT(descriptor_number < number_of_descriptors());
return GetContentArray()->get(ToValueIndex(descriptor_number));

View File

@ -6069,7 +6069,10 @@ MaybeObject* DescriptorArray::RemoveTransitions() {
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();

View File

@ -2453,6 +2453,7 @@ class DescriptorArray: public FixedArray {
// 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 @@ class DescriptorArray: public FixedArray {
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);