From: verwaest@chromium.org Date: Mon, 4 Aug 2014 15:12:01 +0000 (+0000) Subject: Don't insert transitions between maps for prototypes. X-Git-Tag: upstream/4.7.83~7871 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=fafa02ea526d38bfc174cefda5ca0f30a27be873;p=platform%2Fupstream%2Fv8.git Don't insert transitions between maps for prototypes. BUG= R=ishell@chromium.org Review URL: https://codereview.chromium.org/437953004 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@22828 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/objects.cc b/src/objects.cc index 592955d..c1f6114 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -2074,15 +2074,10 @@ bool Map::InstancesNeedRewriting(Map* target, int target_number_of_fields, } -Handle Map::SetElementsTransitionMap( - Handle map, Handle transitioned_map) { - Handle transitions = TransitionArray::CopyInsert( - map, - map->GetIsolate()->factory()->elements_transition_symbol(), - transitioned_map, - FULL_TRANSITION); - map->set_transitions(*transitions); - return transitions; +void Map::ConnectElementsTransition(Handle parent, Handle child) { + Isolate* isolate = parent->GetIsolate(); + Handle name = isolate->factory()->elements_transition_symbol(); + ConnectTransition(parent, child, name, FULL_TRANSITION); } @@ -2090,7 +2085,17 @@ void JSObject::MigrateToMap(Handle object, Handle new_map) { if (object->map() == *new_map) return; if (object->HasFastProperties()) { if (!new_map->is_dictionary_map()) { + Handle old_map(object->map()); MigrateFastToFast(object, new_map); + if (old_map->is_prototype_map()) { + // Clear out the old descriptor array to avoid problems to sharing + // the descriptor array without using an explicit. + old_map->InitializeDescriptors( + old_map->GetHeap()->empty_descriptor_array()); + // Ensure that no transition was inserted for prototype migrations. + DCHECK(!old_map->HasTransitionArray()); + DCHECK(new_map->GetBackPointer()->IsUndefined()); + } } else { MigrateFastToSlow(object, new_map, 0); } @@ -3459,10 +3464,12 @@ static Handle AddMissingElementsTransitions(Handle map, Handle current_map = map; ElementsKind kind = map->elements_kind(); - while (kind != to_kind && !IsTerminalElementsKind(kind)) { - kind = GetNextTransitionElementsKind(kind); - current_map = Map::CopyAsElementsKind( - current_map, kind, INSERT_TRANSITION); + if (!map->is_prototype_map()) { + while (kind != to_kind && !IsTerminalElementsKind(kind)) { + kind = GetNextTransitionElementsKind(kind); + current_map = + Map::CopyAsElementsKind(current_map, kind, INSERT_TRANSITION); + } } // In case we are exiting the fast elements kind system, just add the map in @@ -7110,8 +7117,6 @@ Handle Map::ShareDescriptor(Handle map, Handle result = CopyDropDescriptors(map); Handle name = descriptor->GetKey(); - Handle transitions = - TransitionArray::CopyInsert(map, name, result, SIMPLE_TRANSITION); // Ensure there's space for the new descriptor in the shared descriptor array. if (descriptors->NumberOfSlackDescriptors() == 0) { @@ -7124,22 +7129,33 @@ Handle Map::ShareDescriptor(Handle map, } } - // Commit the state atomically. - DisallowHeapAllocation no_gc; - - descriptors->Append(descriptor); - result->SetBackPointer(*map); - result->InitializeDescriptors(*descriptors); + { + DisallowHeapAllocation no_gc; + descriptors->Append(descriptor); + result->InitializeDescriptors(*descriptors); + } DCHECK(result->NumberOfOwnDescriptors() == map->NumberOfOwnDescriptors() + 1); - - map->set_transitions(*transitions); - map->set_owns_descriptors(false); + ConnectTransition(map, result, name, SIMPLE_TRANSITION); return result; } +void Map::ConnectTransition(Handle parent, Handle child, + Handle name, SimpleTransitionFlag flag) { + parent->set_owns_descriptors(false); + if (parent->is_prototype_map()) { + DCHECK(child->is_prototype_map()); + } else { + Handle transitions = + TransitionArray::CopyInsert(parent, name, child, flag); + parent->set_transitions(*transitions); + child->SetBackPointer(*parent); + } +} + + Handle Map::CopyReplaceDescriptors(Handle map, Handle descriptors, TransitionFlag flag, @@ -7150,19 +7166,18 @@ Handle Map::CopyReplaceDescriptors(Handle map, Handle result = CopyDropDescriptors(map); result->InitializeDescriptors(*descriptors); - if (flag == INSERT_TRANSITION && map->CanHaveMoreTransitions()) { - Handle name; - CHECK(maybe_name.ToHandle(&name)); - Handle transitions = TransitionArray::CopyInsert( - map, name, result, simple_flag); - map->set_transitions(*transitions); - result->SetBackPointer(*map); - } else { - int length = descriptors->number_of_descriptors(); - for (int i = 0; i < length; i++) { - descriptors->SetRepresentation(i, Representation::Tagged()); - if (descriptors->GetDetails(i).type() == FIELD) { - descriptors->SetValue(i, HeapType::Any()); + if (!map->is_prototype_map()) { + if (flag == INSERT_TRANSITION && map->CanHaveMoreTransitions()) { + Handle name; + CHECK(maybe_name.ToHandle(&name)); + ConnectTransition(map, result, name, simple_flag); + } else { + int length = descriptors->number_of_descriptors(); + for (int i = 0; i < length; i++) { + descriptors->SetRepresentation(i, Representation::Tagged()); + if (descriptors->GetDetails(i).type() == FIELD) { + descriptors->SetValue(i, HeapType::Any()); + } } } } @@ -7192,14 +7207,9 @@ Handle Map::CopyInstallDescriptors(Handle map, } result->set_unused_property_fields(unused_property_fields); - result->set_owns_descriptors(false); Handle name = handle(descriptors->GetKey(new_descriptor)); - Handle transitions = TransitionArray::CopyInsert( - map, name, result, SIMPLE_TRANSITION); - - map->set_transitions(*transitions); - result->SetBackPointer(*map); + ConnectTransition(map, result, name, SIMPLE_TRANSITION); return result; } @@ -7228,12 +7238,10 @@ Handle Map::CopyAsElementsKind(Handle map, ElementsKind kind, // transfer ownership to the new map. Handle new_map = CopyDropDescriptors(map); - SetElementsTransitionMap(map, new_map); + ConnectElementsTransition(map, new_map); new_map->set_elements_kind(kind); new_map->InitializeDescriptors(map->instance_descriptors()); - new_map->SetBackPointer(*map); - map->set_owns_descriptors(false); return new_map; } @@ -7245,8 +7253,7 @@ Handle Map::CopyAsElementsKind(Handle map, ElementsKind kind, new_map->set_elements_kind(kind); if (insert_transition) { - SetElementsTransitionMap(map, new_map); - new_map->SetBackPointer(*map); + ConnectElementsTransition(map, new_map); } return new_map; @@ -7264,22 +7271,18 @@ Handle Map::CopyForObserved(Handle map) { if (map->owns_descriptors()) { new_map = CopyDropDescriptors(map); } else { + DCHECK(!map->is_prototype_map()); new_map = Copy(map); } - Handle transitions = TransitionArray::CopyInsert( - map, isolate->factory()->observed_symbol(), new_map, FULL_TRANSITION); - - map->set_transitions(*transitions); - new_map->set_is_observed(); - if (map->owns_descriptors()) { new_map->InitializeDescriptors(map->instance_descriptors()); - map->set_owns_descriptors(false); } - new_map->SetBackPointer(*map); + Handle name = isolate->factory()->observed_symbol(); + ConnectTransition(map, new_map, name, FULL_TRANSITION); + return new_map; } @@ -11923,7 +11926,9 @@ Handle Map::PutPrototypeTransition(Handle map, Handle target_map) { DCHECK(target_map->IsMap()); DCHECK(HeapObject::cast(*prototype)->map()->IsMap()); - // Don't cache prototype transition if this map is shared. + // Don't cache prototype transition if this map is either shared, or a map of + // a prototype. + if (map->is_prototype_map()) return map; if (map->is_shared() || !FLAG_cache_prototype_transitions) return map; const int step = kProtoTransitionElementsPerEntry; diff --git a/src/objects.h b/src/objects.h index a035c72..6c6cefe 100644 --- a/src/objects.h +++ b/src/objects.h @@ -6767,8 +6767,9 @@ class Map: public HeapObject { bool EquivalentToForNormalization(Map* other, PropertyNormalizationMode mode); private: - static Handle SetElementsTransitionMap( - Handle map, Handle transitioned_map); + static void ConnectElementsTransition(Handle parent, Handle child); + static void ConnectTransition(Handle parent, Handle child, + Handle name, SimpleTransitionFlag flag); bool EquivalentToForTransition(Map* other); static Handle RawCopy(Handle map, int instance_size);