| 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 |