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

Unified Diff: src/ic.cc

Issue 75413002: Convert PatchCache (and related methods) to use types rather than objects/maps. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed comment Created 7 years, 1 month 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') | src/ic-inl.h » ('j') | 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 2f225323404f23b9471b6e7df1fdbff936e18559..9b304057ade037d471539297de6c3c4762d9bc73 100644
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -783,7 +783,7 @@ void CallICBase::UpdateCaches(LookupResult* lookup,
: Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate())),
isolate());
- PatchCache(cache_object, name, code);
+ PatchCache(handle(Type::CurrentOf(cache_object), isolate()), name, code);
TRACE_IC("CallIC", name);
}
@@ -967,79 +967,94 @@ static bool AddOneReceiverMapIfMissing(MapHandleList* receiver_maps,
}
-bool IC::UpdatePolymorphicIC(Handle<Object> receiver,
+bool IC::UpdatePolymorphicIC(Handle<Type> type,
Handle<String> name,
Handle<Code> code) {
if (!code->is_handler()) return false;
- MapHandleList receiver_maps;
+ TypeHandleList types;
CodeHandleList handlers;
- int number_of_valid_maps;
+ int number_of_valid_types;
int handler_to_overwrite = -1;
- Handle<Map> new_receiver_map(receiver->GetMarkerMap(isolate()));
-
- target()->FindAllMaps(&receiver_maps);
- int number_of_maps = receiver_maps.length();
- number_of_valid_maps = number_of_maps;
-
- for (int i = 0; i < number_of_maps; i++) {
- Handle<Map> map = receiver_maps.at(i);
- // Filter out deprecated maps to ensure its instances get migrated.
- if (map->is_deprecated()) {
- number_of_valid_maps--;
- // If the receiver map is already in the polymorphic IC, this indicates
+
+ 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<Type> 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.
- } else if (map.is_identical_to(new_receiver_map)) {
- number_of_valid_maps--;
+ } else if (type->Is(current_type)) {
+ ASSERT(handler_to_overwrite == -1);
+ number_of_valid_types--;
handler_to_overwrite = i;
}
}
- if (number_of_valid_maps >= 4) return false;
- if (number_of_maps == 0) return false;
+ if (number_of_valid_types >= 4) return false;
+ if (number_of_types == 0) return false;
+ if (!target()->FindHandlers(&handlers, types.length())) return false;
- if (!target()->FindHandlers(&handlers, receiver_maps.length())) {
- return false;
- }
-
- number_of_valid_maps++;
+ number_of_valid_types++;
if (handler_to_overwrite >= 0) {
handlers.Set(handler_to_overwrite, code);
} else {
- receiver_maps.Add(new_receiver_map);
+ types.Add(type);
handlers.Add(code);
}
Handle<Code> ic = isolate()->stub_cache()->ComputePolymorphicIC(
- &receiver_maps, &handlers, number_of_valid_maps, name, strict_mode());
+ &types, &handlers, number_of_valid_types, name, strict_mode());
set_target(*ic);
return true;
}
-void IC::UpdateMonomorphicIC(Handle<Object> receiver,
+Handle<Map> IC::TypeToMap(Type* type, Isolate* isolate) {
+ if (type->Is(Type::Number())) return isolate->factory()->heap_number_map();
+ if (type->Is(Type::Boolean())) return isolate->factory()->oddball_map();
+ ASSERT(type->IsClass());
+ return type->AsClass();
+}
+
+
+Type* IC::MapToType(Handle<Map> map) {
+ if (map->instance_type() == HEAP_NUMBER_TYPE) return Type::Number();
+ // The only oddballs that can be recorded in ICs are booleans.
+ if (map->instance_type() == ODDBALL_TYPE) return Type::Boolean();
+ return Type::Class(map);
+}
+
+
+void IC::UpdateMonomorphicIC(Handle<Type> type,
Handle<Code> handler,
Handle<String> name) {
if (!handler->is_handler()) return set_target(*handler);
Handle<Code> ic = isolate()->stub_cache()->ComputeMonomorphicIC(
- name, receiver, handler, strict_mode());
+ name, type, handler, strict_mode());
set_target(*ic);
}
void IC::CopyICToMegamorphicCache(Handle<String> name) {
- MapHandleList receiver_maps;
+ TypeHandleList types;
CodeHandleList handlers;
- target()->FindAllMaps(&receiver_maps);
- if (!target()->FindHandlers(&handlers, receiver_maps.length())) return;
- for (int i = 0; i < receiver_maps.length(); i++) {
- UpdateMegamorphicCache(*receiver_maps.at(i), *name, *handlers.at(i));
+ 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::IsTransitionedMapOfMonomorphicTarget(Map* receiver_map) {
+bool IC::IsTransitionOfMonomorphicTarget(Type* 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 =
@@ -1053,14 +1068,14 @@ bool IC::IsTransitionedMapOfMonomorphicTarget(Map* receiver_map) {
}
-void IC::PatchCache(Handle<Object> object,
+void IC::PatchCache(Handle<Type> type,
Handle<String> name,
Handle<Code> code) {
switch (state()) {
case UNINITIALIZED:
case PREMONOMORPHIC:
case MONOMORPHIC_PROTOTYPE_FAILURE:
- UpdateMonomorphicIC(object, code, name);
+ UpdateMonomorphicIC(type, code, name);
break;
case MONOMORPHIC: {
// For now, call stubs are allowed to rewrite to the same stub. This
@@ -1069,23 +1084,21 @@ void IC::PatchCache(Handle<Object> object,
target()->is_keyed_call_stub() ||
!target().is_identical_to(code));
Code* old_handler = target()->FindFirstHandler();
- if (old_handler == *code &&
- IsTransitionedMapOfMonomorphicTarget(
- object->GetMarkerMap(isolate()))) {
- UpdateMonomorphicIC(object, code, name);
+ if (old_handler == *code && IsTransitionOfMonomorphicTarget(*type)) {
+ UpdateMonomorphicIC(type, code, name);
break;
}
// Fall through.
}
case POLYMORPHIC:
if (!target()->is_keyed_stub()) {
- if (UpdatePolymorphicIC(object, name, code)) break;
+ if (UpdatePolymorphicIC(type, name, code)) break;
CopyICToMegamorphicCache(name);
}
set_target(*megamorphic_stub());
// Fall through.
case MEGAMORPHIC:
- UpdateMegamorphicCache(object->GetMarkerMap(isolate()), *name, *code);
+ UpdateMegamorphicCache(*type, *name, *code);
break;
case DEBUG_STUB:
break;
@@ -1135,14 +1148,15 @@ void LoadIC::UpdateCaches(LookupResult* lookup,
code = ComputeHandler(lookup, object, name);
}
- PatchCache(object, name, code);
+ PatchCache(handle(Type::CurrentOf(object), isolate()), name, code);
TRACE_IC("LoadIC", name);
}
-void IC::UpdateMegamorphicCache(Map* map, Name* name, Code* code) {
+void IC::UpdateMegamorphicCache(Type* type, Name* name, Code* code) {
// Cache code holding map should be consistent with
// GenerateMonomorphicCacheProbe.
+ Map* map = *TypeToMap(type, isolate());
isolate()->stub_cache()->Set(name, map, code);
}
@@ -1598,7 +1612,7 @@ void StoreIC::UpdateCaches(LookupResult* lookup,
Handle<Code> code = ComputeHandler(lookup, receiver, name, value);
- PatchCache(receiver, name, code);
+ PatchCache(handle(Type::CurrentOf(receiver), isolate()), name, code);
TRACE_IC("StoreIC", name);
}
@@ -1744,7 +1758,7 @@ Handle<Code> KeyedStoreIC::StoreElementStub(Handle<JSObject> receiver,
transitioned_receiver_map =
ComputeTransitionedMap(receiver, store_mode);
}
- if (IsTransitionedMapOfMonomorphicTarget(*transitioned_receiver_map)) {
+ if (IsTransitionOfMonomorphicTarget(MapToType(transitioned_receiver_map))) {
// Element family is the same, use the "worst" case map.
store_mode = GetNonTransitioningStoreMode(store_mode);
return isolate()->stub_cache()->ComputeKeyedStoreElement(
« no previous file with comments | « src/ic.h ('k') | src/ic-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698