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 3302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3313 } | 3313 } |
3314 | 3314 |
3315 | 3315 |
3316 static Handle<Map> AddMissingElementsTransitions(Handle<Map> map, | 3316 static Handle<Map> AddMissingElementsTransitions(Handle<Map> map, |
3317 ElementsKind to_kind) { | 3317 ElementsKind to_kind) { |
3318 DCHECK(IsTransitionElementsKind(map->elements_kind())); | 3318 DCHECK(IsTransitionElementsKind(map->elements_kind())); |
3319 | 3319 |
3320 Handle<Map> current_map = map; | 3320 Handle<Map> current_map = map; |
3321 | 3321 |
3322 ElementsKind kind = map->elements_kind(); | 3322 ElementsKind kind = map->elements_kind(); |
3323 if (!map->is_prototype_map()) { | 3323 TransitionFlag flag; |
| 3324 if (map->is_prototype_map()) { |
| 3325 flag = OMIT_TRANSITION; |
| 3326 } else { |
| 3327 flag = INSERT_TRANSITION; |
3324 while (kind != to_kind && !IsTerminalElementsKind(kind)) { | 3328 while (kind != to_kind && !IsTerminalElementsKind(kind)) { |
3325 kind = GetNextTransitionElementsKind(kind); | 3329 kind = GetNextTransitionElementsKind(kind); |
3326 current_map = | 3330 current_map = Map::CopyAsElementsKind(current_map, kind, flag); |
3327 Map::CopyAsElementsKind(current_map, kind, INSERT_TRANSITION); | |
3328 } | 3331 } |
3329 } | 3332 } |
3330 | 3333 |
3331 // In case we are exiting the fast elements kind system, just add the map in | 3334 // In case we are exiting the fast elements kind system, just add the map in |
3332 // the end. | 3335 // the end. |
3333 if (kind != to_kind) { | 3336 if (kind != to_kind) { |
3334 current_map = Map::CopyAsElementsKind( | 3337 current_map = Map::CopyAsElementsKind(current_map, to_kind, flag); |
3335 current_map, to_kind, INSERT_TRANSITION); | |
3336 } | 3338 } |
3337 | 3339 |
3338 DCHECK(current_map->elements_kind() == to_kind); | 3340 DCHECK(current_map->elements_kind() == to_kind); |
3339 return current_map; | 3341 return current_map; |
3340 } | 3342 } |
3341 | 3343 |
3342 | 3344 |
3343 Handle<Map> Map::TransitionElementsTo(Handle<Map> map, | 3345 Handle<Map> Map::TransitionElementsTo(Handle<Map> map, |
3344 ElementsKind to_kind) { | 3346 ElementsKind to_kind) { |
3345 ElementsKind from_kind = map->elements_kind(); | 3347 ElementsKind from_kind = map->elements_kind(); |
(...skipping 3445 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6791 IsExternalArrayElementsKind(kind)))); | 6793 IsExternalArrayElementsKind(kind)))); |
6792 DCHECK(!IsFastElementsKind(kind) || | 6794 DCHECK(!IsFastElementsKind(kind) || |
6793 IsMoreGeneralElementsKindTransition(map->elements_kind(), kind)); | 6795 IsMoreGeneralElementsKindTransition(map->elements_kind(), kind)); |
6794 DCHECK(kind != map->elements_kind()); | 6796 DCHECK(kind != map->elements_kind()); |
6795 } | 6797 } |
6796 | 6798 |
6797 bool insert_transition = flag == INSERT_TRANSITION && | 6799 bool insert_transition = flag == INSERT_TRANSITION && |
6798 map->CanHaveMoreTransitions() && | 6800 map->CanHaveMoreTransitions() && |
6799 !map->HasElementsTransition(); | 6801 !map->HasElementsTransition(); |
6800 | 6802 |
6801 if (insert_transition && map->owns_descriptors()) { | 6803 if (insert_transition) { |
6802 // In case the map owned its own descriptors, share the descriptors and | 6804 Handle<Map> new_map = CopyForTransition(map, "CopyAsElementsKind"); |
6803 // transfer ownership to the new map. | 6805 new_map->set_elements_kind(kind); |
6804 Handle<Map> new_map = CopyDropDescriptors(map); | |
6805 | 6806 |
6806 ConnectElementsTransition(map, new_map); | 6807 ConnectElementsTransition(map, new_map); |
6807 | 6808 |
6808 new_map->set_elements_kind(kind); | |
6809 // The properties did not change, so reuse descriptors. | |
6810 new_map->InitializeDescriptors(map->instance_descriptors(), | |
6811 map->GetLayoutDescriptor()); | |
6812 return new_map; | 6809 return new_map; |
6813 } | 6810 } |
6814 | 6811 |
6815 // In case the map did not own its own descriptors, a split is forced by | |
6816 // copying the map; creating a new descriptor array cell. | |
6817 // Create a new free-floating map only if we are not allowed to store it. | 6812 // Create a new free-floating map only if we are not allowed to store it. |
6818 Handle<Map> new_map = Copy(map, "CopyAsElementsKind"); | 6813 Handle<Map> new_map = Copy(map, "CopyAsElementsKind"); |
6819 | |
6820 new_map->set_elements_kind(kind); | 6814 new_map->set_elements_kind(kind); |
6821 | |
6822 if (insert_transition) { | |
6823 ConnectElementsTransition(map, new_map); | |
6824 } | |
6825 | |
6826 return new_map; | 6815 return new_map; |
6827 } | 6816 } |
6828 | 6817 |
6829 | 6818 |
6830 Handle<Map> Map::CopyForObserved(Handle<Map> map) { | 6819 Handle<Map> Map::CopyForObserved(Handle<Map> map) { |
6831 DCHECK(!map->is_observed()); | 6820 DCHECK(!map->is_observed()); |
6832 | 6821 |
6833 Isolate* isolate = map->GetIsolate(); | 6822 Isolate* isolate = map->GetIsolate(); |
6834 | 6823 |
6835 // In case the map owned its own descriptors, share the descriptors and | 6824 bool insert_transition = |
6836 // transfer ownership to the new map. | 6825 map->CanHaveMoreTransitions() && !map->is_prototype_map(); |
6837 Handle<Map> new_map; | 6826 |
6838 if (map->owns_descriptors()) { | 6827 if (insert_transition) { |
6839 new_map = CopyDropDescriptors(map); | 6828 Handle<Map> new_map = CopyForTransition(map, "CopyForObserved"); |
6840 } else { | 6829 new_map->set_is_observed(); |
6841 DCHECK(!map->is_prototype_map()); | 6830 |
6842 new_map = Copy(map, "CopyForObserved"); | 6831 Handle<Name> name = isolate->factory()->observed_symbol(); |
| 6832 ConnectTransition(map, new_map, name, SPECIAL_TRANSITION); |
| 6833 return new_map; |
6843 } | 6834 } |
6844 | 6835 |
| 6836 // Create a new free-floating map only if we are not allowed to store it. |
| 6837 Handle<Map> new_map = Map::Copy(map, "CopyForObserved"); |
6845 new_map->set_is_observed(); | 6838 new_map->set_is_observed(); |
| 6839 return new_map; |
| 6840 } |
| 6841 |
| 6842 |
| 6843 Handle<Map> Map::CopyForTransition(Handle<Map> map, const char* reason) { |
| 6844 DCHECK(!map->is_prototype_map()); |
| 6845 Handle<Map> new_map = CopyDropDescriptors(map); |
| 6846 |
6846 if (map->owns_descriptors()) { | 6847 if (map->owns_descriptors()) { |
| 6848 // In case the map owned its own descriptors, share the descriptors and |
| 6849 // transfer ownership to the new map. |
6847 // The properties did not change, so reuse descriptors. | 6850 // The properties did not change, so reuse descriptors. |
6848 new_map->InitializeDescriptors(map->instance_descriptors(), | 6851 new_map->InitializeDescriptors(map->instance_descriptors(), |
6849 map->GetLayoutDescriptor()); | 6852 map->GetLayoutDescriptor()); |
| 6853 } else { |
| 6854 // In case the map did not own its own descriptors, a split is forced by |
| 6855 // copying the map; creating a new descriptor array cell. |
| 6856 Handle<DescriptorArray> descriptors(map->instance_descriptors()); |
| 6857 int number_of_own_descriptors = map->NumberOfOwnDescriptors(); |
| 6858 Handle<DescriptorArray> new_descriptors = |
| 6859 DescriptorArray::CopyUpTo(descriptors, number_of_own_descriptors); |
| 6860 Handle<LayoutDescriptor> new_layout_descriptor(map->GetLayoutDescriptor(), |
| 6861 map->GetIsolate()); |
| 6862 new_map->InitializeDescriptors(*new_descriptors, *new_layout_descriptor); |
6850 } | 6863 } |
6851 | 6864 |
6852 if (map->CanHaveMoreTransitions()) { | 6865 #if TRACE_MAPS |
6853 Handle<Name> name = isolate->factory()->observed_symbol(); | 6866 if (FLAG_trace_maps) { |
6854 ConnectTransition(map, new_map, name, SPECIAL_TRANSITION); | 6867 PrintF("[TraceMaps: CopyForTransition from= %p to= %p reason= %s ]\n", |
| 6868 reinterpret_cast<void*>(*map), reinterpret_cast<void*>(*new_map), |
| 6869 reason); |
6855 } | 6870 } |
| 6871 #endif |
| 6872 |
6856 return new_map; | 6873 return new_map; |
6857 } | 6874 } |
6858 | 6875 |
6859 | 6876 |
6860 Handle<Map> Map::Copy(Handle<Map> map, const char* reason) { | 6877 Handle<Map> Map::Copy(Handle<Map> map, const char* reason) { |
6861 Handle<DescriptorArray> descriptors(map->instance_descriptors()); | 6878 Handle<DescriptorArray> descriptors(map->instance_descriptors()); |
6862 int number_of_own_descriptors = map->NumberOfOwnDescriptors(); | 6879 int number_of_own_descriptors = map->NumberOfOwnDescriptors(); |
6863 Handle<DescriptorArray> new_descriptors = | 6880 Handle<DescriptorArray> new_descriptors = |
6864 DescriptorArray::CopyUpTo(descriptors, number_of_own_descriptors); | 6881 DescriptorArray::CopyUpTo(descriptors, number_of_own_descriptors); |
6865 Handle<LayoutDescriptor> new_layout_descriptor(map->GetLayoutDescriptor(), | 6882 Handle<LayoutDescriptor> new_layout_descriptor(map->GetLayoutDescriptor(), |
(...skipping 9967 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16833 Handle<DependentCode> codes = | 16850 Handle<DependentCode> codes = |
16834 DependentCode::Insert(handle(cell->dependent_code(), info->isolate()), | 16851 DependentCode::Insert(handle(cell->dependent_code(), info->isolate()), |
16835 DependentCode::kPropertyCellChangedGroup, | 16852 DependentCode::kPropertyCellChangedGroup, |
16836 info->object_wrapper()); | 16853 info->object_wrapper()); |
16837 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); | 16854 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); |
16838 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( | 16855 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( |
16839 cell, info->zone()); | 16856 cell, info->zone()); |
16840 } | 16857 } |
16841 | 16858 |
16842 } } // namespace v8::internal | 16859 } } // namespace v8::internal |
OLD | NEW |