From c2a9d493931b7a28c34c103dc945ffb4ff0f8f62 Mon Sep 17 00:00:00 2001 From: "verwaest@chromium.org" Date: Wed, 10 Oct 2012 13:13:35 +0000 Subject: [PATCH] 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 --- src/objects.cc | 42 ++++++++++++++++++++---------------------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/src/objects.cc b/src/objects.cc index 99be366..4d8fe8e 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -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) { int live_enum = map->EnumLength(); if (live_enum == Map::kInvalidEnumCache) { @@ -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, // because it cannot be called from outside the GC and we already have methods // depending on the transitions layout in the GC anyways. @@ -7505,15 +7511,7 @@ void Map::ClearNonLiveTransitions(Heap* heap) { // Compact all live descriptors to the left. for (int i = 0; i < t->number_of_transitions(); ++i) { Map* target = t->GetTarget(i); - if (ClearBackPointer(heap, target)) { - 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 (!ClearBackPointer(heap, target, descriptors, &descriptors_owner_died)) { if (i != transition_index) { String* key = t->GetKey(i); t->SetKey(transition_index, key); @@ -7527,10 +7525,10 @@ void Map::ClearNonLiveTransitions(Heap* heap) { } if (t->HasElementsTransition() && - ClearBackPointer(heap, t->elements_transition())) { - if (t->elements_transition()->instance_descriptors() == descriptors) { - descriptors_owner_died = true; - } + ClearBackPointer(heap, + t->elements_transition(), + descriptors, + &descriptors_owner_died)) { t->ClearElementsTransition(); } else { // If there are no transitions to be cleared, return. -- 2.7.4