From fd2e3344d3116cd9ca11a14a1f4d800effba25ba Mon Sep 17 00:00:00 2001 From: ulan Date: Mon, 8 Jun 2015 04:20:30 -0700 Subject: [PATCH] Revert of Replace ad-hoc weakness in prototype transitions with WeakCell. (patchset #2 id:20001 of https://codereview.chromium.org/1163073002/) Reason for revert: GC stress failures. Original issue's description: > Replace ad-hoc weakness in prototype transitions with WeakCell. > > BUG= > > Committed: https://crrev.com/bfb81fbe0d38c88cc1b6ed6eb1a4b8cbe2c469c3 > Cr-Commit-Position: refs/heads/master@{#28830} TBR=jkummerow@chromium.org,hpayer@chromium.org NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true BUG= Review URL: https://codereview.chromium.org/1169733002 Cr-Commit-Position: refs/heads/master@{#28832} --- src/heap/mark-compact.cc | 7 ++++--- src/heap/objects-visiting-inl.h | 9 +++++++-- src/transitions.cc | 31 +++++++++++++------------------ src/transitions.h | 5 +++-- test/cctest/test-heap.cc | 3 +-- 5 files changed, 28 insertions(+), 27 deletions(-) diff --git a/src/heap/mark-compact.cc b/src/heap/mark-compact.cc index 30332f513..133fb24c4 100644 --- a/src/heap/mark-compact.cc +++ b/src/heap/mark-compact.cc @@ -2404,10 +2404,11 @@ void MarkCompactCollector::ClearNonLivePrototypeTransitions(Map* map) { const int header = TransitionArray::kProtoTransitionHeaderSize; int new_number_of_transitions = 0; for (int i = 0; i < number_of_transitions; i++) { - Object* cell = prototype_transitions->get(header + i); - if (!WeakCell::cast(cell)->cleared()) { + Object* cached_map = prototype_transitions->get(header + i); + if (IsMarked(cached_map)) { if (new_number_of_transitions != i) { - prototype_transitions->set(header + new_number_of_transitions, cell); + prototype_transitions->set(header + new_number_of_transitions, + cached_map, SKIP_WRITE_BARRIER); } new_number_of_transitions++; } diff --git a/src/heap/objects-visiting-inl.h b/src/heap/objects-visiting-inl.h index 7f83f483b..d1d52a4c7 100644 --- a/src/heap/objects-visiting-inl.h +++ b/src/heap/objects-visiting-inl.h @@ -571,8 +571,13 @@ void StaticMarkingVisitor::MarkTransitionArray( if (!StaticVisitor::MarkObjectWithoutPush(heap, transitions)) return; if (transitions->HasPrototypeTransitions()) { - StaticVisitor::VisitPointer(heap, - transitions->GetPrototypeTransitionsSlot()); + // Mark prototype transitions array but do not push it onto marking + // stack, this will make references from it weak. We will clean dead + // prototype transitions in ClearNonLiveReferences. + Object** slot = transitions->GetPrototypeTransitionsSlot(); + HeapObject* obj = HeapObject::cast(*slot); + heap->mark_compact_collector()->RecordSlot(slot, slot, obj); + StaticVisitor::MarkObjectWithoutPush(heap, obj); } int num_transitions = TransitionArray::NumberOfTransitions(transitions); diff --git a/src/transitions.cc b/src/transitions.cc index c39534bbb..63bb7fa68 100644 --- a/src/transitions.cc +++ b/src/transitions.cc @@ -233,19 +233,17 @@ bool TransitionArray::CanHaveMoreTransitions(Handle map) { // static -void TransitionArray::PutPrototypeTransition(Handle map, - Handle prototype, - Handle target_map) { +Handle TransitionArray::PutPrototypeTransition(Handle map, + Handle prototype, + Handle target_map) { DCHECK(HeapObject::cast(*prototype)->map()->IsMap()); // Don't cache prototype transition if this map is either shared, or a map of // a prototype. - if (map->is_prototype_map()) return; - if (map->is_dictionary_map() || !FLAG_cache_prototype_transitions) return; + if (map->is_prototype_map()) return map; + if (map->is_dictionary_map() || !FLAG_cache_prototype_transitions) return map; const int header = kProtoTransitionHeaderSize; - Handle target_cell = Map::WeakCellForMap(target_map); - Handle cache(GetPrototypeTransitions(*map)); int capacity = cache->length() - header; int transitions = NumberOfPrototypeTransitions(*cache) + 1; @@ -253,7 +251,7 @@ void TransitionArray::PutPrototypeTransition(Handle map, if (transitions > capacity) { // Grow array by factor 2 up to MaxCachedPrototypeTransitions. int new_capacity = Min(kMaxCachedPrototypeTransitions, transitions * 2); - if (new_capacity == capacity) return; + if (new_capacity == capacity) return map; cache = FixedArray::CopySize(cache, header + new_capacity); if (capacity < 0) { @@ -269,8 +267,10 @@ void TransitionArray::PutPrototypeTransition(Handle map, int last = NumberOfPrototypeTransitions(*cache); int entry = header + last; - cache->set(entry, *target_cell); + cache->set(entry, *target_map); SetNumberOfPrototypeTransitions(*cache, last + 1); + + return map; } @@ -281,12 +281,8 @@ Handle TransitionArray::GetPrototypeTransition(Handle map, FixedArray* cache = GetPrototypeTransitions(*map); int number_of_transitions = NumberOfPrototypeTransitions(cache); for (int i = 0; i < number_of_transitions; i++) { - WeakCell* target_cell = - WeakCell::cast(cache->get(kProtoTransitionHeaderSize + i)); - if (!target_cell->cleared() && - Map::cast(target_cell->value())->prototype() == *prototype) { - return handle(Map::cast(target_cell->value())); - } + Map* target = Map::cast(cache->get(kProtoTransitionHeaderSize + i)); + if (target->prototype() == *prototype) return handle(target); } return Handle(); } @@ -440,9 +436,8 @@ void TransitionArray::TraverseTransitionTreeInternal(Map* map, FixedArray* proto_trans = transitions->GetPrototypeTransitions(); for (int i = 0; i < NumberOfPrototypeTransitions(proto_trans); ++i) { int index = TransitionArray::kProtoTransitionHeaderSize + i; - WeakCell* cell = WeakCell::cast(proto_trans->get(index)); - TraverseTransitionTreeInternal(Map::cast(cell->value()), callback, - data); + TraverseTransitionTreeInternal(Map::cast(proto_trans->get(index)), + callback, data); } } for (int i = 0; i < transitions->number_of_transitions(); ++i) { diff --git a/src/transitions.h b/src/transitions.h index b0aab9502..1cb91a222 100644 --- a/src/transitions.h +++ b/src/transitions.h @@ -92,8 +92,9 @@ class TransitionArray: public FixedArray { // 0: finger - index of the first free cell in the cache // 1 + i: target map static const int kMaxCachedPrototypeTransitions = 256; - static void PutPrototypeTransition(Handle map, Handle prototype, - Handle target_map); + static Handle PutPrototypeTransition(Handle map, + Handle prototype, + Handle target_map); static Handle GetPrototypeTransition(Handle map, Handle prototype); diff --git a/test/cctest/test-heap.cc b/test/cctest/test-heap.cc index 0a4cf2b1e..f0dc643fc 100644 --- a/test/cctest/test-heap.cc +++ b/test/cctest/test-heap.cc @@ -2521,8 +2521,7 @@ TEST(PrototypeTransitionClearing) { TransitionArray::GetPrototypeTransitions(baseObject->map()); for (int i = initialTransitions; i < initialTransitions + transitions; i++) { int j = TransitionArray::kProtoTransitionHeaderSize + i; - CHECK(trans->get(j)->IsWeakCell()); - CHECK(WeakCell::cast(trans->get(j))->value()->IsMap()); + CHECK(trans->get(j)->IsMap()); } // Make sure next prototype is placed on an old-space evacuation candidate. -- 2.34.1