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

Unified Diff: src/ic.cc

Issue 25548009: Centralize handler caching and probing in ic.cc. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Undo moving fallback IC handling Created 7 years, 2 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') | src/objects.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 be362d2a4b90967be70fa4d46939123a37006be0..07ab99442c7209545efa7c2a080cca0732403291 100644
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -300,7 +300,8 @@ bool IC::TryRemoveInvalidPrototypeDependentStub(Handle<Object> receiver,
break;
}
- Map* map = IC::GetCodeCacheHolder(isolate(), *receiver, cache_holder)->map();
+ Handle<Map> map(
+ IC::GetCodeCacheHolder(isolate(), *receiver, cache_holder)->map());
// Decide whether the inline cache failed because of changes to the
// receiver itself or changes to one of its prototypes.
@@ -314,13 +315,7 @@ bool IC::TryRemoveInvalidPrototypeDependentStub(Handle<Object> receiver,
if (index >= 0) {
map->RemoveFromCodeCache(*name, *target(), index);
// Handlers are stored in addition to the ICs on the map. Remove those, too.
- Code* handler = target()->FindFirstHandler();
- if (handler != NULL) {
- index = map->IndexInCodeCache(*name, handler);
- if (index >= 0) {
- map->RemoveFromCodeCache(*name, handler, index);
- }
- }
+ TryRemoveInvalidHandlers(map, name);
return true;
}
@@ -334,7 +329,7 @@ bool IC::TryRemoveInvalidPrototypeDependentStub(Handle<Object> receiver,
// the map cannot be deprecated and the stub invalidated.
if (cache_holder == OWN_MAP) {
Map* old_map = target()->FindFirstMap();
- if (old_map == map) return true;
+ if (old_map == *map) return true;
if (old_map != NULL) {
if (old_map->is_deprecated()) return true;
if (IsMoreGeneralElementsKindTransition(old_map->elements_kind(),
@@ -357,8 +352,30 @@ bool IC::TryRemoveInvalidPrototypeDependentStub(Handle<Object> receiver,
}
+void IC::TryRemoveInvalidHandlers(Handle<Map> map, Handle<String> name) {
+ 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);
+ return;
+ }
+ }
+}
+
+
void IC::UpdateState(Handle<Object> receiver, Handle<Object> name) {
- if (state() != MONOMORPHIC || !name->IsString()) return;
+ if (!name->IsString()) return;
+ if (state() != MONOMORPHIC) {
+ if (state() == POLYMORPHIC && receiver->IsHeapObject()) {
+ TryRemoveInvalidHandlers(
+ handle(Handle<HeapObject>::cast(receiver)->map()),
+ Handle<String>::cast(name));
+ }
+ return;
+ }
if (receiver->IsUndefined() || receiver->IsNull()) return;
// Remove the target from the code cache if it became invalid
@@ -1122,7 +1139,6 @@ void LoadIC::UpdateCaches(LookupResult* lookup,
code = slow_stub();
} else {
code = ComputeLoadHandler(lookup, Handle<JSObject>::cast(receiver), name);
- if (code.is_null()) code = slow_stub();
}
PatchCache(receiver, name, code);
@@ -1141,11 +1157,29 @@ Handle<Code> LoadIC::ComputeLoadHandler(LookupResult* lookup,
Handle<JSObject> receiver,
Handle<String> name) {
if (!lookup->IsProperty()) {
- // Nonexistent property. The result is undefined.
- return isolate()->stub_cache()->ComputeLoadNonexistent(name, receiver);
+ return kind() == Code::LOAD_IC
+ ? isolate()->stub_cache()->ComputeLoadNonexistent(name, receiver)
+ : generic_stub();
}
- // Compute monomorphic stub.
+ Handle<Code> code = isolate()->stub_cache()->FindHandler(
+ name, receiver, kind());
+ if (!code.is_null()) return code;
+
+ code = CompileLoadHandler(lookup, receiver, name);
+ if (code.is_null()) return slow_stub();
+
+ if (code->is_handler() && code->type() != Code::NORMAL) {
+ HeapObject::UpdateMapCodeCache(receiver, name, code);
+ }
+
+ return code;
+}
+
+
+Handle<Code> LoadIC::CompileLoadHandler(LookupResult* lookup,
+ Handle<JSObject> receiver,
+ Handle<String> name) {
Handle<JSObject> holder(lookup->holder());
switch (lookup->type()) {
case FIELD:
@@ -1356,12 +1390,9 @@ MaybeObject* KeyedLoadIC::Load(Handle<Object> object,
}
-Handle<Code> KeyedLoadIC::ComputeLoadHandler(LookupResult* lookup,
+Handle<Code> KeyedLoadIC::CompileLoadHandler(LookupResult* lookup,
Handle<JSObject> receiver,
Handle<String> name) {
- // Bail out if we didn't find a result.
- if (!lookup->IsProperty()) return Handle<Code>::null();
-
// Compute a monomorphic stub.
Handle<JSObject> holder(lookup->holder(), isolate());
switch (lookup->type()) {
@@ -1603,10 +1634,6 @@ void StoreIC::UpdateCaches(LookupResult* lookup,
ASSERT(!lookup->IsHandler());
Handle<Code> code = ComputeStoreHandler(lookup, receiver, name, value);
- if (code.is_null()) {
- set_target(*generic_stub());
- return;
- }
PatchCache(receiver, name, code);
TRACE_IC("StoreIC", name);
@@ -1617,6 +1644,25 @@ Handle<Code> StoreIC::ComputeStoreHandler(LookupResult* lookup,
Handle<JSObject> receiver,
Handle<String> name,
Handle<Object> value) {
+ Handle<Code> code = isolate()->stub_cache()->FindHandler(
+ name, receiver, kind(), strict_mode());
+ if (!code.is_null()) return code;
+
+ code = CompileStoreHandler(lookup, receiver, name, value);
+ if (code.is_null()) return generic_stub();
+
+ if (code->is_handler() && code->type() != Code::NORMAL) {
+ HeapObject::UpdateMapCodeCache(receiver, name, code);
+ }
+
+ return code;
+}
+
+
+Handle<Code> StoreIC::CompileStoreHandler(LookupResult* lookup,
+ Handle<JSObject> receiver,
+ Handle<String> name,
+ Handle<Object> value) {
Handle<JSObject> holder(lookup->holder());
switch (lookup->type()) {
case FIELD:
@@ -2005,7 +2051,7 @@ MaybeObject* KeyedStoreIC::Store(Handle<Object> object,
}
-Handle<Code> KeyedStoreIC::ComputeStoreHandler(LookupResult* lookup,
+Handle<Code> KeyedStoreIC::CompileStoreHandler(LookupResult* lookup,
Handle<JSObject> receiver,
Handle<String> name,
Handle<Object> value) {
« no previous file with comments | « src/ic.h ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698