Unify ComputeLoad/StoreHandler and dispatch on compile.

BUG=
R=ulan@chromium.org

Review URL: https://chromiumcodereview.appspot.com/26831002

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@17162 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
verwaest@chromium.org 2013-10-11 13:54:14 +00:00
parent 04e1462f9e
commit e08fbabe15
2 changed files with 64 additions and 70 deletions

View File

@ -1137,8 +1137,13 @@ void LoadIC::UpdateCaches(LookupResult* lookup,
// TODO(jkummerow): It would be nice to support non-JSObjects in // TODO(jkummerow): It would be nice to support non-JSObjects in
// ComputeLoadHandler, then we wouldn't need to go generic here. // ComputeLoadHandler, then we wouldn't need to go generic here.
code = slow_stub(); code = slow_stub();
} else if (!lookup->IsProperty()) {
code = kind() == Code::LOAD_IC
? isolate()->stub_cache()->ComputeLoadNonexistent(
name, Handle<JSObject>::cast(receiver))
: slow_stub();
} else { } else {
code = ComputeLoadHandler(lookup, Handle<JSObject>::cast(receiver), name); code = ComputeHandler(lookup, Handle<JSObject>::cast(receiver), name);
} }
PatchCache(receiver, name, code); PatchCache(receiver, name, code);
@ -1153,20 +1158,15 @@ void IC::UpdateMegamorphicCache(Map* map, Name* name, Code* code) {
} }
Handle<Code> LoadIC::ComputeLoadHandler(LookupResult* lookup, Handle<Code> IC::ComputeHandler(LookupResult* lookup,
Handle<JSObject> receiver, Handle<JSObject> receiver,
Handle<String> name) { Handle<String> name,
if (!lookup->IsProperty()) { Handle<Object> value) {
return kind() == Code::LOAD_IC
? isolate()->stub_cache()->ComputeLoadNonexistent(name, receiver)
: generic_stub();
}
Handle<Code> code = isolate()->stub_cache()->FindHandler( Handle<Code> code = isolate()->stub_cache()->FindHandler(
name, receiver, kind()); name, receiver, kind());
if (!code.is_null()) return code; if (!code.is_null()) return code;
code = CompileLoadHandler(lookup, receiver, name); code = CompileHandler(lookup, receiver, name, value);
if (code.is_null()) return slow_stub(); if (code.is_null()) return slow_stub();
if (code->is_handler() && code->type() != Code::NORMAL) { if (code->is_handler() && code->type() != Code::NORMAL) {
@ -1177,9 +1177,10 @@ Handle<Code> LoadIC::ComputeLoadHandler(LookupResult* lookup,
} }
Handle<Code> LoadIC::CompileLoadHandler(LookupResult* lookup, Handle<Code> LoadIC::CompileHandler(LookupResult* lookup,
Handle<JSObject> receiver, Handle<JSObject> receiver,
Handle<String> name) { Handle<String> name,
Handle<Object> unused) {
Handle<JSObject> holder(lookup->holder()); Handle<JSObject> holder(lookup->holder());
switch (lookup->type()) { switch (lookup->type()) {
case FIELD: case FIELD:
@ -1390,9 +1391,10 @@ MaybeObject* KeyedLoadIC::Load(Handle<Object> object,
} }
Handle<Code> KeyedLoadIC::CompileLoadHandler(LookupResult* lookup, Handle<Code> KeyedLoadIC::CompileHandler(LookupResult* lookup,
Handle<JSObject> receiver, Handle<JSObject> receiver,
Handle<String> name) { Handle<String> name,
Handle<Object> value) {
// Compute a monomorphic stub. // Compute a monomorphic stub.
Handle<JSObject> holder(lookup->holder(), isolate()); Handle<JSObject> holder(lookup->holder(), isolate());
switch (lookup->type()) { switch (lookup->type()) {
@ -1633,37 +1635,17 @@ void StoreIC::UpdateCaches(LookupResult* lookup,
// These are not cacheable, so we never see such LookupResults here. // These are not cacheable, so we never see such LookupResults here.
ASSERT(!lookup->IsHandler()); ASSERT(!lookup->IsHandler());
Handle<Code> code = ComputeStoreHandler(lookup, receiver, name, value); Handle<Code> code = ComputeHandler(lookup, receiver, name, value);
if (code.is_null()) code = slow_stub();
PatchCache(receiver, name, code); PatchCache(receiver, name, code);
TRACE_IC("StoreIC", name); TRACE_IC("StoreIC", name);
} }
Handle<Code> StoreIC::ComputeStoreHandler(LookupResult* lookup, Handle<Code> StoreIC::CompileHandler(LookupResult* lookup,
Handle<JSObject> receiver, Handle<JSObject> receiver,
Handle<String> name, Handle<String> name,
Handle<Object> value) { 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()); Handle<JSObject> holder(lookup->holder());
switch (lookup->type()) { switch (lookup->type()) {
case FIELD: case FIELD:
@ -2052,10 +2034,10 @@ MaybeObject* KeyedStoreIC::Store(Handle<Object> object,
} }
Handle<Code> KeyedStoreIC::CompileStoreHandler(LookupResult* lookup, Handle<Code> KeyedStoreIC::CompileHandler(LookupResult* lookup,
Handle<JSObject> receiver, Handle<JSObject> receiver,
Handle<String> name, Handle<String> name,
Handle<Object> value) { Handle<Object> value) {
// If the property has a non-field type allowing map transitions // If the property has a non-field type allowing map transitions
// where there is extra room in the object, we leave the IC in its // where there is extra room in the object, we leave the IC in its
// current state. // current state.

View File

@ -173,6 +173,18 @@ class IC {
static inline void SetTargetAtAddress(Address address, Code* target); static inline void SetTargetAtAddress(Address address, Code* target);
static void PostPatching(Address address, Code* target, Code* old_target); static void PostPatching(Address address, Code* target, Code* old_target);
// Compute the handler either by compiling or by retrieving a cached version.
Handle<Code> ComputeHandler(LookupResult* lookup,
Handle<JSObject> receiver,
Handle<String> name,
Handle<Object> value = Handle<Code>::null());
virtual Handle<Code> CompileHandler(LookupResult* lookup,
Handle<JSObject> receiver,
Handle<String> name,
Handle<Object> value) {
UNREACHABLE();
return Handle<Code>::null();
}
void UpdateMonomorphicIC(Handle<HeapObject> receiver, void UpdateMonomorphicIC(Handle<HeapObject> receiver,
Handle<Code> handler, Handle<Code> handler,
Handle<String> name); Handle<String> name);
@ -187,6 +199,14 @@ class IC {
Handle<String> name, Handle<String> name,
Handle<Code> code); Handle<Code> code);
virtual void UpdateMegamorphicCache(Map* map, Name* name, Code* code); virtual void UpdateMegamorphicCache(Map* map, Name* name, Code* code);
virtual Code::Kind kind() const {
UNREACHABLE();
return Code::STUB;
}
virtual Handle<Code> slow_stub() const {
UNREACHABLE();
return Handle<Code>::null();
}
virtual Handle<Code> megamorphic_stub() { virtual Handle<Code> megamorphic_stub() {
UNREACHABLE(); UNREACHABLE();
return Handle<Code>::null(); return Handle<Code>::null();
@ -395,12 +415,10 @@ class LoadIC: public IC {
Handle<Object> object, Handle<Object> object,
Handle<String> name); Handle<String> name);
Handle<Code> ComputeLoadHandler(LookupResult* lookup, virtual Handle<Code> CompileHandler(LookupResult* lookup,
Handle<JSObject> receiver, Handle<JSObject> receiver,
Handle<String> name); Handle<String> name,
virtual Handle<Code> CompileLoadHandler(LookupResult* lookup, Handle<Object> unused);
Handle<JSObject> receiver,
Handle<String> name);
private: private:
// Stub accessors. // Stub accessors.
@ -475,9 +493,10 @@ class KeyedLoadIC: public LoadIC {
return isolate()->builtins()->KeyedLoadIC_Slow(); return isolate()->builtins()->KeyedLoadIC_Slow();
} }
virtual Handle<Code> CompileLoadHandler(LookupResult* lookup, virtual Handle<Code> CompileHandler(LookupResult* lookup,
Handle<JSObject> receiver, Handle<JSObject> receiver,
Handle<String> name); Handle<String> name,
Handle<Object> unused);
virtual void UpdateMegamorphicCache(Map* map, Name* name, Code* code) { } virtual void UpdateMegamorphicCache(Map* map, Name* name, Code* code) { }
private: private:
@ -590,17 +609,10 @@ class StoreIC: public IC {
Handle<JSObject> receiver, Handle<JSObject> receiver,
Handle<String> name, Handle<String> name,
Handle<Object> value); Handle<Object> value);
// Compute the code stub for this store; used for rewriting to virtual Handle<Code> CompileHandler(LookupResult* lookup,
// monomorphic state and making sure that the code stub is in the Handle<JSObject> receiver,
// stub cache. Handle<String> name,
Handle<Code> ComputeStoreHandler(LookupResult* lookup, Handle<Object> value);
Handle<JSObject> receiver,
Handle<String> name,
Handle<Object> value);
virtual Handle<Code> CompileStoreHandler(LookupResult* lookup,
Handle<JSObject> receiver,
Handle<String> name,
Handle<Object> value);
private: private:
void set_target(Code* code) { void set_target(Code* code) {
@ -668,10 +680,10 @@ class KeyedStoreIC: public StoreIC {
protected: protected:
virtual Code::Kind kind() const { return Code::KEYED_STORE_IC; } virtual Code::Kind kind() const { return Code::KEYED_STORE_IC; }
virtual Handle<Code> CompileStoreHandler(LookupResult* lookup, virtual Handle<Code> CompileHandler(LookupResult* lookup,
Handle<JSObject> receiver, Handle<JSObject> receiver,
Handle<String> name, Handle<String> name,
Handle<Object> value); Handle<Object> value);
virtual void UpdateMegamorphicCache(Map* map, Name* name, Code* code) { } virtual void UpdateMegamorphicCache(Map* map, Name* name, Code* code) { }
virtual Handle<Code> pre_monomorphic_stub() { virtual Handle<Code> pre_monomorphic_stub() {