From 9f32d94cb3ca379d0c6a81e68eca83c60fee0228 Mon Sep 17 00:00:00 2001 From: "verwaest@chromium.org" Date: Tue, 21 May 2013 11:20:24 +0000 Subject: [PATCH] Don't create new maps in CurrentMapForDeprecated. R=yangguo@chromium.org Review URL: https://chromiumcodereview.appspot.com/15358005 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14728 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/ast.h | 4 +++- src/hydrogen.cc | 2 +- src/objects-inl.h | 6 ------ src/objects.cc | 30 +++++++++++++++++++++++++++++- src/objects.h | 5 ++--- src/type-info.cc | 51 +++++++++++++++++++++++++++------------------------ 6 files changed, 62 insertions(+), 36 deletions(-) diff --git a/src/ast.h b/src/ast.h index d697da7..ad7b119 100644 --- a/src/ast.h +++ b/src/ast.h @@ -278,7 +278,9 @@ class SmallMapList { int length() const { return list_.length(); } void AddMapIfMissing(Handle map, Zone* zone) { - map = Map::CurrentMapForDeprecated(map); + Map* updated = map->CurrentMapForDeprecated(); + if (updated == NULL) return; + map = Handle(updated); for (int i = 0; i < length(); ++i) { if (at(i).is_identical_to(map)) return; } diff --git a/src/hydrogen.cc b/src/hydrogen.cc index a97e083..328ec32 100644 --- a/src/hydrogen.cc +++ b/src/hydrogen.cc @@ -1832,7 +1832,7 @@ void HGraphBuilder::BuildCompareNil( } else { if_nil.Then(); if_nil.Else(); - if (types.Contains(CompareNilICStub::MONOMORPHIC_MAP)) { + if (!map.is_null() && types.Contains(CompareNilICStub::MONOMORPHIC_MAP)) { BuildCheckNonSmi(value); // For ICs, the map checked below is a sentinel map that gets replaced by // the monomorphic map when the code is used as a template to generate a diff --git a/src/objects-inl.h b/src/objects-inl.h index 8c6e925..c48876b 100644 --- a/src/objects-inl.h +++ b/src/objects-inl.h @@ -3624,12 +3624,6 @@ bool Map::CanBeDeprecated() { } -Handle Map::CurrentMapForDeprecated(Handle map) { - if (!map->is_deprecated()) return map; - return GeneralizeRepresentation(map, 0, Representation::Smi()); -} - - void Map::NotifyLeafMapLayoutChange() { dependent_code()->DeoptimizeDependentCodeGroup( GetIsolate(), diff --git a/src/objects.cc b/src/objects.cc index 16d38a6..1e586e8 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -2537,6 +2537,7 @@ MaybeObject* Map::GeneralizeRepresentation(int modify_index, int descriptors = old_map->NumberOfOwnDescriptors(); Map* root_map = old_map->FindRootMap(); + // Check the state of the root map. if (!old_map->EquivalentToForTransition(root_map)) { return CopyGeneralizeAllRepresentations(); } @@ -2547,7 +2548,6 @@ MaybeObject* Map::GeneralizeRepresentation(int modify_index, verbatim, descriptors, old_descriptors); if (updated == NULL) return CopyGeneralizeAllRepresentations(); - // Check the state of the root map. DescriptorArray* updated_descriptors = updated->instance_descriptors(); int valid = updated->NumberOfOwnDescriptors(); @@ -2624,6 +2624,34 @@ MaybeObject* Map::GeneralizeRepresentation(int modify_index, } +Map* Map::CurrentMapForDeprecated() { + AssertNoAllocation no_allocation; + if (!is_deprecated()) return this; + + DescriptorArray* old_descriptors = instance_descriptors(); + + int descriptors = NumberOfOwnDescriptors(); + Map* root_map = FindRootMap(); + + // Check the state of the root map. + if (!EquivalentToForTransition(root_map)) return NULL; + int verbatim = root_map->NumberOfOwnDescriptors(); + + Map* updated = root_map->FindUpdatedMap( + verbatim, descriptors, old_descriptors); + if (updated == NULL) return NULL; + + DescriptorArray* updated_descriptors = updated->instance_descriptors(); + int valid = updated->NumberOfOwnDescriptors(); + if (!updated_descriptors->IsMoreGeneralThan( + verbatim, valid, descriptors, old_descriptors)) { + return NULL; + } + + return updated; +} + + MaybeObject* JSObject::SetPropertyWithInterceptor( Name* name, Object* value, diff --git a/src/objects.h b/src/objects.h index d466f65..2c31f30 100644 --- a/src/objects.h +++ b/src/objects.h @@ -5377,9 +5377,8 @@ class Map: public HeapObject { // Returns a non-deprecated version of the input. If the input was not // deprecated, it is directly returned. Otherwise, the non-deprecated version // is found by re-transitioning from the root of the transition tree using the - // descriptor array of the map. New maps (and transitions) may be created if - // no new (more general) version exists. - static inline Handle CurrentMapForDeprecated(Handle map); + // descriptor array of the map. Returns NULL if no updated map is found. + Map* CurrentMapForDeprecated(); MUST_USE_RESULT MaybeObject* RawCopy(int instance_size); MUST_USE_RESULT MaybeObject* CopyWithPreallocatedFieldDescriptors(); diff --git a/src/type-info.cc b/src/type-info.cc index 21dcf74..53866c1 100644 --- a/src/type-info.cc +++ b/src/type-info.cc @@ -105,6 +105,8 @@ bool TypeFeedbackOracle::LoadIsMonomorphicNormal(Property* expr) { Code::ExtractTypeFromFlags(code->flags()) == Code::NORMAL; if (!preliminary_checks) return false; Map* map = code->FindFirstMap(); + if (map == NULL) return false; + map = map->CurrentMapForDeprecated(); return map != NULL && !CanRetainOtherContext(map, *native_context_); } return false; @@ -136,6 +138,8 @@ bool TypeFeedbackOracle::StoreIsMonomorphicNormal(TypeFeedbackId ast_id) { Code::ExtractTypeFromFlags(code->flags()) == Code::NORMAL; if (!preliminary_checks) return false; Map* map = code->FindFirstMap(); + if (map == NULL) return false; + map = map->CurrentMapForDeprecated(); return map != NULL && !CanRetainOtherContext(map, *native_context_); } return false; @@ -192,14 +196,12 @@ Handle TypeFeedbackOracle::LoadMonomorphicReceiverType(Property* expr) { Handle map_or_code = GetInfo(expr->PropertyFeedbackId()); if (map_or_code->IsCode()) { Handle code = Handle::cast(map_or_code); - Handle first_map(code->FindFirstMap()); - ASSERT(!first_map.is_null()); - first_map = Map::CurrentMapForDeprecated(first_map); - return CanRetainOtherContext(*first_map, *native_context_) + Map* map = code->FindFirstMap()->CurrentMapForDeprecated(); + return map == NULL || CanRetainOtherContext(map, *native_context_) ? Handle::null() - : first_map; + : Handle(map); } - return Map::CurrentMapForDeprecated(Handle::cast(map_or_code)); + return Handle::cast(map_or_code); } @@ -209,14 +211,12 @@ Handle TypeFeedbackOracle::StoreMonomorphicReceiverType( Handle map_or_code = GetInfo(ast_id); if (map_or_code->IsCode()) { Handle code = Handle::cast(map_or_code); - Handle first_map(code->FindFirstMap()); - ASSERT(!first_map.is_null()); - first_map = Map::CurrentMapForDeprecated(first_map); - return CanRetainOtherContext(*first_map, *native_context_) + Map* map = code->FindFirstMap()->CurrentMapForDeprecated(); + return map == NULL || CanRetainOtherContext(map, *native_context_) ? Handle::null() - : first_map; + : Handle(map); } - return Map::CurrentMapForDeprecated(Handle::cast(map_or_code)); + return Handle::cast(map_or_code); } @@ -224,10 +224,15 @@ Handle TypeFeedbackOracle::CompareNilMonomorphicReceiverType( TypeFeedbackId id) { Handle maybe_code = GetInfo(id); if (maybe_code->IsCode()) { - Map* first_map = Handle::cast(maybe_code)->FindFirstMap(); - if (first_map != NULL) { - return Map::CurrentMapForDeprecated(Handle(first_map)); - } + Map* map = Handle::cast(maybe_code)->FindFirstMap(); + if (map == NULL) return Handle(); + map = map->CurrentMapForDeprecated(); + return map == NULL || CanRetainOtherContext(map, *native_context_) + ? Handle() + : Handle(map); + } else if (maybe_code->IsMap()) { + ASSERT(!Handle::cast(maybe_code)->is_deprecated()); + return Handle::cast(maybe_code); } return Handle(); } @@ -351,8 +356,7 @@ ElementsKind TypeFeedbackOracle::GetCallNewElementsKind(CallNew* expr) { Handle TypeFeedbackOracle::GetObjectLiteralStoreMap( ObjectLiteral::Property* prop) { ASSERT(ObjectLiteralStoreIsMonomorphic(prop)); - return Map::CurrentMapForDeprecated( - Handle::cast(GetInfo(prop->key()->LiteralFeedbackId()))); + return Handle::cast(GetInfo(prop->key()->LiteralFeedbackId())); } @@ -431,12 +435,10 @@ Handle TypeFeedbackOracle::GetCompareMap(CompareOperation* expr) { if (state != CompareIC::KNOWN_OBJECT) { return Handle::null(); } - Handle first_map(code->FindFirstMap()); - ASSERT(!first_map.is_null()); - first_map = Map::CurrentMapForDeprecated(first_map); - return CanRetainOtherContext(*first_map, *native_context_) + Map* map = code->FindFirstMap()->CurrentMapForDeprecated(); + return map == NULL || CanRetainOtherContext(map, *native_context_) ? Handle::null() - : first_map; + : Handle(map); } @@ -723,7 +725,8 @@ void TypeFeedbackOracle::ProcessRelocInfos(ZoneList* infos) { SetInfo(ast_id, static_cast(target)); } else if (!CanRetainOtherContext(Map::cast(map), *native_context_)) { - SetInfo(ast_id, map); + Map* feedback = Map::cast(map)->CurrentMapForDeprecated(); + if (feedback != NULL) SetInfo(ast_id, feedback); } } } else { -- 2.7.4