Revision: 19537
Author: [email protected]
Date: Tue Feb 25 10:52:15 2014 UTC
Log: Revert r19455 "Load target types and handlers before IC
computation."
It caused performance regression in dromaeo/jslib.
BUG=346149
LOG=Y
[email protected]
Review URL: https://codereview.chromium.org/179613002
http://code.google.com/p/v8/source/detail?r=19537
Modified:
/branches/bleeding_edge/src/ic.cc
/branches/bleeding_edge/src/ic.h
=======================================
--- /branches/bleeding_edge/src/ic.cc Thu Feb 20 21:55:45 2014 UTC
+++ /branches/bleeding_edge/src/ic.cc Tue Feb 25 10:52:15 2014 UTC
@@ -149,8 +149,6 @@
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 @@
// 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 @@
void IC::TryRemoveInvalidHandlers(Handle<Map> map, Handle<String> name) {
- for (int i = 0; i < handlers()->length(); i++) {
- Handle<Code> handler = handlers()->at(i);
+ CodeHandleList handlers;
+ target()->FindHandlers(&handlers);
+ for (int i = 0; i < handlers.length(); i++) {
+ Handle<Code> handler = handlers.at(i);
int index = map->IndexInCodeCache(*name, *handler);
if (index >= 0) {
map->RemoveFromCodeCache(*name, *handler, index);
@@ -605,14 +605,18 @@
Handle<String> name,
Handle<Code> 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<HeapType> current_type = types()->at(i);
+ Handle<HeapType> 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 @@
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<Code> 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::CopyICToMegamorphicCache(Handle<String> 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<HeapType> 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 @@
// 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 @@
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);
}
@@ -1410,6 +1416,15 @@
return isolate()->stub_cache()->ComputeKeyedStoreElement(
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
@@ -1417,19 +1432,22 @@
// changed or it has transitioned to a more general kind.
KeyedAccessStoreMode old_store_mode =
KeyedStoreIC::GetKeyedAccessStoreMode(target()->extra_ic_state());
+ Handle<Map> 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<Map> transitioned_map = receiver_map;
+ Handle<Map> 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<HeapType>(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 @@
ASSERT(state() != GENERIC);
- MapHandleList target_receiver_maps;
- GetMapsFromTypes(&target_receiver_maps);
-
bool map_added =
AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map);
@@ -2703,8 +2718,8 @@
// Find or create the specialized stub to support the new set of types.
Handle<Code> code;
if (stub.IsMonomorphic()) {
- Handle<Map> monomorphic_map(already_monomorphic && (first_map() !=
NULL)
- ? first_map()
+ Handle<Map> monomorphic_map(already_monomorphic
+ ? target()->FindFirstMap()
: HeapObject::cast(*object)->map());
code = isolate()->stub_cache()->ComputeCompareNil(monomorphic_map,
stub);
} else {
=======================================
--- /branches/bleeding_edge/src/ic.h Tue Feb 18 15:12:58 2014 UTC
+++ /branches/bleeding_edge/src/ic.h Tue Feb 25 10:52:15 2014 UTC
@@ -150,19 +150,6 @@
// Get the call-site target; used for determining the state.
Handle<Code> 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 @@
virtual void UpdateMegamorphicCache(HeapType* type, Name* name, Code*
code);
void CopyICToMegamorphicCache(Handle<String> name);
- bool IsTransitionOfMonomorphicTarget(Map* source_map, Map* target_map);
+ bool IsTransitionOfMonomorphicTarget(Handle<HeapType> type);
void PatchCache(Handle<HeapType> type,
Handle<String> name,
Handle<Code> code);
@@ -273,9 +260,6 @@
ExtraICState extra_ic_state_;
- TypeHandleList types_;
- CodeHandleList handlers_;
-
DISALLOW_IMPLICIT_CONSTRUCTORS(IC);
};
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.