| Index: src/transitions.cc
|
| diff --git a/src/transitions.cc b/src/transitions.cc
|
| index 63bb7fa68f515db5bb90e64fc4629e1807c6b898..c39534bbb566a2930934d2a56482517a2d18e1c6 100644
|
| --- a/src/transitions.cc
|
| +++ b/src/transitions.cc
|
| @@ -233,17 +233,19 @@ bool TransitionArray::CanHaveMoreTransitions(Handle<Map> map) {
|
|
|
|
|
| // static
|
| -Handle<Map> TransitionArray::PutPrototypeTransition(Handle<Map> map,
|
| - Handle<Object> prototype,
|
| - Handle<Map> target_map) {
|
| +void 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 map;
|
| - if (map->is_dictionary_map() || !FLAG_cache_prototype_transitions) return map;
|
| + if (map->is_prototype_map()) return;
|
| + if (map->is_dictionary_map() || !FLAG_cache_prototype_transitions) return;
|
|
|
| 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;
|
| @@ -251,7 +253,7 @@ Handle<Map> 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 map;
|
| + if (new_capacity == capacity) return;
|
|
|
| cache = FixedArray::CopySize(cache, header + new_capacity);
|
| if (capacity < 0) {
|
| @@ -267,10 +269,8 @@ Handle<Map> TransitionArray::PutPrototypeTransition(Handle<Map> map,
|
| int last = NumberOfPrototypeTransitions(*cache);
|
| int entry = header + last;
|
|
|
| - cache->set(entry, *target_map);
|
| + cache->set(entry, *target_cell);
|
| SetNumberOfPrototypeTransitions(*cache, last + 1);
|
| -
|
| - return map;
|
| }
|
|
|
|
|
| @@ -281,8 +281,12 @@ 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++) {
|
| - Map* target = Map::cast(cache->get(kProtoTransitionHeaderSize + i));
|
| - if (target->prototype() == *prototype) return handle(target);
|
| + 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()));
|
| + }
|
| }
|
| return Handle<Map>();
|
| }
|
| @@ -436,8 +440,9 @@ void TransitionArray::TraverseTransitionTreeInternal(Map* map,
|
| FixedArray* proto_trans = transitions->GetPrototypeTransitions();
|
| for (int i = 0; i < NumberOfPrototypeTransitions(proto_trans); ++i) {
|
| int index = TransitionArray::kProtoTransitionHeaderSize + i;
|
| - TraverseTransitionTreeInternal(Map::cast(proto_trans->get(index)),
|
| - callback, data);
|
| + WeakCell* cell = WeakCell::cast(proto_trans->get(index));
|
| + TraverseTransitionTreeInternal(Map::cast(cell->value()), callback,
|
| + data);
|
| }
|
| }
|
| for (int i = 0; i < transitions->number_of_transitions(); ++i) {
|
|
|