Chromium Code Reviews| Index: src/objects.cc |
| diff --git a/src/objects.cc b/src/objects.cc |
| index 03f5e553a4bf65981fc10858d904a1499947224e..7bbb87dfe0f390fe84973048b8b00a3a2032d4c1 100644 |
| --- a/src/objects.cc |
| +++ b/src/objects.cc |
| @@ -5135,11 +5135,11 @@ class IntrusivePrototypeTransitionIterator { |
| void Start() { |
| ASSERT(!IsIterating()); |
| - if (HasTransitions()) *Header() = Smi::FromInt(0); |
| + *Header() = Smi::FromInt(0); |
|
Michael Starzinger
2012/07/06 13:53:18
Oh yeah, I like that change!
|
| } |
| bool IsIterating() { |
| - return HasTransitions() && (*Header())->IsSmi(); |
| + return (*Header())->IsSmi(); |
| } |
| Map* Next() { |
| @@ -5154,23 +5154,17 @@ class IntrusivePrototypeTransitionIterator { |
| } |
| private: |
| - bool HasTransitions() { |
| - return proto_trans_->map()->IsSmi() || proto_trans_->IsFixedArray(); |
| - } |
| - |
| Object** Header() { |
| return HeapObject::RawField(proto_trans_, FixedArray::kMapOffset); |
| } |
| int NumberOfTransitions() { |
| - ASSERT(HasTransitions()); |
| FixedArray* proto_trans = reinterpret_cast<FixedArray*>(proto_trans_); |
| Object* num = proto_trans->get(Map::kProtoTransitionNumberOfEntriesOffset); |
| return Smi::cast(num)->value(); |
| } |
| Map* GetTransition(int transitionNumber) { |
| - ASSERT(HasTransitions()); |
| FixedArray* proto_trans = reinterpret_cast<FixedArray*>(proto_trans_); |
| return Map::cast(proto_trans->get(IndexFor(transitionNumber))); |
| } |
| @@ -5220,42 +5214,41 @@ class TraversableMap : public Map { |
| return old_parent; |
| } |
| - // Can either be Smi (no instance descriptors), or a descriptor array with the |
| - // header overwritten as a Smi (thus iterating). |
| - TransitionArray* MutatedTransitions() { |
| - Object* object = *HeapObject::RawField(instance_descriptors(), |
| - DescriptorArray::kTransitionsOffset); |
| - TransitionArray* transition_array = static_cast<TransitionArray*>(object); |
| - return transition_array; |
| - } |
| - |
| // Start iterating over this map's children, possibly destroying a FixedArray |
| // map (see explanation above). |
| void ChildIteratorStart() { |
| if (HasTransitionArray()) { |
| + if (HasPrototypeTransitions()) { |
| + IntrusivePrototypeTransitionIterator(prototype_transitions()).Start(); |
| + } |
| + |
| IntrusiveMapTransitionIterator(transitions()).Start(); |
| } |
| - IntrusivePrototypeTransitionIterator( |
| - unchecked_prototype_transitions()).Start(); |
| } |
| // If we have an unvisited child map, return that one and advance. If we have |
| // none, return NULL and reset any destroyed FixedArray maps. |
| TraversableMap* ChildIteratorNext() { |
| - IntrusivePrototypeTransitionIterator |
| - proto_iterator(unchecked_prototype_transitions()); |
| - if (proto_iterator.IsIterating()) { |
| - Map* next = proto_iterator.Next(); |
| - if (next != NULL) return static_cast<TraversableMap*>(next); |
| - } |
| if (HasTransitionArray()) { |
| - IntrusiveMapTransitionIterator |
| - transitions_iterator(MutatedTransitions()); |
| - if (transitions_iterator.IsIterating()) { |
| - Map* next = transitions_iterator.Next(); |
| + TransitionArray* transition_array = unchecked_transition_array(); |
| + |
| + if (transition_array->HasPrototypeTransitions()) { |
| + HeapObject* proto_transitions = |
| + transition_array->unchecked_prototype_transitions(); |
| + IntrusivePrototypeTransitionIterator proto_iterator(proto_transitions); |
| + if (proto_iterator.IsIterating()) { |
| + Map* next = proto_iterator.Next(); |
| + if (next != NULL) return static_cast<TraversableMap*>(next); |
| + } |
| + } |
| + |
| + IntrusiveMapTransitionIterator transition_iterator(transition_array); |
| + if (transition_iterator.IsIterating()) { |
| + Map* next = transition_iterator.Next(); |
| if (next != NULL) return static_cast<TraversableMap*>(next); |
| } |
| } |
| + |
| return NULL; |
| } |
| }; |
| @@ -7404,7 +7397,9 @@ void Map::ClearNonLiveTransitions(Heap* heap) { |
| // If the final transition array does not contain any live transitions, remove |
| // the transition array from the map. |
| - if (transition_index == 0 && !t->HasElementsTransition()) { |
| + if (transition_index == 0 && |
| + !t->HasElementsTransition() && |
| + !t->HasPrototypeTransitions()) { |
| return ClearTransitions(); |
| } |
| @@ -8867,7 +8862,8 @@ MaybeObject* Map::PutPrototypeTransition(Object* prototype, Map* map) { |
| new_cache->set(i + header, cache->get(i + header)); |
| } |
| cache = new_cache; |
| - set_prototype_transitions(cache); |
| + MaybeObject* set_result = set_prototype_transitions(cache); |
| + if (set_result->IsFailure()) return set_result; |
| } |
| int last = transitions - 1; |