Avoid sharing AccessorPairs during Genesis.

To test the upcoming changes for map sharing in the presence of accessors, it is
essential that we keep a few global invariants: The map tree should always stay
a tree and AccessorPairs should not be shared between different DescriptorArrays
and/or StringDictionaries. This CL adds a test method for the latter invariant
and makes some changes to the bootstrapping process to avoid such sharing.

Note that we can't enable the new test method permanently yet, because we
currently go back and forth between fast mode and slow mode when adding an
accessor and break this invariant temporarily. This will be handled in a
separate CL.

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10744 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent e2ec1839
This diff is collapsed.
...@@ -5062,8 +5062,39 @@ void Heap::Verify() { ...@@ -5062,8 +5062,39 @@ void Heap::Verify() {
cell_space_->Verify(&no_dirty_regions_visitor); cell_space_->Verify(&no_dirty_regions_visitor);
lo_space_->Verify(); lo_space_->Verify();
}
// TODO(svenpanne) We should enable this when our fast->slow->fast-mode dance
// for setting accessor properties is fixed.
// VerifyNoAccessorPairSharing();
}
void Heap::VerifyNoAccessorPairSharing() {
// Verification is done in 2 phases: First we mark all AccessorPairs, checking
// that we mark only unmarked pairs, then we clear all marks, restoring the
// initial state. We use the Smi tag of the AccessorPair's getter as the
// marking bit, because we can never see a Smi as the getter.
for (int phase = 0; phase < 2; phase++) {
HeapObjectIterator iter(map_space());
for (HeapObject* obj = iter.Next(); obj != NULL; obj = iter.Next()) {
if (obj->IsMap()) {
DescriptorArray* descs = Map::cast(obj)->instance_descriptors();
for (int i = 0; i < descs->number_of_descriptors(); i++) {
if (descs->GetType(i) == CALLBACKS &&
descs->GetValue(i)->IsAccessorPair()) {
AccessorPair* accessors = AccessorPair::cast(descs->GetValue(i));
uintptr_t before = reinterpret_cast<intptr_t>(accessors->getter());
uintptr_t after = (phase == 0) ?
((before & ~kSmiTagMask) | kSmiTag) :
((before & ~kHeapObjectTag) | kHeapObjectTag);
CHECK(before != after);
accessors->set_getter(reinterpret_cast<Object*>(after));
}
}
}
}
}
}
#endif // DEBUG #endif // DEBUG
......
...@@ -1219,6 +1219,10 @@ class Heap { ...@@ -1219,6 +1219,10 @@ class Heap {
// Verify the heap is in its normal state before or after a GC. // Verify the heap is in its normal state before or after a GC.
void Verify(); void Verify();
// Verify that AccessorPairs are not shared, i.e. make sure that they have
// exactly one pointer to them.
void VerifyNoAccessorPairSharing();
void OldPointerSpaceCheckStoreBuffer(); void OldPointerSpaceCheckStoreBuffer();
void MapSpaceCheckStoreBuffer(); void MapSpaceCheckStoreBuffer();
void LargeObjectSpaceCheckStoreBuffer(); void LargeObjectSpaceCheckStoreBuffer();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment