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 <iomanip> | 5 #include <iomanip> |
6 #include <sstream> | 6 #include <sstream> |
7 | 7 |
8 #include "src/v8.h" | 8 #include "src/v8.h" |
9 | 9 |
10 #include "src/accessors.h" | 10 #include "src/accessors.h" |
(...skipping 1745 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1756 DCHECK(target_inobject < inobject_properties()); | 1756 DCHECK(target_inobject < inobject_properties()); |
1757 if (target_number_of_fields <= target_inobject) { | 1757 if (target_number_of_fields <= target_inobject) { |
1758 DCHECK(target_number_of_fields + target_unused == target_inobject); | 1758 DCHECK(target_number_of_fields + target_unused == target_inobject); |
1759 return false; | 1759 return false; |
1760 } | 1760 } |
1761 // Otherwise, properties will need to be moved to the backing store. | 1761 // Otherwise, properties will need to be moved to the backing store. |
1762 return true; | 1762 return true; |
1763 } | 1763 } |
1764 | 1764 |
1765 | 1765 |
1766 void Map::ConnectElementsTransition(Handle<Map> parent, Handle<Map> child) { | |
1767 Isolate* isolate = parent->GetIsolate(); | |
1768 Handle<Name> name = isolate->factory()->elements_transition_symbol(); | |
1769 ConnectTransition(parent, child, name, SPECIAL_TRANSITION); | |
1770 } | |
1771 | |
1772 | |
1773 void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map, | 1766 void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map, |
1774 int expected_additional_properties) { | 1767 int expected_additional_properties) { |
1775 if (object->map() == *new_map) return; | 1768 if (object->map() == *new_map) return; |
1776 // If this object is a prototype (the callee will check), invalidate any | 1769 // If this object is a prototype (the callee will check), invalidate any |
1777 // prototype chains involving it. | 1770 // prototype chains involving it. |
1778 InvalidatePrototypeChains(object->map()); | 1771 InvalidatePrototypeChains(object->map()); |
1779 Handle<Map> old_map(object->map()); | 1772 Handle<Map> old_map(object->map()); |
1780 | 1773 |
1781 // If the map was registered with its prototype before, ensure that it | 1774 // If the map was registered with its prototype before, ensure that it |
1782 // registers with its new prototype now. This preserves the invariant that | 1775 // registers with its new prototype now. This preserves the invariant that |
(...skipping 1936 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3719 DisallowHeapAllocation no_gc; | 3712 DisallowHeapAllocation no_gc; |
3720 FixedArray* array_maps = FixedArray::cast(maybe_array_maps); | 3713 FixedArray* array_maps = FixedArray::cast(maybe_array_maps); |
3721 if (array_maps->get(from_kind) == *map) { | 3714 if (array_maps->get(from_kind) == *map) { |
3722 Object* maybe_transitioned_map = array_maps->get(to_kind); | 3715 Object* maybe_transitioned_map = array_maps->get(to_kind); |
3723 if (maybe_transitioned_map->IsMap()) { | 3716 if (maybe_transitioned_map->IsMap()) { |
3724 return handle(Map::cast(maybe_transitioned_map)); | 3717 return handle(Map::cast(maybe_transitioned_map)); |
3725 } | 3718 } |
3726 } | 3719 } |
3727 } | 3720 } |
3728 | 3721 |
3729 return TransitionElementsToSlow(map, to_kind); | 3722 DCHECK(!map->IsUndefined()); |
3730 } | 3723 bool allow_store_transition = IsTransitionElementsKind(from_kind); |
3731 | |
3732 | |
3733 Handle<Map> Map::TransitionElementsToSlow(Handle<Map> map, | |
3734 ElementsKind to_kind) { | |
3735 ElementsKind from_kind = map->elements_kind(); | |
3736 | |
3737 if (from_kind == to_kind) { | |
3738 return map; | |
3739 } | |
3740 | |
3741 bool allow_store_transition = | |
3742 // Only remember the map transition if there is not an already existing | |
3743 // non-matching element transition. | |
3744 !map->IsUndefined() && !map->is_dictionary_map() && | |
3745 IsTransitionElementsKind(from_kind); | |
3746 | |
3747 // Only store fast element maps in ascending generality. | 3724 // Only store fast element maps in ascending generality. |
3748 if (IsFastElementsKind(to_kind)) { | 3725 if (IsFastElementsKind(to_kind)) { |
3749 allow_store_transition &= | 3726 allow_store_transition &= |
3750 IsTransitionableFastElementsKind(from_kind) && | 3727 IsTransitionableFastElementsKind(from_kind) && |
3751 IsMoreGeneralElementsKindTransition(from_kind, to_kind); | 3728 IsMoreGeneralElementsKindTransition(from_kind, to_kind); |
3752 } | 3729 } |
3753 | 3730 |
3754 if (!allow_store_transition) { | 3731 if (!allow_store_transition) { |
3755 return Map::CopyAsElementsKind(map, to_kind, OMIT_TRANSITION); | 3732 return Map::CopyAsElementsKind(map, to_kind, OMIT_TRANSITION); |
3756 } | 3733 } |
(...skipping 1835 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5592 } | 5569 } |
5593 | 5570 |
5594 Handle<Map> old_map(object->map(), isolate); | 5571 Handle<Map> old_map(object->map(), isolate); |
5595 Map* transition = | 5572 Map* transition = |
5596 TransitionArray::SearchSpecial(*old_map, *transition_marker); | 5573 TransitionArray::SearchSpecial(*old_map, *transition_marker); |
5597 if (transition != NULL) { | 5574 if (transition != NULL) { |
5598 Handle<Map> transition_map(transition, isolate); | 5575 Handle<Map> transition_map(transition, isolate); |
5599 DCHECK(transition_map->has_dictionary_elements()); | 5576 DCHECK(transition_map->has_dictionary_elements()); |
5600 DCHECK(!transition_map->is_extensible()); | 5577 DCHECK(!transition_map->is_extensible()); |
5601 JSObject::MigrateToMap(object, transition_map); | 5578 JSObject::MigrateToMap(object, transition_map); |
5602 } else if (object->HasFastProperties() && | 5579 } else if (TransitionArray::CanHaveMoreTransitions(old_map)) { |
5603 TransitionArray::CanHaveMoreTransitions(old_map)) { | |
5604 // Create a new descriptor array with the appropriate property attributes | 5580 // Create a new descriptor array with the appropriate property attributes |
5605 Handle<Map> new_map = Map::CopyForPreventExtensions( | 5581 Handle<Map> new_map = Map::CopyForPreventExtensions( |
5606 old_map, attrs, transition_marker, "CopyForPreventExtensions"); | 5582 old_map, attrs, transition_marker, "CopyForPreventExtensions"); |
5607 JSObject::MigrateToMap(object, new_map); | 5583 JSObject::MigrateToMap(object, new_map); |
5608 } else { | 5584 } else { |
5609 DCHECK(old_map->is_dictionary_map() || !old_map->is_prototype_map()); | 5585 DCHECK(old_map->is_dictionary_map() || !old_map->is_prototype_map()); |
5610 // Slow path: need to normalize properties for safety | 5586 // Slow path: need to normalize properties for safety |
5611 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0, | 5587 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0, |
5612 "SlowPreventExtensions"); | 5588 "SlowPreventExtensions"); |
5613 | 5589 |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5661 DCHECK(!object->IsJSGlobalObject()); | 5637 DCHECK(!object->IsJSGlobalObject()); |
5662 Isolate* isolate = object->GetIsolate(); | 5638 Isolate* isolate = object->GetIsolate(); |
5663 Handle<Map> new_map; | 5639 Handle<Map> new_map; |
5664 Handle<Map> old_map(object->map(), isolate); | 5640 Handle<Map> old_map(object->map(), isolate); |
5665 DCHECK(!old_map->is_observed()); | 5641 DCHECK(!old_map->is_observed()); |
5666 Map* transition = TransitionArray::SearchSpecial( | 5642 Map* transition = TransitionArray::SearchSpecial( |
5667 *old_map, isolate->heap()->observed_symbol()); | 5643 *old_map, isolate->heap()->observed_symbol()); |
5668 if (transition != NULL) { | 5644 if (transition != NULL) { |
5669 new_map = handle(transition, isolate); | 5645 new_map = handle(transition, isolate); |
5670 DCHECK(new_map->is_observed()); | 5646 DCHECK(new_map->is_observed()); |
5671 } else if (object->HasFastProperties() && | 5647 } else if (TransitionArray::CanHaveMoreTransitions(old_map)) { |
5672 TransitionArray::CanHaveMoreTransitions(old_map)) { | |
5673 new_map = Map::CopyForObserved(old_map); | 5648 new_map = Map::CopyForObserved(old_map); |
5674 } else { | 5649 } else { |
5675 new_map = Map::Copy(old_map, "SlowObserved"); | 5650 new_map = Map::Copy(old_map, "SlowObserved"); |
5676 new_map->set_is_observed(); | 5651 new_map->set_is_observed(); |
5677 } | 5652 } |
5678 JSObject::MigrateToMap(object, new_map); | 5653 JSObject::MigrateToMap(object, new_map); |
5679 } | 5654 } |
5680 | 5655 |
5681 | 5656 |
5682 Handle<Object> JSObject::FastPropertyAt(Handle<JSObject> object, | 5657 Handle<Object> JSObject::FastPropertyAt(Handle<JSObject> object, |
(...skipping 1273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6956 } | 6931 } |
6957 | 6932 |
6958 bool insert_transition = flag == INSERT_TRANSITION && | 6933 bool insert_transition = flag == INSERT_TRANSITION && |
6959 TransitionArray::CanHaveMoreTransitions(map) && | 6934 TransitionArray::CanHaveMoreTransitions(map) && |
6960 maybe_elements_transition_map == NULL; | 6935 maybe_elements_transition_map == NULL; |
6961 | 6936 |
6962 if (insert_transition) { | 6937 if (insert_transition) { |
6963 Handle<Map> new_map = CopyForTransition(map, "CopyAsElementsKind"); | 6938 Handle<Map> new_map = CopyForTransition(map, "CopyAsElementsKind"); |
6964 new_map->set_elements_kind(kind); | 6939 new_map->set_elements_kind(kind); |
6965 | 6940 |
6966 ConnectElementsTransition(map, new_map); | 6941 Isolate* isolate = map->GetIsolate(); |
6967 | 6942 Handle<Name> name = isolate->factory()->elements_transition_symbol(); |
| 6943 ConnectTransition(map, new_map, name, SPECIAL_TRANSITION); |
6968 return new_map; | 6944 return new_map; |
6969 } | 6945 } |
6970 | 6946 |
6971 // Create a new free-floating map only if we are not allowed to store it. | 6947 // Create a new free-floating map only if we are not allowed to store it. |
6972 Handle<Map> new_map = Copy(map, "CopyAsElementsKind"); | 6948 Handle<Map> new_map = Copy(map, "CopyAsElementsKind"); |
6973 new_map->set_elements_kind(kind); | 6949 new_map->set_elements_kind(kind); |
6974 return new_map; | 6950 return new_map; |
6975 } | 6951 } |
6976 | 6952 |
6977 | 6953 |
(...skipping 9383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16361 Handle<Object> new_value) { | 16337 Handle<Object> new_value) { |
16362 if (cell->value() != *new_value) { | 16338 if (cell->value() != *new_value) { |
16363 cell->set_value(*new_value); | 16339 cell->set_value(*new_value); |
16364 Isolate* isolate = cell->GetIsolate(); | 16340 Isolate* isolate = cell->GetIsolate(); |
16365 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 16341 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
16366 isolate, DependentCode::kPropertyCellChangedGroup); | 16342 isolate, DependentCode::kPropertyCellChangedGroup); |
16367 } | 16343 } |
16368 } | 16344 } |
16369 } // namespace internal | 16345 } // namespace internal |
16370 } // namespace v8 | 16346 } // namespace v8 |
OLD | NEW |