Replace ad-hoc weakness in transition array with WeakCell.
authorulan <ulan@chromium.org>
Wed, 17 Jun 2015 12:07:41 +0000 (05:07 -0700)
committerCommit bot <commit-bot@chromium.org>
Wed, 17 Jun 2015 12:07:52 +0000 (12:07 +0000)
BUG=

Review URL: https://codereview.chromium.org/1157943003

Cr-Commit-Position: refs/heads/master@{#29083}

src/heap/mark-compact.cc
src/heap/objects-visiting-inl.h
src/heap/objects-visiting.h
src/transitions-inl.h
src/transitions.cc
src/transitions.h

index 90fc13616c65f750b974ce58ff821742603486f8..7ee78083ce049b7ecfb3ac6c37684f489c853cf0 100644 (file)
@@ -2468,25 +2468,39 @@ void MarkCompactCollector::ClearMapTransitions(Map* map, Map* dead_transition) {
 
   int transition_index = 0;
 
-  bool descriptors_owner_died = false;
+  // This flag will be cleared if we find the live owner in the loop below.
+  bool descriptors_owner_died = true;
 
   // Compact all live descriptors to the left.
-  for (int i = 0; i < num_transitions; ++i) {
-    Map* target = TransitionArray::GetTarget(transitions, i);
-    if (ClearMapBackPointer(target)) {
-      if (target->instance_descriptors() == descriptors) {
-        descriptors_owner_died = true;
+  if (TransitionArray::IsFullTransitionArray(transitions)) {
+    for (int i = 0; i < num_transitions; ++i) {
+      WeakCell* target_cell =
+          TransitionArray::cast(transitions)->GetTargetCell(i);
+      if (!target_cell->cleared()) {
+        if (Map::cast(target_cell->value())->instance_descriptors() ==
+            descriptors) {
+          descriptors_owner_died = false;
+        }
+        if (i != transition_index) {
+          TransitionArray* t = TransitionArray::cast(transitions);
+          Name* key = t->GetKey(i);
+          t->SetKey(transition_index, key);
+          Object** key_slot = t->GetKeySlot(transition_index);
+          RecordSlot(key_slot, key_slot, key);
+          WeakCell* target_cell = t->GetTargetCell(i);
+          t->SetTargetCell(transition_index, target_cell);
+          Object** target_slot = t->GetTargetSlot(transition_index);
+          RecordSlot(target_slot, target_slot, target_cell);
+        }
+        transition_index++;
       }
-    } else {
-      if (i != transition_index) {
-        DCHECK(TransitionArray::IsFullTransitionArray(transitions));
-        TransitionArray* t = TransitionArray::cast(transitions);
-        Name* key = t->GetKey(i);
-        t->SetKey(transition_index, key);
-        Object** key_slot = t->GetKeySlot(transition_index);
-        RecordSlot(key_slot, key_slot, key);
-        // Target slots do not need to be recorded since maps are not compacted.
-        t->SetTarget(transition_index, t->GetTarget(i));
+    }
+  } else if (transitions->IsWeakCell()) {
+    WeakCell* target_cell = WeakCell::cast(transitions);
+    if (!target_cell->cleared()) {
+      if (Map::cast(target_cell->value())->instance_descriptors() ==
+          descriptors) {
+        descriptors_owner_died = false;
       }
       transition_index++;
     }
index 433fc6deab3e0efc7cb921501d7757d1c42a2688..d22f6d268db27ded38e9d468afd739a57233e6e5 100644 (file)
@@ -537,11 +537,6 @@ void StaticMarkingVisitor<StaticVisitor>::VisitJSDataView(Map* map,
 template <typename StaticVisitor>
 void StaticMarkingVisitor<StaticVisitor>::MarkMapContents(Heap* heap,
                                                           Map* map) {
-  Object* raw_transitions = map->raw_transitions();
-  if (TransitionArray::IsFullTransitionArray(raw_transitions)) {
-    MarkTransitionArray(heap, TransitionArray::cast(raw_transitions));
-  }
-
   // Since descriptor arrays are potentially shared, ensure that only the
   // descriptors that belong to this map are marked. The first time a
   // non-empty descriptor array is marked, its header is also visited. The slot
@@ -570,23 +565,6 @@ void StaticMarkingVisitor<StaticVisitor>::MarkMapContents(Heap* heap,
 }
 
 
-template <typename StaticVisitor>
-void StaticMarkingVisitor<StaticVisitor>::MarkTransitionArray(
-    Heap* heap, TransitionArray* transitions) {
-  if (!StaticVisitor::MarkObjectWithoutPush(heap, transitions)) return;
-
-  if (transitions->HasPrototypeTransitions()) {
-    StaticVisitor::VisitPointer(heap,
-                                transitions->GetPrototypeTransitionsSlot());
-  }
-
-  int num_transitions = TransitionArray::NumberOfTransitions(transitions);
-  for (int i = 0; i < num_transitions; ++i) {
-    StaticVisitor::VisitPointer(heap, transitions->GetKeySlot(i));
-  }
-}
-
-
 template <typename StaticVisitor>
 void StaticMarkingVisitor<StaticVisitor>::MarkInlinedFunctionsCode(Heap* heap,
                                                                    Code* code) {
index 1b788e893b7b23d0236d4acbe5e59ef61bee4f23..9d1634516d89120bb84400ccba04134a098467ec 100644 (file)
@@ -438,7 +438,6 @@ class StaticMarkingVisitor : public StaticVisitorBase {
   // Mark pointers in a Map and its TransitionArray together, possibly
   // treating transitions or back pointers weak.
   static void MarkMapContents(Heap* heap, Map* map);
-  static void MarkTransitionArray(Heap* heap, TransitionArray* transitions);
 
   // Code flushing support.
   INLINE(static bool IsFlushable(Heap* heap, JSFunction* function));
index f31eff96ba19e6e8e1dca0f1a4b3ee0c7c654a53..870c8e7c0696a58400173c4dd056c34baca2e42e 100644 (file)
@@ -47,6 +47,12 @@ Object** TransitionArray::GetKeySlot(int transition_number) {
 }
 
 
+Object** TransitionArray::GetTargetSlot(int transition_number) {
+  DCHECK(transition_number < number_of_transitions());
+  return RawFieldOfElementAt(ToTargetIndex(transition_number));
+}
+
+
 Name* TransitionArray::GetKey(int transition_number) {
   DCHECK(transition_number < number_of_transitions());
   return Name::cast(get(ToKeyIndex(transition_number)));
@@ -71,7 +77,8 @@ void TransitionArray::SetKey(int transition_number, Name* key) {
 
 Map* TransitionArray::GetTarget(int transition_number) {
   DCHECK(transition_number < number_of_transitions());
-  return Map::cast(get(ToTargetIndex(transition_number)));
+  WeakCell* cell = GetTargetCell(transition_number);
+  return Map::cast(cell->value());
 }
 
 
@@ -86,7 +93,13 @@ Map* TransitionArray::GetTarget(Object* raw_transitions,
 }
 
 
-void TransitionArray::SetTarget(int transition_number, Map* value) {
+WeakCell* TransitionArray::GetTargetCell(int transition_number) {
+  DCHECK(transition_number < number_of_transitions());
+  return WeakCell::cast(get(ToTargetIndex(transition_number)));
+}
+
+
+void TransitionArray::SetTargetCell(int transition_number, WeakCell* value) {
   DCHECK(transition_number < number_of_transitions());
   set(ToTargetIndex(transition_number), value);
 }
@@ -158,13 +171,9 @@ PropertyDetails TransitionArray::GetTargetDetails(Name* name, Map* target) {
 }
 
 
-void TransitionArray::NoIncrementalWriteBarrierSet(int transition_number,
-                                                   Name* key,
-                                                   Map* target) {
-  FixedArray::NoIncrementalWriteBarrierSet(
-      this, ToKeyIndex(transition_number), key);
-  FixedArray::NoIncrementalWriteBarrierSet(
-      this, ToTargetIndex(transition_number), target);
+void TransitionArray::Set(int transition_number, Name* key, WeakCell* target) {
+  set(ToKeyIndex(transition_number), key);
+  set(ToTargetIndex(transition_number), target);
 }
 
 
index c39534bbb566a2930934d2a56482517a2d18e1c6..d646eb80c888f287b42ec346ccc9585c22a4b622 100644 (file)
@@ -17,11 +17,11 @@ void TransitionArray::Insert(Handle<Map> map, Handle<Name> name,
                              Handle<Map> target, SimpleTransitionFlag flag) {
   Isolate* isolate = map->GetIsolate();
   target->SetBackPointer(*map);
+  Handle<WeakCell> cell = Map::WeakCellForMap(target);
 
   // If the map doesn't have any transitions at all yet, install the new one.
   if (CanStoreSimpleTransition(map->raw_transitions())) {
     if (flag == SIMPLE_PROPERTY_TRANSITION) {
-      Handle<WeakCell> cell = Map::WeakCellForMap(target);
       ReplaceTransitions(map, *cell);
       return;
     }
@@ -42,7 +42,6 @@ void TransitionArray::Insert(Handle<Map> map, Handle<Name> name,
     if (flag == SIMPLE_PROPERTY_TRANSITION && key->Equals(*name) &&
         old_details.kind() == new_details.kind() &&
         old_details.attributes() == new_details.attributes()) {
-      Handle<WeakCell> cell = Map::WeakCellForMap(target);
       ReplaceTransitions(map, *cell);
       return;
     }
@@ -51,8 +50,8 @@ void TransitionArray::Insert(Handle<Map> map, Handle<Name> name,
     // Re-read existing data; the allocation might have caused it to be cleared.
     if (IsSimpleTransition(map->raw_transitions())) {
       old_target = GetSimpleTransition(map->raw_transitions());
-      result->NoIncrementalWriteBarrierSet(
-          0, GetSimpleTransitionKey(old_target), old_target);
+      result->Set(0, GetSimpleTransitionKey(old_target),
+                  GetSimpleTransitionCell(map->raw_transitions()));
     } else {
       result->SetNumberOfTransitions(0);
     }
@@ -83,7 +82,7 @@ void TransitionArray::Insert(Handle<Map> map, Handle<Name> name,
                             &insertion_index);
     // If an existing entry was found, overwrite it and return.
     if (index != kNotFound) {
-      array->SetTarget(index, *target);
+      array->SetTargetCell(index, *cell);
       return;
     }
 
@@ -96,10 +95,10 @@ void TransitionArray::Insert(Handle<Map> map, Handle<Name> name,
       array->SetNumberOfTransitions(new_nof);
       for (index = number_of_transitions; index > insertion_index; --index) {
         array->SetKey(index, array->GetKey(index - 1));
-        array->SetTarget(index, array->GetTarget(index - 1));
+        array->SetTargetCell(index, array->GetTargetCell(index - 1));
       }
       array->SetKey(index, *name);
-      array->SetTarget(index, *target);
+      array->SetTargetCell(index, *cell);
       SLOW_DCHECK(array->IsSortedNoDuplicates());
       return;
     }
@@ -145,11 +144,11 @@ void TransitionArray::Insert(Handle<Map> map, Handle<Name> name,
 
   DCHECK_NE(kNotFound, insertion_index);
   for (int i = 0; i < insertion_index; ++i) {
-    result->NoIncrementalWriteBarrierCopyFrom(array, i, i);
+    result->CopyFrom(array, i, i);
   }
-  result->NoIncrementalWriteBarrierSet(insertion_index, *name, *target);
+  result->Set(insertion_index, *name, *cell);
   for (int i = insertion_index; i < number_of_transitions; ++i) {
-    result->NoIncrementalWriteBarrierCopyFrom(array, i, i + 1);
+    result->CopyFrom(array, i, i + 1);
   }
 
   SLOW_DCHECK(result->IsSortedNoDuplicates());
@@ -349,12 +348,10 @@ Handle<TransitionArray> TransitionArray::Allocate(Isolate* isolate,
 }
 
 
-void TransitionArray::NoIncrementalWriteBarrierCopyFrom(TransitionArray* origin,
-                                                        int origin_transition,
-                                                        int target_transition) {
-  NoIncrementalWriteBarrierSet(target_transition,
-                               origin->GetKey(origin_transition),
-                               origin->GetTarget(origin_transition));
+void TransitionArray::CopyFrom(TransitionArray* origin, int origin_transition,
+                               int target_transition) {
+  Set(target_transition, origin->GetKey(origin_transition),
+      origin->GetTargetCell(origin_transition));
 }
 
 
@@ -422,9 +419,9 @@ void TransitionArray::EnsureHasFullTransitionArray(Handle<Map> map) {
     result->Shrink(ToKeyIndex(0));
     result->SetNumberOfTransitions(0);
   } else if (nof == 1) {
-    Map* target = GetSimpleTransition(raw_transitions);
-    Name* key = GetSimpleTransitionKey(target);
-    result->NoIncrementalWriteBarrierSet(0, key, target);
+    WeakCell* target_cell = GetSimpleTransitionCell(raw_transitions);
+    Name* key = GetSimpleTransitionKey(Map::cast(target_cell->value()));
+    result->Set(0, key, target_cell);
   }
   ReplaceTransitions(map, *result);
 }
index b0aab9502e5d2e08dd810ae16aac23cc5edd7bf5..9e14279757082432569da63df82e7875caa12694 100644 (file)
@@ -71,6 +71,11 @@ class TransitionArray: public FixedArray {
     DCHECK(raw_transition->IsWeakCell());
     return Map::cast(WeakCell::cast(raw_transition)->value());
   }
+  static inline WeakCell* GetSimpleTransitionCell(Object* raw_transition) {
+    DCHECK(IsSimpleTransition(raw_transition));
+    DCHECK(raw_transition->IsWeakCell());
+    return WeakCell::cast(raw_transition);
+  }
   static inline bool IsFullTransitionArray(Object* raw_transitions) {
     return raw_transitions->IsTransitionArray();
   }
@@ -135,6 +140,7 @@ class TransitionArray: public FixedArray {
   inline Name* GetKey(int transition_number);
   inline void SetKey(int transition_number, Name* value);
   inline Object** GetKeySlot(int transition_number);
+  inline Object** GetTargetSlot(int transition_number);
   int GetSortedKeyIndex(int transition_number) { return transition_number; }
 
   Name* GetSortedKey(int transition_number) {
@@ -143,7 +149,9 @@ class TransitionArray: public FixedArray {
 
   static inline Map* GetTarget(Object* raw_transitions, int transition_number);
   inline Map* GetTarget(int transition_number);
-  inline void SetTarget(int transition_number, Map* target);
+
+  inline WeakCell* GetTargetCell(int transition_number);
+  inline void SetTargetCell(int transition_number, WeakCell* target);
 
   static inline PropertyDetails GetTargetDetails(Name* name, Map* target);
 
@@ -283,14 +291,11 @@ class TransitionArray: public FixedArray {
                                    PropertyKind kind2,
                                    PropertyAttributes attributes2);
 
-  inline void NoIncrementalWriteBarrierSet(int transition_number,
-                                           Name* key,
-                                           Map* target);
+  inline void Set(int transition_number, Name* key, WeakCell* target_cell);
 
   // Copy a single transition from the origin array.
-  inline void NoIncrementalWriteBarrierCopyFrom(TransitionArray* origin,
-                                                int origin_transition,
-                                                int target_transition);
+  inline void CopyFrom(TransitionArray* origin, int origin_transition,
+                       int target_transition);
 
 #ifdef DEBUG
   static void CheckNewTransitionsAreConsistent(Handle<Map> map,