Commit 179b4b0c authored by ulan@chromium.org's avatar ulan@chromium.org

Unify monomorphic and polymorphic cases in IC::PatchCache.

BUG=
R=verwaest@chromium.org

Review URL: https://codereview.chromium.org/171683007

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20294 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent caad1de7
...@@ -624,28 +624,33 @@ bool IC::UpdatePolymorphicIC(Handle<HeapType> type, ...@@ -624,28 +624,33 @@ bool IC::UpdatePolymorphicIC(Handle<HeapType> type,
TypeHandleList types; TypeHandleList types;
CodeHandleList handlers; CodeHandleList handlers;
int number_of_valid_types;
int handler_to_overwrite = -1;
target()->FindAllTypes(&types); target()->FindAllTypes(&types);
int number_of_types = types.length(); 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++) { 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()) { if (current_type->IsClass() && current_type->AsClass()->is_deprecated()) {
number_of_valid_types--; // Filter out deprecated maps to ensure their instances get migrated.
// If the receiver type is already in the polymorphic IC, this indicates ++deprecated_types;
// there was a prototoype chain failure. In that case, just overwrite the
// handler.
} else if (type->IsCurrently(current_type)) { } else if (type->IsCurrently(current_type)) {
ASSERT(handler_to_overwrite == -1); // If the receiver type is already in the polymorphic IC, this indicates
number_of_valid_types--; // 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; 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_valid_types >= 4) return false;
if (number_of_types == 0) return false; if (number_of_types == 0) return false;
if (!target()->FindHandlers(&handlers, types.length())) return false; if (!target()->FindHandlers(&handlers, types.length())) return false;
...@@ -653,6 +658,9 @@ bool IC::UpdatePolymorphicIC(Handle<HeapType> type, ...@@ -653,6 +658,9 @@ bool IC::UpdatePolymorphicIC(Handle<HeapType> type,
number_of_valid_types++; number_of_valid_types++;
if (handler_to_overwrite >= 0) { if (handler_to_overwrite >= 0) {
handlers.Set(handler_to_overwrite, code); handlers.Set(handler_to_overwrite, code);
if (!type->IsCurrently(types.at(handler_to_overwrite))) {
types.Set(handler_to_overwrite, type);
}
} else { } else {
types.Add(type); types.Add(type);
handlers.Add(code); handlers.Add(code);
...@@ -727,19 +735,18 @@ void IC::CopyICToMegamorphicCache(Handle<String> name) { ...@@ -727,19 +735,18 @@ void IC::CopyICToMegamorphicCache(Handle<String> name) {
} }
bool IC::IsTransitionOfMonomorphicTarget(Handle<HeapType> type) { bool IC::IsTransitionOfMonomorphicTarget(Map* source_map, Map* target_map) {
if (!type->IsClass()) return false; if (source_map == NULL) return true;
Map* receiver_map = *type->AsClass(); if (target_map == NULL) return false;
Map* current_map = target()->FindFirstMap(); ElementsKind target_elements_kind = target_map->elements_kind();
ElementsKind receiver_elements_kind = receiver_map->elements_kind();
bool more_general_transition = bool more_general_transition =
IsMoreGeneralElementsKindTransition( IsMoreGeneralElementsKindTransition(
current_map->elements_kind(), receiver_elements_kind); source_map->elements_kind(), target_elements_kind);
Map* transitioned_map = more_general_transition Map* transitioned_map = more_general_transition
? current_map->LookupElementsTransitionMap(receiver_elements_kind) ? source_map->LookupElementsTransitionMap(target_elements_kind)
: NULL; : NULL;
return transitioned_map == receiver_map; return transitioned_map == target_map;
} }
...@@ -752,17 +759,7 @@ void IC::PatchCache(Handle<HeapType> type, ...@@ -752,17 +759,7 @@ void IC::PatchCache(Handle<HeapType> type,
case MONOMORPHIC_PROTOTYPE_FAILURE: case MONOMORPHIC_PROTOTYPE_FAILURE:
UpdateMonomorphicIC(type, code, name); UpdateMonomorphicIC(type, code, name);
break; break;
case MONOMORPHIC: { case MONOMORPHIC: // Fall through.
// 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 POLYMORPHIC: case POLYMORPHIC:
if (!target()->is_keyed_stub()) { if (!target()->is_keyed_stub()) {
if (UpdatePolymorphicIC(type, name, code)) break; if (UpdatePolymorphicIC(type, name, code)) break;
...@@ -1457,8 +1454,8 @@ Handle<Code> KeyedStoreIC::StoreElementStub(Handle<JSObject> receiver, ...@@ -1457,8 +1454,8 @@ Handle<Code> KeyedStoreIC::StoreElementStub(Handle<JSObject> receiver,
} }
if ((receiver_map.is_identical_to(previous_receiver_map) && if ((receiver_map.is_identical_to(previous_receiver_map) &&
IsTransitionStoreMode(store_mode)) || IsTransitionStoreMode(store_mode)) ||
IsTransitionOfMonomorphicTarget( IsTransitionOfMonomorphicTarget(*previous_receiver_map,
MapToType<HeapType>(transitioned_receiver_map, isolate()))) { *transitioned_receiver_map)) {
// If the "old" and "new" maps are in the same elements map family, or // 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, // if they at least come from the same origin for a transitioning store,
// stay MONOMORPHIC and use the map for the most generic ElementsKind. // stay MONOMORPHIC and use the map for the most generic ElementsKind.
......
...@@ -217,7 +217,7 @@ class IC { ...@@ -217,7 +217,7 @@ class IC {
virtual void UpdateMegamorphicCache(HeapType* type, Name* name, Code* code); virtual void UpdateMegamorphicCache(HeapType* type, Name* name, Code* code);
void CopyICToMegamorphicCache(Handle<String> name); void CopyICToMegamorphicCache(Handle<String> name);
bool IsTransitionOfMonomorphicTarget(Handle<HeapType> type); bool IsTransitionOfMonomorphicTarget(Map* source_map, Map* target_map);
void PatchCache(Handle<HeapType> type, void PatchCache(Handle<HeapType> type,
Handle<String> name, Handle<String> name,
Handle<Code> code); Handle<Code> code);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment