Revision: 17161
Author: [email protected]
Date: Fri Oct 11 13:48:14 2013 UTC
Log: Centralize handler caching and probing in ic.cc.
Also purge invalid POLYMORPHIC stubs. In a next step the compilers should
probably be merged and the "Compute*" on the stub-cache removed.
BUG=
[email protected]
Review URL: https://chromiumcodereview.appspot.com/25548009
http://code.google.com/p/v8/source/detail?r=17161
Modified:
/branches/bleeding_edge/src/ic.cc
/branches/bleeding_edge/src/ic.h
/branches/bleeding_edge/src/objects.h
/branches/bleeding_edge/src/stub-cache.cc
/branches/bleeding_edge/src/stub-cache.h
=======================================
--- /branches/bleeding_edge/src/ic.cc Fri Oct 11 10:50:26 2013 UTC
+++ /branches/bleeding_edge/src/ic.cc Fri Oct 11 13:48:14 2013 UTC
@@ -300,7 +300,8 @@
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 @@
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 @@
// 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(),
@@ -355,10 +350,32 @@
return false;
}
+
+
+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 @@
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<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 @@
}
-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()) {
@@ -1613,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()) {
@@ -2002,7 +2052,7 @@
}
-Handle<Code> KeyedStoreIC::ComputeStoreHandler(LookupResult* lookup,
+Handle<Code> KeyedStoreIC::CompileStoreHandler(LookupResult* lookup,
Handle<JSObject> receiver,
Handle<String> name,
Handle<Object> value) {
=======================================
--- /branches/bleeding_edge/src/ic.h Fri Oct 11 10:50:26 2013 UTC
+++ /branches/bleeding_edge/src/ic.h Fri Oct 11 13:48:14 2013 UTC
@@ -198,6 +198,7 @@
virtual StrictModeFlag strict_mode() const { return kNonStrictMode; }
bool TryRemoveInvalidPrototypeDependentStub(Handle<Object> receiver,
Handle<String> name);
+ void TryRemoveInvalidHandlers(Handle<Map> map, Handle<String> name);
private:
// Frame pointer for the frame that uses (calls) the IC.
@@ -394,7 +395,10 @@
Handle<Object> object,
Handle<String> name);
- virtual Handle<Code> ComputeLoadHandler(LookupResult* lookup,
+ Handle<Code> ComputeLoadHandler(LookupResult* lookup,
+ Handle<JSObject> receiver,
+ Handle<String> name);
+ virtual Handle<Code> CompileLoadHandler(LookupResult* lookup,
Handle<JSObject> receiver,
Handle<String> name);
@@ -471,8 +475,7 @@
return isolate()->builtins()->KeyedLoadIC_Slow();
}
- // Update the inline cache.
- virtual Handle<Code> ComputeLoadHandler(LookupResult* lookup,
+ virtual Handle<Code> CompileLoadHandler(LookupResult* lookup,
Handle<JSObject> receiver,
Handle<String> name);
virtual void UpdateMegamorphicCache(Map* map, Name* name, Code* code) { }
@@ -590,7 +593,11 @@
// Compute the code stub for this store; used for rewriting to
// monomorphic state and making sure that the code stub is in the
// stub cache.
- virtual Handle<Code> ComputeStoreHandler(LookupResult* lookup,
+ Handle<Code> ComputeStoreHandler(LookupResult* lookup,
+ Handle<JSObject> receiver,
+ Handle<String> name,
+ Handle<Object> value);
+ virtual Handle<Code> CompileStoreHandler(LookupResult* lookup,
Handle<JSObject> receiver,
Handle<String> name,
Handle<Object> value);
@@ -661,7 +668,7 @@
protected:
virtual Code::Kind kind() const { return Code::KEYED_STORE_IC; }
- virtual Handle<Code> ComputeStoreHandler(LookupResult* lookup,
+ virtual Handle<Code> CompileStoreHandler(LookupResult* lookup,
Handle<JSObject> receiver,
Handle<String> name,
Handle<Object> value);
=======================================
--- /branches/bleeding_edge/src/objects.h Thu Oct 10 15:38:52 2013 UTC
+++ /branches/bleeding_edge/src/objects.h Fri Oct 11 13:48:14 2013 UTC
@@ -5073,7 +5073,7 @@
// Find |length| handlers and put them into |code_list|. Returns false
if not
// enough handlers can be found.
- MUST_USE_RESULT bool FindHandlers(CodeHandleList* code_list, int length);
+ bool FindHandlers(CodeHandleList* code_list, int length = -1);
// Find the first name in an IC stub.
Name* FindFirstName();
=======================================
--- /branches/bleeding_edge/src/stub-cache.cc Thu Oct 10 15:27:02 2013 UTC
+++ /branches/bleeding_edge/src/stub-cache.cc Fri Oct 11 13:48:14 2013 UTC
@@ -119,24 +119,15 @@
}
-Handle<Code> StubCache::FindLoadHandler(Handle<Name> name,
- Handle<JSObject> receiver,
- Code::Kind kind) {
- Code::Flags flags = Code::ComputeMonomorphicFlags(
- Code::HANDLER, Code::kNoExtraICState, Code::NORMAL, kind);
- Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags),
- isolate_);
- if (probe->IsCode()) return Handle<Code>::cast(probe);
- return Handle<Code>::null();
-}
-
-
-Handle<Code> StubCache::FindStoreHandler(Handle<Name> name,
- Handle<JSObject> receiver,
- Code::Kind kind,
- StrictModeFlag strict_mode) {
- Code::ExtraICState extra_ic_state = Code::ComputeExtraICState(
- STANDARD_STORE, strict_mode);
+Handle<Code> StubCache::FindHandler(Handle<Name> name,
+ Handle<JSObject> receiver,
+ Code::Kind kind,
+ StrictModeFlag strict_mode) {
+ Code::ExtraICState extra_ic_state = Code::kNoExtraICState;
+ if (kind == Code::STORE_IC || kind == Code::KEYED_STORE_IC) {
+ extra_ic_state = Code::ComputeExtraICState(
+ STANDARD_STORE, strict_mode);
+ }
Code::Flags flags = Code::ComputeMonomorphicFlags(
Code::HANDLER, extra_ic_state, Code::NORMAL, kind);
Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags),
@@ -200,7 +191,7 @@
// Compile the stub that is either shared for all names or
// name specific if there are global objects involved.
- Handle<Code> handler = FindLoadHandler(cache_name, receiver,
Code::LOAD_IC);
+ Handle<Code> handler = FindHandler(cache_name, receiver, Code::LOAD_IC);
if (!handler.is_null()) return handler;
LoadStubCompiler compiler(isolate_);
@@ -222,15 +213,10 @@
representation);
return stub.GetCode(isolate());
}
-
- Handle<Code> stub = FindLoadHandler(name, receiver, Code::LOAD_IC);
- if (!stub.is_null()) return stub;
LoadStubCompiler compiler(isolate_);
- Handle<Code> handler =
- compiler.CompileLoadField(receiver, holder, name, field,
representation);
- HeapObject::UpdateMapCodeCache(receiver, name, handler);
- return handler;
+ return compiler.CompileLoadField(
+ receiver, holder, name, field, representation);
}
@@ -240,14 +226,8 @@
Handle<JSObject> holder,
Handle<ExecutableAccessorInfo> callback) {
ASSERT(v8::ToCData<Address>(callback->getter()) != 0);
- Handle<Code> stub = FindLoadHandler(name, receiver, Code::LOAD_IC);
- if (!stub.is_null()) return stub;
-
LoadStubCompiler compiler(isolate_);
- Handle<Code> handler =
- compiler.CompileLoadCallback(receiver, holder, name, callback);
- HeapObject::UpdateMapCodeCache(receiver, name, handler);
- return handler;
+ return compiler.CompileLoadCallback(receiver, holder, name, callback);
}
@@ -256,14 +236,9 @@
Handle<JSObject> receiver,
Handle<JSObject> holder,
const CallOptimization& call_optimization) {
- Handle<Code> stub = FindLoadHandler(name, receiver, Code::LOAD_IC);
- if (!stub.is_null()) return stub;
-
LoadStubCompiler compiler(isolate_);
- Handle<Code> handler =
- compiler.CompileLoadCallback(receiver, holder, name,
call_optimization);
- HeapObject::UpdateMapCodeCache(receiver, name, handler);
- return handler;
+ return compiler.CompileLoadCallback(
+ receiver, holder, name, call_optimization);
}
@@ -271,14 +246,8 @@
Handle<JSObject> receiver,
Handle<JSObject> holder,
Handle<JSFunction> getter) {
- Handle<Code> stub = FindLoadHandler(name, receiver, Code::LOAD_IC);
- if (!stub.is_null()) return stub;
-
LoadStubCompiler compiler(isolate_);
- Handle<Code> handler =
- compiler.CompileLoadViaGetter(receiver, holder, name, getter);
- HeapObject::UpdateMapCodeCache(receiver, name, handler);
- return handler;
+ return compiler.CompileLoadViaGetter(receiver, holder, name, getter);
}
@@ -286,28 +255,16 @@
Handle<JSObject> receiver,
Handle<JSObject> holder,
Handle<Object> value) {
- Handle<Code> handler = FindLoadHandler(name, receiver, Code::LOAD_IC);
- if (!handler.is_null()) return handler;
-
LoadStubCompiler compiler(isolate_);
- handler = compiler.CompileLoadConstant(receiver, holder, name, value);
- HeapObject::UpdateMapCodeCache(receiver, name, handler);
-
- return handler;
+ return compiler.CompileLoadConstant(receiver, holder, name, value);
}
Handle<Code> StubCache::ComputeLoadInterceptor(Handle<Name> name,
Handle<JSObject> receiver,
Handle<JSObject> holder) {
- Handle<Code> stub = FindLoadHandler(name, receiver, Code::LOAD_IC);
- if (!stub.is_null()) return stub;
-
LoadStubCompiler compiler(isolate_);
- Handle<Code> handler =
- compiler.CompileLoadInterceptor(receiver, holder, name);
- HeapObject::UpdateMapCodeCache(receiver, name, handler);
- return handler;
+ return compiler.CompileLoadInterceptor(receiver, holder, name);
}
@@ -345,15 +302,10 @@
representation);
return stub.GetCode(isolate());
}
-
- Handle<Code> stub = FindLoadHandler(name, receiver, Code::KEYED_LOAD_IC);
- if (!stub.is_null()) return stub;
KeyedLoadStubCompiler compiler(isolate_);
- Handle<Code> handler =
- compiler.CompileLoadField(receiver, holder, name, field,
representation);
- HeapObject::UpdateMapCodeCache(receiver, name, handler);
- return handler;
+ return compiler.CompileLoadField(
+ receiver, holder, name, field, representation);
}
@@ -361,27 +313,17 @@
Handle<JSObject> receiver,
Handle<JSObject> holder,
Handle<Object> value) {
- Handle<Code> handler = FindLoadHandler(name, receiver,
Code::KEYED_LOAD_IC);
- if (!handler.is_null()) return handler;
-
KeyedLoadStubCompiler compiler(isolate_);
- handler = compiler.CompileLoadConstant(receiver, holder, name, value);
- HeapObject::UpdateMapCodeCache(receiver, name, handler);
- return handler;
+ return compiler.CompileLoadConstant(
+ receiver, holder, name, value);
}
Handle<Code> StubCache::ComputeKeyedLoadInterceptor(Handle<Name> name,
Handle<JSObject>
receiver,
Handle<JSObject>
holder) {
- Handle<Code> stub = FindLoadHandler(name, receiver, Code::KEYED_LOAD_IC);
- if (!stub.is_null()) return stub;
-
KeyedLoadStubCompiler compiler(isolate_);
- Handle<Code> handler =
- compiler.CompileLoadInterceptor(receiver, holder, name);
- HeapObject::UpdateMapCodeCache(receiver, name, handler);
- return handler;
+ return compiler.CompileLoadInterceptor(receiver, holder, name);
}
@@ -390,14 +332,8 @@
Handle<JSObject> receiver,
Handle<JSObject> holder,
Handle<ExecutableAccessorInfo> callback) {
- Handle<Code> stub = FindLoadHandler(name, receiver, Code::KEYED_LOAD_IC);
- if (!stub.is_null()) return stub;
-
KeyedLoadStubCompiler compiler(isolate_);
- Handle<Code> handler =
- compiler.CompileLoadCallback(receiver, holder, name, callback);
- HeapObject::UpdateMapCodeCache(receiver, name, handler);
- return handler;
+ return compiler.CompileLoadCallback(receiver, holder, name, callback);
}
@@ -406,14 +342,9 @@
Handle<JSObject> receiver,
Handle<JSObject> holder,
const CallOptimization& call_optimization) {
- Handle<Code> stub = FindLoadHandler(name, receiver, Code::KEYED_LOAD_IC);
- if (!stub.is_null()) return stub;
-
KeyedLoadStubCompiler compiler(isolate_);
- Handle<Code> handler =
- compiler.CompileLoadCallback(receiver, holder, name,
call_optimization);
- HeapObject::UpdateMapCodeCache(receiver, name, handler);
- return handler;
+ return compiler.CompileLoadCallback(
+ receiver, holder, name, call_optimization);
}
@@ -421,14 +352,8 @@
Handle<JSObject> receiver,
LookupResult* lookup,
StrictModeFlag strict_mode) {
- Handle<Code> stub = FindStoreHandler(
- name, receiver, Code::STORE_IC, strict_mode);
- if (!stub.is_null()) return stub;
-
StoreStubCompiler compiler(isolate_, strict_mode);
- Handle<Code> handler = compiler.CompileStoreField(receiver, lookup,
name);
- HeapObject::UpdateMapCodeCache(receiver, name, handler);
- return handler;
+ return compiler.CompileStoreField(receiver, lookup, name);
}
@@ -437,15 +362,8 @@
LookupResult* lookup,
Handle<Map> transition,
StrictModeFlag strict_mode)
{
- Handle<Code> stub = FindStoreHandler(
- name, receiver, Code::STORE_IC, strict_mode);
- if (!stub.is_null()) return stub;
-
StoreStubCompiler compiler(isolate_, strict_mode);
- Handle<Code> handler =
- compiler.CompileStoreTransition(receiver, lookup, transition, name);
- HeapObject::UpdateMapCodeCache(receiver, name, handler);
- return handler;
+ return compiler.CompileStoreTransition(receiver, lookup, transition,
name);
}
@@ -537,15 +455,8 @@
Handle<ExecutableAccessorInfo> callback,
StrictModeFlag strict_mode) {
ASSERT(v8::ToCData<Address>(callback->setter()) != 0);
- Handle<Code> stub = FindStoreHandler(
- name, receiver, Code::STORE_IC, strict_mode);
- if (!stub.is_null()) return stub;
-
StoreStubCompiler compiler(isolate_, strict_mode);
- Handle<Code> handler = compiler.CompileStoreCallback(
- receiver, holder, name, callback);
- HeapObject::UpdateMapCodeCache(receiver, name, handler);
- return handler;
+ return compiler.CompileStoreCallback(receiver, holder, name, callback);
}
@@ -555,15 +466,9 @@
Handle<JSObject> holder,
const CallOptimization& call_optimization,
StrictModeFlag strict_mode) {
- Handle<Code> stub = FindStoreHandler(
- name, receiver, Code::STORE_IC, strict_mode);
- if (!stub.is_null()) return stub;
-
StoreStubCompiler compiler(isolate_, strict_mode);
- Handle<Code> handler = compiler.CompileStoreCallback(
+ return compiler.CompileStoreCallback(
receiver, holder, name, call_optimization);
- HeapObject::UpdateMapCodeCache(receiver, name, handler);
- return handler;
}
@@ -572,29 +477,16 @@
Handle<JSObject> holder,
Handle<JSFunction> setter,
StrictModeFlag strict_mode) {
- Handle<Code> stub = FindStoreHandler(
- name, receiver, Code::STORE_IC, strict_mode);
- if (!stub.is_null()) return stub;
-
StoreStubCompiler compiler(isolate_, strict_mode);
- Handle<Code> handler = compiler.CompileStoreViaSetter(
- receiver, holder, name, setter);
- HeapObject::UpdateMapCodeCache(receiver, name, handler);
- return handler;
+ return compiler.CompileStoreViaSetter(receiver, holder, name, setter);
}
Handle<Code> StubCache::ComputeStoreInterceptor(Handle<Name> name,
Handle<JSObject> receiver,
StrictModeFlag
strict_mode) {
- Handle<Code> stub = FindStoreHandler(
- name, receiver, Code::STORE_IC, strict_mode);
- if (!stub.is_null()) return stub;
-
StoreStubCompiler compiler(isolate_, strict_mode);
- Handle<Code> handler = compiler.CompileStoreInterceptor(receiver, name);
- HeapObject::UpdateMapCodeCache(receiver, name, handler);
- return handler;
+ return compiler.CompileStoreInterceptor(receiver, name);
}
@@ -602,14 +494,8 @@
Handle<JSObject> receiver,
LookupResult* lookup,
StrictModeFlag strict_mode)
{
- Handle<Code> stub = FindStoreHandler(
- name, receiver, Code::KEYED_STORE_IC, strict_mode);
- if (!stub.is_null()) return stub;
-
KeyedStoreStubCompiler compiler(isolate(), strict_mode, STANDARD_STORE);
- Handle<Code> handler = compiler.CompileStoreField(receiver, lookup,
name);
- HeapObject::UpdateMapCodeCache(receiver, name, handler);
- return handler;
+ return compiler.CompileStoreField(receiver, lookup, name);
}
@@ -619,15 +505,8 @@
LookupResult* lookup,
Handle<Map> transition,
StrictModeFlag strict_mode) {
- Handle<Code> stub = FindStoreHandler(
- name, receiver, Code::KEYED_STORE_IC, strict_mode);
- if (!stub.is_null()) return stub;
-
KeyedStoreStubCompiler compiler(isolate(), strict_mode, STANDARD_STORE);
- Handle<Code> handler =
- compiler.CompileStoreTransition(receiver, lookup, transition, name);
- HeapObject::UpdateMapCodeCache(receiver, name, handler);
- return handler;
+ return compiler.CompileStoreTransition(receiver, lookup, transition,
name);
}
=======================================
--- /branches/bleeding_edge/src/stub-cache.h Wed Oct 2 17:23:30 2013 UTC
+++ /branches/bleeding_edge/src/stub-cache.h Fri Oct 11 13:48:14 2013 UTC
@@ -90,14 +90,10 @@
Code::Kind kind,
Code::ExtraICState extra_state =
Code::kNoExtraICState);
- Handle<Code> FindLoadHandler(Handle<Name> name,
- Handle<JSObject> receiver,
- Code::Kind kind);
-
- Handle<Code> FindStoreHandler(Handle<Name> name,
- Handle<JSObject> receiver,
- Code::Kind kind,
- StrictModeFlag strict_mode);
+ Handle<Code> FindHandler(Handle<Name> name,
+ Handle<JSObject> receiver,
+ Code::Kind kind,
+ StrictModeFlag strict_mode = kNonStrictMode);
Handle<Code> ComputeMonomorphicIC(Handle<HeapObject> receiver,
Handle<Code> handler,
--
--
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.