OLD | NEW |
---|---|
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <sstream> | 5 #include <sstream> |
6 | 6 |
7 #include "src/v8.h" | 7 #include "src/v8.h" |
8 | 8 |
9 #include "src/accessors.h" | 9 #include "src/accessors.h" |
10 #include "src/allocation-site-scopes.h" | 10 #include "src/allocation-site-scopes.h" |
(...skipping 7472 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7483 } | 7483 } |
7484 | 7484 |
7485 int NumberOfTransitions() { | 7485 int NumberOfTransitions() { |
7486 FixedArray* proto_trans = reinterpret_cast<FixedArray*>(proto_trans_); | 7486 FixedArray* proto_trans = reinterpret_cast<FixedArray*>(proto_trans_); |
7487 Object* num = proto_trans->get(Map::kProtoTransitionNumberOfEntriesOffset); | 7487 Object* num = proto_trans->get(Map::kProtoTransitionNumberOfEntriesOffset); |
7488 return Smi::cast(num)->value(); | 7488 return Smi::cast(num)->value(); |
7489 } | 7489 } |
7490 | 7490 |
7491 Map* GetTransition(int transitionNumber) { | 7491 Map* GetTransition(int transitionNumber) { |
7492 FixedArray* proto_trans = reinterpret_cast<FixedArray*>(proto_trans_); | 7492 FixedArray* proto_trans = reinterpret_cast<FixedArray*>(proto_trans_); |
7493 return Map::cast(proto_trans->get(IndexFor(transitionNumber))); | 7493 int index = Map::kProtoTransitionHeaderSize + transitionNumber; |
7494 } | 7494 return Map::cast(proto_trans->get(index)); |
7495 | |
7496 int IndexFor(int transitionNumber) { | |
7497 return Map::kProtoTransitionHeaderSize + | |
7498 Map::kProtoTransitionMapOffset + | |
7499 transitionNumber * Map::kProtoTransitionElementsPerEntry; | |
7500 } | 7495 } |
7501 | 7496 |
7502 Map* map_; | 7497 Map* map_; |
7503 HeapObject* proto_trans_; | 7498 HeapObject* proto_trans_; |
7504 Object* constructor_; | 7499 Object* constructor_; |
7505 }; | 7500 }; |
7506 | 7501 |
7507 | 7502 |
7508 // To traverse the transition tree iteratively, we have to store two kinds of | 7503 // To traverse the transition tree iteratively, we have to store two kinds of |
7509 // information in a map: The parent map in the traversal and which children of a | 7504 // information in a map: The parent map in the traversal and which children of a |
(...skipping 4293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
11803 | 11798 |
11804 RETURN_ON_EXCEPTION( | 11799 RETURN_ON_EXCEPTION( |
11805 isolate, EnqueueSpliceRecord(array, index, deleted, add_count), Object); | 11800 isolate, EnqueueSpliceRecord(array, index, deleted, add_count), Object); |
11806 | 11801 |
11807 return hresult; | 11802 return hresult; |
11808 } | 11803 } |
11809 | 11804 |
11810 | 11805 |
11811 Handle<Map> Map::GetPrototypeTransition(Handle<Map> map, | 11806 Handle<Map> Map::GetPrototypeTransition(Handle<Map> map, |
11812 Handle<Object> prototype) { | 11807 Handle<Object> prototype) { |
11808 DisallowHeapAllocation no_gc; | |
11813 FixedArray* cache = map->GetPrototypeTransitions(); | 11809 FixedArray* cache = map->GetPrototypeTransitions(); |
11814 int number_of_transitions = map->NumberOfProtoTransitions(); | 11810 int number_of_transitions = map->NumberOfProtoTransitions(); |
11815 const int proto_offset = | |
11816 kProtoTransitionHeaderSize + kProtoTransitionPrototypeOffset; | |
11817 const int map_offset = kProtoTransitionHeaderSize + kProtoTransitionMapOffset; | |
11818 const int step = kProtoTransitionElementsPerEntry; | |
11819 for (int i = 0; i < number_of_transitions; i++) { | 11811 for (int i = 0; i < number_of_transitions; i++) { |
11820 if (cache->get(proto_offset + i * step) == *prototype) { | 11812 Map* map = Map::cast(cache->get(kProtoTransitionHeaderSize + i)); |
11821 Object* result = cache->get(map_offset + i * step); | 11813 if (map->prototype() == *prototype) return handle(map); |
11822 return Handle<Map>(Map::cast(result)); | |
11823 } | |
11824 } | 11814 } |
11825 return Handle<Map>(); | 11815 return Handle<Map>(); |
11826 } | 11816 } |
11827 | 11817 |
11828 | 11818 |
11829 Handle<Map> Map::PutPrototypeTransition(Handle<Map> map, | 11819 Handle<Map> Map::PutPrototypeTransition(Handle<Map> map, |
11830 Handle<Object> prototype, | 11820 Handle<Object> prototype, |
11831 Handle<Map> target_map) { | 11821 Handle<Map> target_map) { |
11832 DCHECK(target_map->IsMap()); | 11822 DCHECK(target_map->IsMap()); |
11833 DCHECK(HeapObject::cast(*prototype)->map()->IsMap()); | 11823 DCHECK(HeapObject::cast(*prototype)->map()->IsMap()); |
11834 // Don't cache prototype transition if this map is either shared, or a map of | 11824 // Don't cache prototype transition if this map is either shared, or a map of |
11835 // a prototype. | 11825 // a prototype. |
11836 if (map->is_prototype_map()) return map; | 11826 if (map->is_prototype_map()) return map; |
11837 if (map->is_dictionary_map() || !FLAG_cache_prototype_transitions) return map; | 11827 if (map->is_dictionary_map() || !FLAG_cache_prototype_transitions) return map; |
11838 | 11828 |
11839 const int step = kProtoTransitionElementsPerEntry; | |
11840 const int header = kProtoTransitionHeaderSize; | 11829 const int header = kProtoTransitionHeaderSize; |
11841 | 11830 |
11842 Handle<FixedArray> cache(map->GetPrototypeTransitions()); | 11831 Handle<FixedArray> cache(map->GetPrototypeTransitions()); |
11843 int capacity = (cache->length() - header) / step; | 11832 int capacity = cache->length() - header; |
11844 int transitions = map->NumberOfProtoTransitions() + 1; | 11833 int transitions = map->NumberOfProtoTransitions() + 1; |
11845 | 11834 |
11846 if (transitions > capacity) { | 11835 if (transitions > capacity) { |
11847 if (capacity > kMaxCachedPrototypeTransitions) return map; | 11836 // Grow array by factor 2 up to MaxCachedPrototypeTransitions. |
11837 int new_capacity = Min(kMaxCachedPrototypeTransitions, transitions * 2); | |
Hannes Payer (out of office)
2015/02/16 13:37:20
We could have used a constant there for the growin
| |
11838 if (new_capacity == capacity) return map; | |
11848 | 11839 |
11849 // Grow array by factor 2 over and above what we need. | 11840 cache = FixedArray::CopySize(cache, header + new_capacity); |
11850 cache = FixedArray::CopySize(cache, transitions * 2 * step + header); | |
11851 | 11841 |
11852 SetPrototypeTransitions(map, cache); | 11842 SetPrototypeTransitions(map, cache); |
11853 } | 11843 } |
11854 | 11844 |
11855 // Reload number of transitions as GC might shrink them. | 11845 // Reload number of transitions as GC might shrink them. |
11856 int last = map->NumberOfProtoTransitions(); | 11846 int last = map->NumberOfProtoTransitions(); |
11857 int entry = header + last * step; | 11847 int entry = header + last; |
11858 | 11848 |
11859 cache->set(entry + kProtoTransitionPrototypeOffset, *prototype); | 11849 cache->set(entry, *target_map); |
11860 cache->set(entry + kProtoTransitionMapOffset, *target_map); | |
11861 map->SetNumberOfProtoTransitions(last + 1); | 11850 map->SetNumberOfProtoTransitions(last + 1); |
11862 | 11851 |
11863 return map; | 11852 return map; |
11864 } | 11853 } |
11865 | 11854 |
11866 | 11855 |
11867 void Map::ZapTransitions() { | 11856 void Map::ZapTransitions() { |
11868 TransitionArray* transition_array = transitions(); | 11857 TransitionArray* transition_array = transitions(); |
11869 // TODO(mstarzinger): Temporarily use a slower version instead of the faster | 11858 // TODO(mstarzinger): Temporarily use a slower version instead of the faster |
11870 // MemsetPointer to investigate a crasher. Switch back to MemsetPointer. | 11859 // MemsetPointer to investigate a crasher. Switch back to MemsetPointer. |
(...skipping 5134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
17005 CompilationInfo* info) { | 16994 CompilationInfo* info) { |
17006 Handle<DependentCode> codes = DependentCode::InsertCompilationInfo( | 16995 Handle<DependentCode> codes = DependentCode::InsertCompilationInfo( |
17007 handle(cell->dependent_code(), info->isolate()), | 16996 handle(cell->dependent_code(), info->isolate()), |
17008 DependentCode::kPropertyCellChangedGroup, info->object_wrapper()); | 16997 DependentCode::kPropertyCellChangedGroup, info->object_wrapper()); |
17009 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); | 16998 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); |
17010 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( | 16999 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( |
17011 cell, info->zone()); | 17000 cell, info->zone()); |
17012 } | 17001 } |
17013 | 17002 |
17014 } } // namespace v8::internal | 17003 } } // namespace v8::internal |
OLD | NEW |