| OLD | NEW | 
|      1 // Copyright 2012 the V8 project authors. All rights reserved. |      1 // Copyright 2012 the V8 project authors. All rights reserved. | 
|      2 // Redistribution and use in source and binary forms, with or without |      2 // Redistribution and use in source and binary forms, with or without | 
|      3 // modification, are permitted provided that the following conditions are |      3 // modification, are permitted provided that the following conditions are | 
|      4 // met: |      4 // met: | 
|      5 // |      5 // | 
|      6 //     * Redistributions of source code must retain the above copyright |      6 //     * Redistributions of source code must retain the above copyright | 
|      7 //       notice, this list of conditions and the following disclaimer. |      7 //       notice, this list of conditions and the following disclaimer. | 
|      8 //     * Redistributions in binary form must reproduce the above |      8 //     * Redistributions in binary form must reproduce the above | 
|      9 //       copyright notice, this list of conditions and the following |      9 //       copyright notice, this list of conditions and the following | 
|     10 //       disclaimer in the documentation and/or other materials provided |     10 //       disclaimer in the documentation and/or other materials provided | 
| (...skipping 5117 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   5128  |   5128  | 
|   5129 // An iterator over all prototype transitions, reusing the map field of the |   5129 // An iterator over all prototype transitions, reusing the map field of the | 
|   5130 // underlying array while it is running. |   5130 // underlying array while it is running. | 
|   5131 class IntrusivePrototypeTransitionIterator { |   5131 class IntrusivePrototypeTransitionIterator { | 
|   5132  public: |   5132  public: | 
|   5133   explicit IntrusivePrototypeTransitionIterator(HeapObject* proto_trans) |   5133   explicit IntrusivePrototypeTransitionIterator(HeapObject* proto_trans) | 
|   5134       : proto_trans_(proto_trans) { } |   5134       : proto_trans_(proto_trans) { } | 
|   5135  |   5135  | 
|   5136   void Start() { |   5136   void Start() { | 
|   5137     ASSERT(!IsIterating()); |   5137     ASSERT(!IsIterating()); | 
|   5138     if (HasTransitions()) *Header() = Smi::FromInt(0); |   5138     *Header() = Smi::FromInt(0); | 
|   5139   } |   5139   } | 
|   5140  |   5140  | 
|   5141   bool IsIterating() { |   5141   bool IsIterating() { | 
|   5142     return HasTransitions() && (*Header())->IsSmi(); |   5142     return (*Header())->IsSmi(); | 
|   5143   } |   5143   } | 
|   5144  |   5144  | 
|   5145   Map* Next() { |   5145   Map* Next() { | 
|   5146     ASSERT(IsIterating()); |   5146     ASSERT(IsIterating()); | 
|   5147     int transitionNumber = Smi::cast(*Header())->value(); |   5147     int transitionNumber = Smi::cast(*Header())->value(); | 
|   5148     if (transitionNumber < NumberOfTransitions()) { |   5148     if (transitionNumber < NumberOfTransitions()) { | 
|   5149       *Header() = Smi::FromInt(transitionNumber + 1); |   5149       *Header() = Smi::FromInt(transitionNumber + 1); | 
|   5150       return GetTransition(transitionNumber); |   5150       return GetTransition(transitionNumber); | 
|   5151     } |   5151     } | 
|   5152     *Header() = proto_trans_->GetHeap()->fixed_array_map(); |   5152     *Header() = proto_trans_->GetHeap()->fixed_array_map(); | 
|   5153     return NULL; |   5153     return NULL; | 
|   5154   } |   5154   } | 
|   5155  |   5155  | 
|   5156  private: |   5156  private: | 
|   5157   bool HasTransitions() { |  | 
|   5158     return proto_trans_->map()->IsSmi() || proto_trans_->IsFixedArray(); |  | 
|   5159   } |  | 
|   5160  |  | 
|   5161   Object** Header() { |   5157   Object** Header() { | 
|   5162     return HeapObject::RawField(proto_trans_, FixedArray::kMapOffset); |   5158     return HeapObject::RawField(proto_trans_, FixedArray::kMapOffset); | 
|   5163   } |   5159   } | 
|   5164  |   5160  | 
|   5165   int NumberOfTransitions() { |   5161   int NumberOfTransitions() { | 
|   5166     ASSERT(HasTransitions()); |  | 
|   5167     FixedArray* proto_trans = reinterpret_cast<FixedArray*>(proto_trans_); |   5162     FixedArray* proto_trans = reinterpret_cast<FixedArray*>(proto_trans_); | 
|   5168     Object* num = proto_trans->get(Map::kProtoTransitionNumberOfEntriesOffset); |   5163     Object* num = proto_trans->get(Map::kProtoTransitionNumberOfEntriesOffset); | 
|   5169     return Smi::cast(num)->value(); |   5164     return Smi::cast(num)->value(); | 
|   5170   } |   5165   } | 
|   5171  |   5166  | 
|   5172   Map* GetTransition(int transitionNumber) { |   5167   Map* GetTransition(int transitionNumber) { | 
|   5173     ASSERT(HasTransitions()); |  | 
|   5174     FixedArray* proto_trans = reinterpret_cast<FixedArray*>(proto_trans_); |   5168     FixedArray* proto_trans = reinterpret_cast<FixedArray*>(proto_trans_); | 
|   5175     return Map::cast(proto_trans->get(IndexFor(transitionNumber))); |   5169     return Map::cast(proto_trans->get(IndexFor(transitionNumber))); | 
|   5176   } |   5170   } | 
|   5177  |   5171  | 
|   5178   int IndexFor(int transitionNumber) { |   5172   int IndexFor(int transitionNumber) { | 
|   5179     return Map::kProtoTransitionHeaderSize + |   5173     return Map::kProtoTransitionHeaderSize + | 
|   5180         Map::kProtoTransitionMapOffset + |   5174         Map::kProtoTransitionMapOffset + | 
|   5181         transitionNumber * Map::kProtoTransitionElementsPerEntry; |   5175         transitionNumber * Map::kProtoTransitionElementsPerEntry; | 
|   5182   } |   5176   } | 
|   5183  |   5177  | 
| (...skipping 29 matching lines...) Expand all  Loading... | 
|   5213   // this map's map! |   5207   // this map's map! | 
|   5214   void SetParent(TraversableMap* parent) { set_map_no_write_barrier(parent); } |   5208   void SetParent(TraversableMap* parent) { set_map_no_write_barrier(parent); } | 
|   5215  |   5209  | 
|   5216   // Reset the current map's map, returning the parent previously stored in it. |   5210   // Reset the current map's map, returning the parent previously stored in it. | 
|   5217   TraversableMap* GetAndResetParent() { |   5211   TraversableMap* GetAndResetParent() { | 
|   5218     TraversableMap* old_parent = static_cast<TraversableMap*>(map()); |   5212     TraversableMap* old_parent = static_cast<TraversableMap*>(map()); | 
|   5219     set_map_no_write_barrier(GetHeap()->meta_map()); |   5213     set_map_no_write_barrier(GetHeap()->meta_map()); | 
|   5220     return old_parent; |   5214     return old_parent; | 
|   5221   } |   5215   } | 
|   5222  |   5216  | 
|   5223   // Can either be Smi (no instance descriptors), or a descriptor array with the |  | 
|   5224   // header overwritten as a Smi (thus iterating). |  | 
|   5225   TransitionArray* MutatedTransitions() { |  | 
|   5226     Object* object = *HeapObject::RawField(instance_descriptors(), |  | 
|   5227                                            DescriptorArray::kTransitionsOffset); |  | 
|   5228     TransitionArray* transition_array = static_cast<TransitionArray*>(object); |  | 
|   5229     return transition_array; |  | 
|   5230   } |  | 
|   5231  |  | 
|   5232   // Start iterating over this map's children, possibly destroying a FixedArray |   5217   // Start iterating over this map's children, possibly destroying a FixedArray | 
|   5233   // map (see explanation above). |   5218   // map (see explanation above). | 
|   5234   void ChildIteratorStart() { |   5219   void ChildIteratorStart() { | 
|   5235     if (HasTransitionArray()) { |   5220     if (HasTransitionArray()) { | 
 |   5221       if (HasPrototypeTransitions()) { | 
 |   5222         IntrusivePrototypeTransitionIterator(GetPrototypeTransitions()).Start(); | 
 |   5223       } | 
 |   5224  | 
|   5236       IntrusiveMapTransitionIterator(transitions()).Start(); |   5225       IntrusiveMapTransitionIterator(transitions()).Start(); | 
|   5237     } |   5226     } | 
|   5238     IntrusivePrototypeTransitionIterator( |  | 
|   5239         unchecked_prototype_transitions()).Start(); |  | 
|   5240   } |   5227   } | 
|   5241  |   5228  | 
|   5242   // If we have an unvisited child map, return that one and advance. If we have |   5229   // If we have an unvisited child map, return that one and advance. If we have | 
|   5243   // none, return NULL and reset any destroyed FixedArray maps. |   5230   // none, return NULL and reset any destroyed FixedArray maps. | 
|   5244   TraversableMap* ChildIteratorNext() { |   5231   TraversableMap* ChildIteratorNext() { | 
|   5245     IntrusivePrototypeTransitionIterator |  | 
|   5246         proto_iterator(unchecked_prototype_transitions()); |  | 
|   5247     if (proto_iterator.IsIterating()) { |  | 
|   5248       Map* next = proto_iterator.Next(); |  | 
|   5249       if (next != NULL) return static_cast<TraversableMap*>(next); |  | 
|   5250     } |  | 
|   5251     if (HasTransitionArray()) { |   5232     if (HasTransitionArray()) { | 
|   5252       IntrusiveMapTransitionIterator |   5233       TransitionArray* transition_array = unchecked_transition_array(); | 
|   5253           transitions_iterator(MutatedTransitions()); |   5234  | 
|   5254       if (transitions_iterator.IsIterating()) { |   5235       if (transition_array->HasPrototypeTransitions()) { | 
|   5255         Map* next = transitions_iterator.Next(); |   5236         HeapObject* proto_transitions = | 
 |   5237             transition_array->UncheckedPrototypeTransitions(); | 
 |   5238         IntrusivePrototypeTransitionIterator proto_iterator(proto_transitions); | 
 |   5239         if (proto_iterator.IsIterating()) { | 
 |   5240           Map* next = proto_iterator.Next(); | 
 |   5241           if (next != NULL) return static_cast<TraversableMap*>(next); | 
 |   5242         } | 
 |   5243       } | 
 |   5244  | 
 |   5245       IntrusiveMapTransitionIterator transition_iterator(transition_array); | 
 |   5246       if (transition_iterator.IsIterating()) { | 
 |   5247         Map* next = transition_iterator.Next(); | 
|   5256         if (next != NULL) return static_cast<TraversableMap*>(next); |   5248         if (next != NULL) return static_cast<TraversableMap*>(next); | 
|   5257       } |   5249       } | 
|   5258     } |   5250     } | 
 |   5251  | 
|   5259     return NULL; |   5252     return NULL; | 
|   5260   } |   5253   } | 
|   5261 }; |   5254 }; | 
|   5262  |   5255  | 
|   5263  |   5256  | 
|   5264 // Traverse the transition tree in postorder without using the C++ stack by |   5257 // Traverse the transition tree in postorder without using the C++ stack by | 
|   5265 // doing pointer reversal. |   5258 // doing pointer reversal. | 
|   5266 void Map::TraverseTransitionTree(TraverseCallback callback, void* data) { |   5259 void Map::TraverseTransitionTree(TraverseCallback callback, void* data) { | 
|   5267   TraversableMap* current = static_cast<TraversableMap*>(this); |   5260   TraversableMap* current = static_cast<TraversableMap*>(this); | 
|   5268   current->ChildIteratorStart(); |   5261   current->ChildIteratorStart(); | 
| (...skipping 2128 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   7397     t->ClearElementsTransition(); |   7390     t->ClearElementsTransition(); | 
|   7398   } else { |   7391   } else { | 
|   7399     // If there are no transitions to be cleared, return. |   7392     // If there are no transitions to be cleared, return. | 
|   7400     // TODO(verwaest) Should be an assert, otherwise back pointers are not |   7393     // TODO(verwaest) Should be an assert, otherwise back pointers are not | 
|   7401     // properly cleared. |   7394     // properly cleared. | 
|   7402     if (transition_index == t->number_of_transitions()) return; |   7395     if (transition_index == t->number_of_transitions()) return; | 
|   7403   } |   7396   } | 
|   7404  |   7397  | 
|   7405   // If the final transition array does not contain any live transitions, remove |   7398   // If the final transition array does not contain any live transitions, remove | 
|   7406   // the transition array from the map. |   7399   // the transition array from the map. | 
|   7407   if (transition_index == 0 && !t->HasElementsTransition()) { |   7400   if (transition_index == 0 && | 
 |   7401       !t->HasElementsTransition() && | 
 |   7402       !t->HasPrototypeTransitions()) { | 
|   7408     return ClearTransitions(); |   7403     return ClearTransitions(); | 
|   7409   } |   7404   } | 
|   7410  |   7405  | 
|   7411   int trim = t->number_of_transitions() - transition_index; |   7406   int trim = t->number_of_transitions() - transition_index; | 
|   7412   if (trim > 0) { |   7407   if (trim > 0) { | 
|   7413     RightTrimFixedArray(heap, t, trim * TransitionArray::kTransitionSize); |   7408     RightTrimFixedArray(heap, t, trim * TransitionArray::kTransitionSize); | 
|   7414   } |   7409   } | 
|   7415 } |   7410 } | 
|   7416  |   7411  | 
|   7417  |   7412  | 
| (...skipping 1397 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   8815  |   8810  | 
|   8816  |   8811  | 
|   8817 MaybeObject* JSArray::SetElementsLength(Object* len) { |   8812 MaybeObject* JSArray::SetElementsLength(Object* len) { | 
|   8818   // We should never end in here with a pixel or external array. |   8813   // We should never end in here with a pixel or external array. | 
|   8819   ASSERT(AllowsSetElementsLength()); |   8814   ASSERT(AllowsSetElementsLength()); | 
|   8820   return GetElementsAccessor()->SetLength(this, len); |   8815   return GetElementsAccessor()->SetLength(this, len); | 
|   8821 } |   8816 } | 
|   8822  |   8817  | 
|   8823  |   8818  | 
|   8824 Map* Map::GetPrototypeTransition(Object* prototype) { |   8819 Map* Map::GetPrototypeTransition(Object* prototype) { | 
|   8825   FixedArray* cache = prototype_transitions(); |   8820   FixedArray* cache = GetPrototypeTransitions(); | 
|   8826   int number_of_transitions = NumberOfProtoTransitions(); |   8821   int number_of_transitions = NumberOfProtoTransitions(); | 
|   8827   const int proto_offset = |   8822   const int proto_offset = | 
|   8828       kProtoTransitionHeaderSize + kProtoTransitionPrototypeOffset; |   8823       kProtoTransitionHeaderSize + kProtoTransitionPrototypeOffset; | 
|   8829   const int map_offset = kProtoTransitionHeaderSize + kProtoTransitionMapOffset; |   8824   const int map_offset = kProtoTransitionHeaderSize + kProtoTransitionMapOffset; | 
|   8830   const int step = kProtoTransitionElementsPerEntry; |   8825   const int step = kProtoTransitionElementsPerEntry; | 
|   8831   for (int i = 0; i < number_of_transitions; i++) { |   8826   for (int i = 0; i < number_of_transitions; i++) { | 
|   8832     if (cache->get(proto_offset + i * step) == prototype) { |   8827     if (cache->get(proto_offset + i * step) == prototype) { | 
|   8833       Object* map = cache->get(map_offset + i * step); |   8828       Object* map = cache->get(map_offset + i * step); | 
|   8834       return Map::cast(map); |   8829       return Map::cast(map); | 
|   8835     } |   8830     } | 
|   8836   } |   8831   } | 
|   8837   return NULL; |   8832   return NULL; | 
|   8838 } |   8833 } | 
|   8839  |   8834  | 
|   8840  |   8835  | 
|   8841 MaybeObject* Map::PutPrototypeTransition(Object* prototype, Map* map) { |   8836 MaybeObject* Map::PutPrototypeTransition(Object* prototype, Map* map) { | 
|   8842   ASSERT(map->IsMap()); |   8837   ASSERT(map->IsMap()); | 
|   8843   ASSERT(HeapObject::cast(prototype)->map()->IsMap()); |   8838   ASSERT(HeapObject::cast(prototype)->map()->IsMap()); | 
|   8844   // Don't cache prototype transition if this map is shared. |   8839   // Don't cache prototype transition if this map is shared. | 
|   8845   if (is_shared() || !FLAG_cache_prototype_transitions) return this; |   8840   if (is_shared() || !FLAG_cache_prototype_transitions) return this; | 
|   8846  |   8841  | 
|   8847   FixedArray* cache = prototype_transitions(); |   8842   FixedArray* cache = GetPrototypeTransitions(); | 
|   8848  |   8843  | 
|   8849   const int step = kProtoTransitionElementsPerEntry; |   8844   const int step = kProtoTransitionElementsPerEntry; | 
|   8850   const int header = kProtoTransitionHeaderSize; |   8845   const int header = kProtoTransitionHeaderSize; | 
|   8851  |   8846  | 
|   8852   int capacity = (cache->length() - header) / step; |   8847   int capacity = (cache->length() - header) / step; | 
|   8853  |   8848  | 
|   8854   int transitions = NumberOfProtoTransitions() + 1; |   8849   int transitions = NumberOfProtoTransitions() + 1; | 
|   8855  |   8850  | 
|   8856   if (transitions > capacity) { |   8851   if (transitions > capacity) { | 
|   8857     if (capacity > kMaxCachedPrototypeTransitions) return this; |   8852     if (capacity > kMaxCachedPrototypeTransitions) return this; | 
|   8858  |   8853  | 
|   8859     FixedArray* new_cache; |   8854     FixedArray* new_cache; | 
|   8860     // Grow array by factor 2 over and above what we need. |   8855     // Grow array by factor 2 over and above what we need. | 
|   8861     { MaybeObject* maybe_cache = |   8856     { MaybeObject* maybe_cache = | 
|   8862           GetHeap()->AllocateFixedArray(transitions * 2 * step + header); |   8857           GetHeap()->AllocateFixedArray(transitions * 2 * step + header); | 
|   8863       if (!maybe_cache->To(&new_cache)) return maybe_cache; |   8858       if (!maybe_cache->To(&new_cache)) return maybe_cache; | 
|   8864     } |   8859     } | 
|   8865  |   8860  | 
|   8866     for (int i = 0; i < capacity * step; i++) { |   8861     for (int i = 0; i < capacity * step; i++) { | 
|   8867       new_cache->set(i + header, cache->get(i + header)); |   8862       new_cache->set(i + header, cache->get(i + header)); | 
|   8868     } |   8863     } | 
|   8869     cache = new_cache; |   8864     cache = new_cache; | 
|   8870     set_prototype_transitions(cache); |   8865     MaybeObject* set_result = SetPrototypeTransitions(cache); | 
 |   8866     if (set_result->IsFailure()) return set_result; | 
|   8871   } |   8867   } | 
|   8872  |   8868  | 
|   8873   int last = transitions - 1; |   8869   int last = transitions - 1; | 
|   8874  |   8870  | 
|   8875   cache->set(header + last * step + kProtoTransitionPrototypeOffset, prototype); |   8871   cache->set(header + last * step + kProtoTransitionPrototypeOffset, prototype); | 
|   8876   cache->set(header + last * step + kProtoTransitionMapOffset, map); |   8872   cache->set(header + last * step + kProtoTransitionMapOffset, map); | 
|   8877   SetNumberOfProtoTransitions(transitions); |   8873   SetNumberOfProtoTransitions(transitions); | 
|   8878  |   8874  | 
|   8879   return cache; |   8875   return cache; | 
|   8880 } |   8876 } | 
| (...skipping 4382 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  13263   set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); |  13259   set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); | 
|  13264   set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); |  13260   set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); | 
|  13265   set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); |  13261   set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); | 
|  13266   set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); |  13262   set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); | 
|  13267   set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); |  13263   set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); | 
|  13268   set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); |  13264   set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); | 
|  13269   set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); |  13265   set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); | 
|  13270 } |  13266 } | 
|  13271  |  13267  | 
|  13272 } }  // namespace v8::internal |  13268 } }  // namespace v8::internal | 
| OLD | NEW |