Index: src/objects.cc |
diff --git a/src/objects.cc b/src/objects.cc |
index e709720e2504531e6b19ef17585ddc2d3a9c9594..99a2e3243fd6fbd33e7768023e279618f9c380c9 100644 |
--- a/src/objects.cc |
+++ b/src/objects.cc |
@@ -3320,19 +3320,21 @@ static Handle<Map> AddMissingElementsTransitions(Handle<Map> map, |
Handle<Map> current_map = map; |
ElementsKind kind = map->elements_kind(); |
- if (!map->is_prototype_map()) { |
+ TransitionFlag flag; |
+ if (map->is_prototype_map()) { |
+ flag = OMIT_TRANSITION; |
+ } else { |
+ flag = INSERT_TRANSITION; |
while (kind != to_kind && !IsTerminalElementsKind(kind)) { |
kind = GetNextTransitionElementsKind(kind); |
- current_map = |
- Map::CopyAsElementsKind(current_map, kind, INSERT_TRANSITION); |
+ current_map = Map::CopyAsElementsKind(current_map, kind, flag); |
} |
} |
// In case we are exiting the fast elements kind system, just add the map in |
// the end. |
if (kind != to_kind) { |
- current_map = Map::CopyAsElementsKind( |
- current_map, to_kind, INSERT_TRANSITION); |
+ current_map = Map::CopyAsElementsKind(current_map, to_kind, flag); |
} |
DCHECK(current_map->elements_kind() == to_kind); |
@@ -6798,31 +6800,18 @@ Handle<Map> Map::CopyAsElementsKind(Handle<Map> map, ElementsKind kind, |
map->CanHaveMoreTransitions() && |
!map->HasElementsTransition(); |
- if (insert_transition && map->owns_descriptors()) { |
- // In case the map owned its own descriptors, share the descriptors and |
- // transfer ownership to the new map. |
- Handle<Map> new_map = CopyDropDescriptors(map); |
+ if (insert_transition) { |
+ Handle<Map> new_map = CopyForTransition(map, "CopyAsElementsKind"); |
+ new_map->set_elements_kind(kind); |
ConnectElementsTransition(map, new_map); |
- new_map->set_elements_kind(kind); |
- // The properties did not change, so reuse descriptors. |
- new_map->InitializeDescriptors(map->instance_descriptors(), |
- map->GetLayoutDescriptor()); |
return new_map; |
} |
- // In case the map did not own its own descriptors, a split is forced by |
- // copying the map; creating a new descriptor array cell. |
// Create a new free-floating map only if we are not allowed to store it. |
Handle<Map> new_map = Copy(map, "CopyAsElementsKind"); |
- |
new_map->set_elements_kind(kind); |
- |
- if (insert_transition) { |
- ConnectElementsTransition(map, new_map); |
- } |
- |
return new_map; |
} |
@@ -6832,27 +6821,55 @@ Handle<Map> Map::CopyForObserved(Handle<Map> map) { |
Isolate* isolate = map->GetIsolate(); |
- // In case the map owned its own descriptors, share the descriptors and |
- // transfer ownership to the new map. |
- Handle<Map> new_map; |
- if (map->owns_descriptors()) { |
- new_map = CopyDropDescriptors(map); |
- } else { |
- DCHECK(!map->is_prototype_map()); |
- new_map = Copy(map, "CopyForObserved"); |
+ bool insert_transition = |
+ map->CanHaveMoreTransitions() && !map->is_prototype_map(); |
+ |
+ if (insert_transition) { |
+ Handle<Map> new_map = CopyForTransition(map, "CopyForObserved"); |
+ new_map->set_is_observed(); |
+ |
+ Handle<Name> name = isolate->factory()->observed_symbol(); |
+ ConnectTransition(map, new_map, name, SPECIAL_TRANSITION); |
+ return new_map; |
} |
+ // Create a new free-floating map only if we are not allowed to store it. |
+ Handle<Map> new_map = Map::Copy(map, "CopyForObserved"); |
new_map->set_is_observed(); |
+ return new_map; |
+} |
+ |
+ |
+Handle<Map> Map::CopyForTransition(Handle<Map> map, const char* reason) { |
+ DCHECK(!map->is_prototype_map()); |
+ Handle<Map> new_map = CopyDropDescriptors(map); |
+ |
if (map->owns_descriptors()) { |
+ // In case the map owned its own descriptors, share the descriptors and |
+ // transfer ownership to the new map. |
// The properties did not change, so reuse descriptors. |
new_map->InitializeDescriptors(map->instance_descriptors(), |
map->GetLayoutDescriptor()); |
+ } else { |
+ // In case the map did not own its own descriptors, a split is forced by |
+ // copying the map; creating a new descriptor array cell. |
+ Handle<DescriptorArray> descriptors(map->instance_descriptors()); |
+ int number_of_own_descriptors = map->NumberOfOwnDescriptors(); |
+ Handle<DescriptorArray> new_descriptors = |
+ DescriptorArray::CopyUpTo(descriptors, number_of_own_descriptors); |
+ Handle<LayoutDescriptor> new_layout_descriptor(map->GetLayoutDescriptor(), |
+ map->GetIsolate()); |
+ new_map->InitializeDescriptors(*new_descriptors, *new_layout_descriptor); |
} |
- if (map->CanHaveMoreTransitions()) { |
- Handle<Name> name = isolate->factory()->observed_symbol(); |
- ConnectTransition(map, new_map, name, SPECIAL_TRANSITION); |
+#if TRACE_MAPS |
+ if (FLAG_trace_maps) { |
+ PrintF("[TraceMaps: CopyForTransition from= %p to= %p reason= %s ]\n", |
+ reinterpret_cast<void*>(*map), reinterpret_cast<void*>(*new_map), |
+ reason); |
} |
+#endif |
+ |
return new_map; |
} |