Commit c2a9d493 authored by verwaest@chromium.org's avatar verwaest@chromium.org

Transition ownership back if the descriptors were shared via elements transitions.

BUG=

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12689 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent dde1cdfb
...@@ -7431,15 +7431,6 @@ void String::PrintOn(FILE* file) { ...@@ -7431,15 +7431,6 @@ void String::PrintOn(FILE* file) {
} }
// Clear a possible back pointer in case the transition leads to a dead map.
// Return true in case a back pointer has been cleared and false otherwise.
static bool ClearBackPointer(Heap* heap, Map* target) {
if (Marking::MarkBitFrom(target).Get()) return false;
target->SetBackPointer(heap->undefined_value(), SKIP_WRITE_BARRIER);
return true;
}
static void TrimEnumCache(Heap* heap, Map* map, DescriptorArray* descriptors) { static void TrimEnumCache(Heap* heap, Map* map, DescriptorArray* descriptors) {
int live_enum = map->EnumLength(); int live_enum = map->EnumLength();
if (live_enum == Map::kInvalidEnumCache) { if (live_enum == Map::kInvalidEnumCache) {
...@@ -7485,6 +7476,21 @@ static void TrimDescriptorArray(Heap* heap, ...@@ -7485,6 +7476,21 @@ static void TrimDescriptorArray(Heap* heap,
} }
// Clear a possible back pointer in case the transition leads to a dead map.
// Return true in case a back pointer has been cleared and false otherwise.
static bool ClearBackPointer(Heap* heap,
Map* target,
DescriptorArray* descriptors,
bool* descriptors_owner_died) {
if (Marking::MarkBitFrom(target).Get()) return false;
if (target->instance_descriptors() == descriptors) {
*descriptors_owner_died = true;
}
target->SetBackPointer(heap->undefined_value(), SKIP_WRITE_BARRIER);
return true;
}
// TODO(mstarzinger): This method should be moved into MarkCompactCollector, // TODO(mstarzinger): This method should be moved into MarkCompactCollector,
// because it cannot be called from outside the GC and we already have methods // because it cannot be called from outside the GC and we already have methods
// depending on the transitions layout in the GC anyways. // depending on the transitions layout in the GC anyways.
...@@ -7505,15 +7511,7 @@ void Map::ClearNonLiveTransitions(Heap* heap) { ...@@ -7505,15 +7511,7 @@ void Map::ClearNonLiveTransitions(Heap* heap) {
// Compact all live descriptors to the left. // Compact all live descriptors to the left.
for (int i = 0; i < t->number_of_transitions(); ++i) { for (int i = 0; i < t->number_of_transitions(); ++i) {
Map* target = t->GetTarget(i); Map* target = t->GetTarget(i);
if (ClearBackPointer(heap, target)) { if (!ClearBackPointer(heap, target, descriptors, &descriptors_owner_died)) {
ASSERT(!Marking::IsGrey(Marking::MarkBitFrom(target)));
DescriptorArray* target_descriptors = target->instance_descriptors();
if ((target_descriptors->number_of_descriptors() == 0 &&
target->NumberOfOwnDescriptors() > 0) ||
target_descriptors == descriptors) {
descriptors_owner_died = true;
}
} else {
if (i != transition_index) { if (i != transition_index) {
String* key = t->GetKey(i); String* key = t->GetKey(i);
t->SetKey(transition_index, key); t->SetKey(transition_index, key);
...@@ -7527,10 +7525,10 @@ void Map::ClearNonLiveTransitions(Heap* heap) { ...@@ -7527,10 +7525,10 @@ void Map::ClearNonLiveTransitions(Heap* heap) {
} }
if (t->HasElementsTransition() && if (t->HasElementsTransition() &&
ClearBackPointer(heap, t->elements_transition())) { ClearBackPointer(heap,
if (t->elements_transition()->instance_descriptors() == descriptors) { t->elements_transition(),
descriptors_owner_died = true; descriptors,
} &descriptors_owner_died)) {
t->ClearElementsTransition(); t->ClearElementsTransition();
} else { } else {
// If there are no transitions to be cleared, return. // If there are no transitions to be cleared, return.
......
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