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++;
}
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
}
-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) {
// 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));
}
+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)));
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());
}
}
-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);
}
}
-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);
}
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;
}
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;
}
// 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);
}
&insertion_index);
// If an existing entry was found, overwrite it and return.
if (index != kNotFound) {
- array->SetTarget(index, *target);
+ array->SetTargetCell(index, *cell);
return;
}
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;
}
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());
}
-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));
}
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);
}
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();
}
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) {
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);
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,