Revert of Replace ad-hoc weakness in prototype transitions with WeakCell. (patchset...
authorulan <ulan@chromium.org>
Mon, 8 Jun 2015 11:20:30 +0000 (04:20 -0700)
committerCommit bot <commit-bot@chromium.org>
Mon, 8 Jun 2015 11:20:37 +0000 (11:20 +0000)
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
src/heap/objects-visiting-inl.h
src/transitions.cc
src/transitions.h
test/cctest/test-heap.cc

index 30332f513384461c51e4e707173daa2bf0ac9185..133fb24c40ee0ddbaa6c6661abec96c2680d4e76 100644 (file)
@@ -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++;
     }
index 7f83f483ba750e9e149da2c8ed580f5f6fe0dee0..d1d52a4c7a7b0c548838d566fb2195364a4ceb7a 100644 (file)
@@ -571,8 +571,13 @@ void StaticMarkingVisitor<StaticVisitor>::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);
index c39534bbb566a2930934d2a56482517a2d18e1c6..63bb7fa68f515db5bb90e64fc4629e1807c6b898 100644 (file)
@@ -233,19 +233,17 @@ bool TransitionArray::CanHaveMoreTransitions(Handle<Map> map) {
 
 
 // static
-void TransitionArray::PutPrototypeTransition(Handle<Map> map,
-                                             Handle<Object> prototype,
-                                             Handle<Map> target_map) {
+Handle<Map> TransitionArray::PutPrototypeTransition(Handle<Map> map,
+                                                    Handle<Object> prototype,
+                                                    Handle<Map> 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<WeakCell> target_cell = Map::WeakCellForMap(target_map);
-
   Handle<FixedArray> cache(GetPrototypeTransitions(*map));
   int capacity = cache->length() - header;
   int transitions = NumberOfPrototypeTransitions(*cache) + 1;
@@ -253,7 +251,7 @@ void TransitionArray::PutPrototypeTransition(Handle<Map> 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> 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<Map> TransitionArray::GetPrototypeTransition(Handle<Map> 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<Map>();
 }
@@ -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) {
index b0aab9502e5d2e08dd810ae16aac23cc5edd7bf5..1cb91a222e6fec33133c3c3fd060102cb01a3750 100644 (file)
@@ -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> map, Handle<Object> prototype,
-                                     Handle<Map> target_map);
+  static Handle<Map> PutPrototypeTransition(Handle<Map> map,
+                                            Handle<Object> prototype,
+                                            Handle<Map> target_map);
 
   static Handle<Map> GetPrototypeTransition(Handle<Map> map,
                                             Handle<Object> prototype);
index 0a4cf2b1e4006a7983ef6cd158a252d116ea94e3..f0dc643fc60f3a06b65e190bdc534ff7aca9735b 100644 (file)
@@ -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.