Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(542)

Unified Diff: src/ic.cc

Issue 171683007: Unify monomorphic and polymorphic cases in IC::PatchCache. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebase and add IsTransitionOfMonomorphicTarget from r19537 Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/ic.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/ic.cc
diff --git a/src/ic.cc b/src/ic.cc
index da8afca789af9a974913c7192dfcd75f47e99b0d..a32717362965973cc961e9f4ba7ebfaa2b073f66 100644
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -624,28 +624,33 @@ bool IC::UpdatePolymorphicIC(Handle<HeapType> type,
TypeHandleList types;
CodeHandleList handlers;
- int number_of_valid_types;
- int handler_to_overwrite = -1;
-
target()->FindAllTypes(&types);
int number_of_types = types.length();
- number_of_valid_types = number_of_types;
+ int deprecated_types = 0;
+ int handler_to_overwrite = -1;
for (int i = 0; i < number_of_types; 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--;
- // If the receiver type is already in the polymorphic IC, this indicates
- // there was a prototoype chain failure. In that case, just overwrite the
- // handler.
+ // Filter out deprecated maps to ensure their instances get migrated.
+ ++deprecated_types;
} else if (type->IsCurrently(current_type)) {
- ASSERT(handler_to_overwrite == -1);
- number_of_valid_types--;
+ // If the receiver type is already in the polymorphic IC, this indicates
+ // there was a prototoype chain failure. In that case, just overwrite the
+ // handler.
+ handler_to_overwrite = i;
+ } else if (handler_to_overwrite == -1 &&
+ current_type->IsClass() &&
+ type->IsClass() &&
+ IsTransitionOfMonomorphicTarget(*current_type->AsClass(),
+ *type->AsClass())) {
handler_to_overwrite = i;
}
}
+ int number_of_valid_types =
+ number_of_types - deprecated_types - (handler_to_overwrite != -1);
+
if (number_of_valid_types >= 4) return false;
if (number_of_types == 0) return false;
if (!target()->FindHandlers(&handlers, types.length())) return false;
@@ -653,6 +658,9 @@ bool IC::UpdatePolymorphicIC(Handle<HeapType> type,
number_of_valid_types++;
if (handler_to_overwrite >= 0) {
handlers.Set(handler_to_overwrite, code);
+ if (!type->IsCurrently(types.at(handler_to_overwrite))) {
+ types.Set(handler_to_overwrite, type);
+ }
} else {
types.Add(type);
handlers.Add(code);
@@ -727,19 +735,18 @@ void IC::CopyICToMegamorphicCache(Handle<String> name) {
}
-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 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(
- current_map->elements_kind(), receiver_elements_kind);
+ source_map->elements_kind(), target_elements_kind);
Map* transitioned_map = more_general_transition
- ? current_map->LookupElementsTransitionMap(receiver_elements_kind)
+ ? source_map->LookupElementsTransitionMap(target_elements_kind)
: NULL;
- return transitioned_map == receiver_map;
+ return transitioned_map == target_map;
}
@@ -752,17 +759,7 @@ void IC::PatchCache(Handle<HeapType> type,
case MONOMORPHIC_PROTOTYPE_FAILURE:
UpdateMonomorphicIC(type, code, name);
break;
- case MONOMORPHIC: {
- // 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));
- Code* old_handler = target()->FindFirstHandler();
- if (old_handler == *code && IsTransitionOfMonomorphicTarget(type)) {
- UpdateMonomorphicIC(type, code, name);
- break;
- }
- // Fall through.
- }
+ case MONOMORPHIC: // Fall through.
case POLYMORPHIC:
if (!target()->is_keyed_stub()) {
if (UpdatePolymorphicIC(type, name, code)) break;
@@ -1457,8 +1454,8 @@ Handle<Code> KeyedStoreIC::StoreElementStub(Handle<JSObject> receiver,
}
if ((receiver_map.is_identical_to(previous_receiver_map) &&
IsTransitionStoreMode(store_mode)) ||
- IsTransitionOfMonomorphicTarget(
- MapToType<HeapType>(transitioned_receiver_map, isolate()))) {
+ IsTransitionOfMonomorphicTarget(*previous_receiver_map,
+ *transitioned_receiver_map)) {
// If the "old" and "new" maps are in the same elements map family, or
// if they at least come from the same origin for a transitioning store,
// stay MONOMORPHIC and use the map for the most generic ElementsKind.
« no previous file with comments | « src/ic.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698