From 368782f06136882053c094068b5a33d8f3e97e28 Mon Sep 17 00:00:00 2001 From: "ulan@chromium.org" Date: Tue, 25 Feb 2014 10:52:15 +0000 Subject: [PATCH] Revert r19455 "Load target types and handlers before IC computation." It caused performance regression in dromaeo/jslib. BUG=346149 LOG=Y R=verwaest@chromium.org Review URL: https://codereview.chromium.org/179613002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@19537 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/ic.cc | 95 ++++++++++++++++++++++++++++++++++++--------------------------- src/ic.h | 18 +----------- 2 files changed, 56 insertions(+), 57 deletions(-) diff --git a/src/ic.cc b/src/ic.cc index 7c156e5..8ba0274 100644 --- a/src/ic.cc +++ b/src/ic.cc @@ -149,8 +149,6 @@ IC::IC(FrameDepth depth, Isolate* isolate) target_ = handle(raw_target(), isolate); state_ = target_->ic_state(); extra_ic_state_ = target_->extra_ic_state(); - target()->FindAllTypes(&types_); - target()->FindHandlers(&handlers_); } @@ -283,7 +281,7 @@ bool IC::TryRemoveInvalidPrototypeDependentStub(Handle receiver, // If the IC is shared between multiple receivers (slow dictionary mode), then // the map cannot be deprecated and the stub invalidated. if (cache_holder == OWN_MAP) { - Map* old_map = first_map(); + Map* old_map = target()->FindFirstMap(); if (old_map == *map) return true; if (old_map != NULL) { if (old_map->is_deprecated()) return true; @@ -308,8 +306,10 @@ bool IC::TryRemoveInvalidPrototypeDependentStub(Handle receiver, void IC::TryRemoveInvalidHandlers(Handle map, Handle name) { - for (int i = 0; i < handlers()->length(); i++) { - Handle handler = handlers()->at(i); + CodeHandleList handlers; + target()->FindHandlers(&handlers); + for (int i = 0; i < handlers.length(); i++) { + Handle handler = handlers.at(i); int index = map->IndexInCodeCache(*name, *handler); if (index >= 0) { map->RemoveFromCodeCache(*name, *handler, index); @@ -605,14 +605,18 @@ bool IC::UpdatePolymorphicIC(Handle type, Handle name, Handle code) { if (!code->is_handler()) return false; + TypeHandleList types; + CodeHandleList handlers; + int number_of_valid_types; int handler_to_overwrite = -1; - int number_of_types = types()->length(); + target()->FindAllTypes(&types); + int number_of_types = types.length(); number_of_valid_types = number_of_types; for (int i = 0; i < number_of_types; i++) { - Handle current_type = types()->at(i); + Handle current_type = types.at(i); // Filter out deprecated maps to ensure their instances get migrated. if (current_type->IsClass() && current_type->AsClass()->is_deprecated()) { number_of_valid_types--; @@ -628,19 +632,18 @@ bool IC::UpdatePolymorphicIC(Handle type, if (number_of_valid_types >= 4) return false; if (number_of_types == 0) return false; - if (handlers()->length() < types()->length()) return false; + if (!target()->FindHandlers(&handlers, types.length())) return false; number_of_valid_types++; if (handler_to_overwrite >= 0) { - handlers()->Set(handler_to_overwrite, code); + handlers.Set(handler_to_overwrite, code); } else { - types()->Add(type); - handlers()->Add(code); + types.Add(type); + handlers.Add(code); } Handle ic = isolate()->stub_cache()->ComputePolymorphicIC( - kind(), types(), handlers(), number_of_valid_types, - name, extra_ic_state()); + kind(), &types, &handlers, number_of_valid_types, name, extra_ic_state()); set_target(*ic); return true; } @@ -698,23 +701,29 @@ void IC::UpdateMonomorphicIC(Handle type, void IC::CopyICToMegamorphicCache(Handle name) { - if (handlers()->length() < types()->length()) return; - for (int i = 0; i < types()->length(); i++) { - UpdateMegamorphicCache(*types()->at(i), *name, *handlers()->at(i)); + TypeHandleList types; + CodeHandleList handlers; + target()->FindAllTypes(&types); + if (!target()->FindHandlers(&handlers, types.length())) return; + for (int i = 0; i < types.length(); i++) { + UpdateMegamorphicCache(*types.at(i), *name, *handlers.at(i)); } } -bool IC::IsTransitionOfMonomorphicTarget(Map* source_map, Map* target_map) { - if (source_map == NULL) return true; - if (target_map == NULL) return false; - ElementsKind target_elements_kind = target_map->elements_kind(); - bool more_general_transition = IsMoreGeneralElementsKindTransition( - source_map->elements_kind(), target_elements_kind); +bool IC::IsTransitionOfMonomorphicTarget(Handle type) { + if (!type->IsClass()) return false; + Map* receiver_map = *type->AsClass(); + Map* current_map = target()->FindFirstMap(); + ElementsKind receiver_elements_kind = receiver_map->elements_kind(); + bool more_general_transition = + IsMoreGeneralElementsKindTransition( + current_map->elements_kind(), receiver_elements_kind); Map* transitioned_map = more_general_transition - ? source_map->LookupElementsTransitionMap(target_elements_kind) + ? current_map->LookupElementsTransitionMap(receiver_elements_kind) : NULL; - return transitioned_map == target_map; + + return transitioned_map == receiver_map; } @@ -731,11 +740,8 @@ void IC::PatchCache(Handle type, // For now, call stubs are allowed to rewrite to the same stub. This // happens e.g., when the field does not contain a function. ASSERT(!target().is_identical_to(code)); - Map* old_map = first_map(); - Code* old_handler = first_handler(); - Map* map = type->IsClass() ? *type->AsClass() : NULL; - if (old_handler == *code && - IsTransitionOfMonomorphicTarget(old_map, map)) { + Code* old_handler = target()->FindFirstHandler(); + if (old_handler == *code && IsTransitionOfMonomorphicTarget(type)) { UpdateMonomorphicIC(type, code, name); break; } @@ -1007,7 +1013,7 @@ Handle KeyedLoadIC::LoadElementStub(Handle receiver) { if (target().is_identical_to(string_stub())) { target_receiver_maps.Add(isolate()->factory()->string_map()); } else { - GetMapsFromTypes(&target_receiver_maps); + target()->FindAllMaps(&target_receiver_maps); if (target_receiver_maps.length() == 0) { return isolate()->stub_cache()->ComputeKeyedLoadElement(receiver_map); } @@ -1411,25 +1417,37 @@ Handle KeyedStoreIC::StoreElementStub(Handle receiver, monomorphic_map, strict_mode(), store_mode); } + MapHandleList target_receiver_maps; + target()->FindAllMaps(&target_receiver_maps); + if (target_receiver_maps.length() == 0) { + // In the case that there is a non-map-specific IC is installed (e.g. keyed + // stores into properties in dictionary mode), then there will be not + // receiver maps in the target. + return generic_stub(); + } + // There are several special cases where an IC that is MONOMORPHIC can still // transition to a different GetNonTransitioningStoreMode IC that handles a // superset of the original IC. Handle those here if the receiver map hasn't // changed or it has transitioned to a more general kind. KeyedAccessStoreMode old_store_mode = KeyedStoreIC::GetKeyedAccessStoreMode(target()->extra_ic_state()); + Handle previous_receiver_map = target_receiver_maps.at(0); if (state() == MONOMORPHIC) { // If the "old" and "new" maps are in the same elements map family, stay // MONOMORPHIC and use the map for the most generic ElementsKind. - Handle transitioned_map = receiver_map; + Handle transitioned_receiver_map = receiver_map; if (IsTransitionStoreMode(store_mode)) { - transitioned_map = ComputeTransitionedMap(receiver, store_mode); + transitioned_receiver_map = + ComputeTransitionedMap(receiver, store_mode); } - if (IsTransitionOfMonomorphicTarget(first_map(), *transitioned_map)) { + if (IsTransitionOfMonomorphicTarget( + MapToType(transitioned_receiver_map, isolate()))) { // Element family is the same, use the "worst" case map. store_mode = GetNonTransitioningStoreMode(store_mode); return isolate()->stub_cache()->ComputeKeyedStoreElement( - transitioned_map, strict_mode(), store_mode); - } else if (first_map() == receiver->map() && + transitioned_receiver_map, strict_mode(), store_mode); + } else if (*previous_receiver_map == receiver->map() && old_store_mode == STANDARD_STORE && (IsGrowStoreMode(store_mode) || store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS || @@ -1444,9 +1462,6 @@ Handle KeyedStoreIC::StoreElementStub(Handle receiver, ASSERT(state() != GENERIC); - MapHandleList target_receiver_maps; - GetMapsFromTypes(&target_receiver_maps); - bool map_added = AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map); @@ -2703,8 +2718,8 @@ MaybeObject* CompareNilIC::CompareNil(Handle object) { // Find or create the specialized stub to support the new set of types. Handle code; if (stub.IsMonomorphic()) { - Handle monomorphic_map(already_monomorphic && (first_map() != NULL) - ? first_map() + Handle monomorphic_map(already_monomorphic + ? target()->FindFirstMap() : HeapObject::cast(*object)->map()); code = isolate()->stub_cache()->ComputeCompareNil(monomorphic_map, stub); } else { diff --git a/src/ic.h b/src/ic.h index fce585f..213a481 100644 --- a/src/ic.h +++ b/src/ic.h @@ -150,19 +150,6 @@ class IC { // Get the call-site target; used for determining the state. Handle target() const { return target_; } - TypeHandleList* types() { return &types_; } - CodeHandleList* handlers() { return &handlers_; } - Map* first_map() { - return types_.length() == 0 ? NULL : *TypeToMap(*types_.at(0), isolate_); - } - Code* first_handler() { - return handlers_.length() == 0 ? NULL : *handlers_.at(0); - } - void GetMapsFromTypes(MapHandleList* maps) { - for (int i = 0; i < types_.length(); ++i) { - maps->Add(TypeToMap(*types_.at(i), isolate_)); - } - } Address fp() const { return fp_; } Address pc() const { return *pc_address_; } Isolate* isolate() const { return isolate_; } @@ -222,7 +209,7 @@ class IC { virtual void UpdateMegamorphicCache(HeapType* type, Name* name, Code* code); void CopyICToMegamorphicCache(Handle name); - bool IsTransitionOfMonomorphicTarget(Map* source_map, Map* target_map); + bool IsTransitionOfMonomorphicTarget(Handle type); void PatchCache(Handle type, Handle name, Handle code); @@ -273,9 +260,6 @@ class IC { ExtraICState extra_ic_state_; - TypeHandleList types_; - CodeHandleList handlers_; - DISALLOW_IMPLICIT_CONSTRUCTORS(IC); }; -- 2.7.4