Unify computation of load stubs in stub cache.

R=verwaest@chromium.org

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16660 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 8bf91ffe
......@@ -1318,7 +1318,7 @@ Handle<Code> LoadIC::ComputeLoadHandler(LookupResult* lookup,
switch (lookup->type()) {
case FIELD:
return isolate()->stub_cache()->ComputeLoadField(
name, receiver, holder,
name, receiver, holder, Code::LOAD_IC,
lookup->GetFieldIndex(), lookup->representation());
case CONSTANT: {
Handle<Object> constant(lookup->GetConstant(), isolate());
......@@ -1326,7 +1326,7 @@ Handle<Code> LoadIC::ComputeLoadHandler(LookupResult* lookup,
// be embedded into code.
if (constant->IsConsString()) return Handle<Code>::null();
return isolate()->stub_cache()->ComputeLoadConstant(
name, receiver, holder, constant);
name, receiver, holder, Code::LOAD_IC, constant);
}
case NORMAL:
if (holder->IsGlobalObject()) {
......@@ -1350,7 +1350,7 @@ Handle<Code> LoadIC::ComputeLoadHandler(LookupResult* lookup,
if (v8::ToCData<Address>(info->getter()) == 0) break;
if (!info->IsCompatibleReceiver(*receiver)) break;
return isolate()->stub_cache()->ComputeLoadCallback(
name, receiver, holder, info);
name, receiver, holder, Code::LOAD_IC, info);
} else if (callback->IsAccessorPair()) {
Handle<Object> getter(Handle<AccessorPair>::cast(callback)->getter(),
isolate());
......@@ -1363,7 +1363,7 @@ Handle<Code> LoadIC::ComputeLoadHandler(LookupResult* lookup,
call_optimization.IsCompatibleReceiver(*receiver) &&
FLAG_js_accessor_ics) {
return isolate()->stub_cache()->ComputeLoadCallback(
name, receiver, holder, call_optimization);
name, receiver, holder, Code::LOAD_IC, call_optimization);
}
return isolate()->stub_cache()->ComputeLoadViaGetter(
name, receiver, holder, function);
......@@ -1372,7 +1372,8 @@ Handle<Code> LoadIC::ComputeLoadHandler(LookupResult* lookup,
PropertyIndex lengthIndex =
PropertyIndex::NewHeaderIndex(JSArray::kLengthOffset / kPointerSize);
return isolate()->stub_cache()->ComputeLoadField(
name, receiver, holder, lengthIndex, Representation::Tagged());
name, receiver, holder, Code::LOAD_IC,
lengthIndex, Representation::Tagged());
}
// TODO(dcarney): Handle correctly.
if (callback->IsDeclaredAccessorInfo()) break;
......@@ -1383,7 +1384,7 @@ Handle<Code> LoadIC::ComputeLoadHandler(LookupResult* lookup,
case INTERCEPTOR:
ASSERT(HasInterceptorGetter(*holder));
return isolate()->stub_cache()->ComputeLoadInterceptor(
name, receiver, holder);
name, receiver, holder, Code::LOAD_IC);
default:
break;
}
......@@ -1538,16 +1539,16 @@ Handle<Code> KeyedLoadIC::ComputeLoadHandler(LookupResult* lookup,
Handle<JSObject> holder(lookup->holder(), isolate());
switch (lookup->type()) {
case FIELD:
return isolate()->stub_cache()->ComputeKeyedLoadField(
name, receiver, holder,
return isolate()->stub_cache()->ComputeLoadField(
name, receiver, holder, Code::KEYED_LOAD_IC,
lookup->GetFieldIndex(), lookup->representation());
case CONSTANT: {
Handle<Object> constant(lookup->GetConstant(), isolate());
// TODO(2803): Don't compute a stub for cons strings because they cannot
// be embedded into code.
if (constant->IsConsString()) return Handle<Code>::null();
return isolate()->stub_cache()->ComputeKeyedLoadConstant(
name, receiver, holder, constant);
return isolate()->stub_cache()->ComputeLoadConstant(
name, receiver, holder, Code::KEYED_LOAD_IC, constant);
}
case CALLBACKS: {
Handle<Object> callback_object(lookup->GetCallbackObject(), isolate());
......@@ -1557,8 +1558,8 @@ Handle<Code> KeyedLoadIC::ComputeLoadHandler(LookupResult* lookup,
Handle<ExecutableAccessorInfo>::cast(callback_object);
if (v8::ToCData<Address>(callback->getter()) == 0) break;
if (!callback->IsCompatibleReceiver(*receiver)) break;
return isolate()->stub_cache()->ComputeKeyedLoadCallback(
name, receiver, holder, callback);
return isolate()->stub_cache()->ComputeLoadCallback(
name, receiver, holder, Code::KEYED_LOAD_IC, callback);
} else if (callback_object->IsAccessorPair()) {
Handle<Object> getter(
Handle<AccessorPair>::cast(callback_object)->getter(),
......@@ -1571,16 +1572,16 @@ Handle<Code> KeyedLoadIC::ComputeLoadHandler(LookupResult* lookup,
if (call_optimization.is_simple_api_call() &&
call_optimization.IsCompatibleReceiver(*receiver) &&
FLAG_js_accessor_ics) {
return isolate()->stub_cache()->ComputeKeyedLoadCallback(
name, receiver, holder, call_optimization);
return isolate()->stub_cache()->ComputeLoadCallback(
name, receiver, holder, Code::KEYED_LOAD_IC, call_optimization);
}
}
break;
}
case INTERCEPTOR:
ASSERT(HasInterceptorGetter(lookup->holder()));
return isolate()->stub_cache()->ComputeKeyedLoadInterceptor(
name, receiver, holder);
return isolate()->stub_cache()->ComputeLoadInterceptor(
name, receiver, holder, Code::KEYED_LOAD_IC);
default:
// Always rewrite to the generic case so that we do not
// repeatedly try to rewrite.
......
......@@ -272,21 +272,29 @@ Handle<Code> StubCache::ComputeLoadNonexistent(Handle<Name> name,
Handle<Code> StubCache::ComputeLoadField(Handle<Name> name,
Handle<JSObject> receiver,
Handle<JSObject> holder,
Code::Kind kind,
PropertyIndex field,
Representation representation) {
if (receiver.is_identical_to(holder)) {
if (kind == Code::LOAD_IC) {
LoadFieldStub stub(field.is_inobject(holder),
field.translate(holder),
representation);
return stub.GetCode(isolate());
} else {
KeyedLoadFieldStub stub(field.is_inobject(holder),
field.translate(holder),
representation);
return stub.GetCode(isolate());
}
}
Handle<JSObject> stub_holder = StubHolder(receiver, holder);
Handle<Code> stub = FindLoadHandler(
name, receiver, stub_holder, Code::LOAD_IC, Code::FIELD);
name, receiver, stub_holder, kind, Code::FIELD);
if (!stub.is_null()) return stub;
LoadStubCompiler compiler(isolate_);
BaseLoadStubCompiler compiler(isolate_, kind);
Handle<Code> handler =
compiler.CompileLoadField(receiver, holder, name, field, representation);
JSObject::UpdateMapCodeCache(stub_holder, name, handler);
......@@ -298,14 +306,15 @@ Handle<Code> StubCache::ComputeLoadCallback(
Handle<Name> name,
Handle<JSObject> receiver,
Handle<JSObject> holder,
Code::Kind kind,
Handle<ExecutableAccessorInfo> callback) {
ASSERT(v8::ToCData<Address>(callback->getter()) != 0);
Handle<JSObject> stub_holder = StubHolder(receiver, holder);
Handle<Code> stub = FindLoadHandler(
name, receiver, stub_holder, Code::LOAD_IC, Code::CALLBACKS);
name, receiver, stub_holder, kind, Code::CALLBACKS);
if (!stub.is_null()) return stub;
LoadStubCompiler compiler(isolate_);
BaseLoadStubCompiler compiler(isolate_, kind);
Handle<Code> handler =
compiler.CompileLoadCallback(receiver, holder, name, callback);
JSObject::UpdateMapCodeCache(stub_holder, name, handler);
......@@ -317,13 +326,14 @@ Handle<Code> StubCache::ComputeLoadCallback(
Handle<Name> name,
Handle<JSObject> receiver,
Handle<JSObject> holder,
Code::Kind kind,
const CallOptimization& call_optimization) {
Handle<JSObject> stub_holder = StubHolder(receiver, holder);
Handle<Code> stub = FindLoadHandler(
name, receiver, stub_holder, Code::LOAD_IC, Code::CALLBACKS);
name, receiver, stub_holder, kind, Code::CALLBACKS);
if (!stub.is_null()) return stub;
LoadStubCompiler compiler(isolate_);
BaseLoadStubCompiler compiler(isolate_, kind);
Handle<Code> handler =
compiler.CompileLoadCallback(receiver, holder, name, call_optimization);
JSObject::UpdateMapCodeCache(stub_holder, name, handler);
......@@ -351,29 +361,30 @@ Handle<Code> StubCache::ComputeLoadViaGetter(Handle<Name> name,
Handle<Code> StubCache::ComputeLoadConstant(Handle<Name> name,
Handle<JSObject> receiver,
Handle<JSObject> holder,
Code::Kind kind,
Handle<Object> value) {
Handle<JSObject> stub_holder = StubHolder(receiver, holder);
Handle<Code> handler = FindLoadHandler(
name, receiver, stub_holder, Code::LOAD_IC, Code::CONSTANT);
name, receiver, stub_holder, kind, Code::CONSTANT);
if (!handler.is_null()) return handler;
LoadStubCompiler compiler(isolate_);
BaseLoadStubCompiler compiler(isolate_, kind);
handler = compiler.CompileLoadConstant(receiver, holder, name, value);
JSObject::UpdateMapCodeCache(stub_holder, name, handler);
return handler;
}
Handle<Code> StubCache::ComputeLoadInterceptor(Handle<Name> name,
Handle<JSObject> receiver,
Handle<JSObject> holder) {
Handle<JSObject> holder,
Code::Kind kind) {
Handle<JSObject> stub_holder = StubHolder(receiver, holder);
Handle<Code> stub = FindLoadHandler(
name, receiver, stub_holder, Code::LOAD_IC, Code::INTERCEPTOR);
name, receiver, stub_holder, kind, Code::INTERCEPTOR);
if (!stub.is_null()) return stub;
LoadStubCompiler compiler(isolate_);
BaseLoadStubCompiler compiler(isolate_, kind);
Handle<Code> handler =
compiler.CompileLoadInterceptor(receiver, holder, name);
JSObject::UpdateMapCodeCache(stub_holder, name, handler);
......@@ -404,101 +415,6 @@ Handle<Code> StubCache::ComputeLoadGlobal(Handle<Name> name,
}
Handle<Code> StubCache::ComputeKeyedLoadField(Handle<Name> name,
Handle<JSObject> receiver,
Handle<JSObject> holder,
PropertyIndex field,
Representation representation) {
if (receiver.is_identical_to(holder)) {
// TODO(titzer): this should use an HObjectAccess
KeyedLoadFieldStub stub(field.is_inobject(holder),
field.translate(holder),
representation);
return stub.GetCode(isolate());
}
Handle<JSObject> stub_holder = StubHolder(receiver, holder);
Handle<Code> stub = FindLoadHandler(
name, receiver, stub_holder, Code::KEYED_LOAD_IC, Code::FIELD);
if (!stub.is_null()) return stub;
KeyedLoadStubCompiler compiler(isolate_);
Handle<Code> handler =
compiler.CompileLoadField(receiver, holder, name, field, representation);
JSObject::UpdateMapCodeCache(stub_holder, name, handler);
return handler;
}
Handle<Code> StubCache::ComputeKeyedLoadConstant(Handle<Name> name,
Handle<JSObject> receiver,
Handle<JSObject> holder,
Handle<Object> value) {
Handle<JSObject> stub_holder = StubHolder(receiver, holder);
Handle<Code> handler = FindLoadHandler(
name, receiver, stub_holder, Code::KEYED_LOAD_IC,
Code::CONSTANT);
if (!handler.is_null()) return handler;
KeyedLoadStubCompiler compiler(isolate_);
handler = compiler.CompileLoadConstant(receiver, holder, name, value);
JSObject::UpdateMapCodeCache(stub_holder, name, handler);
return handler;
}
Handle<Code> StubCache::ComputeKeyedLoadInterceptor(Handle<Name> name,
Handle<JSObject> receiver,
Handle<JSObject> holder) {
Handle<JSObject> stub_holder = StubHolder(receiver, holder);
Handle<Code> stub = FindLoadHandler(
name, receiver, stub_holder, Code::KEYED_LOAD_IC, Code::INTERCEPTOR);
if (!stub.is_null()) return stub;
KeyedLoadStubCompiler compiler(isolate_);
Handle<Code> handler =
compiler.CompileLoadInterceptor(receiver, holder, name);
JSObject::UpdateMapCodeCache(stub_holder, name, handler);
return handler;
}
Handle<Code> StubCache::ComputeKeyedLoadCallback(
Handle<Name> name,
Handle<JSObject> receiver,
Handle<JSObject> holder,
Handle<ExecutableAccessorInfo> callback) {
Handle<JSObject> stub_holder = StubHolder(receiver, holder);
Handle<Code> stub = FindLoadHandler(
name, receiver, stub_holder, Code::KEYED_LOAD_IC, Code::CALLBACKS);
if (!stub.is_null()) return stub;
KeyedLoadStubCompiler compiler(isolate_);
Handle<Code> handler =
compiler.CompileLoadCallback(receiver, holder, name, callback);
JSObject::UpdateMapCodeCache(stub_holder, name, handler);
return handler;
}
Handle<Code> StubCache::ComputeKeyedLoadCallback(
Handle<Name> name,
Handle<JSObject> receiver,
Handle<JSObject> holder,
const CallOptimization& call_optimization) {
Handle<JSObject> stub_holder = StubHolder(receiver, holder);
Handle<Code> stub = FindLoadHandler(
name, receiver, stub_holder, Code::KEYED_LOAD_IC, Code::CALLBACKS);
if (!stub.is_null()) return stub;
KeyedLoadStubCompiler compiler(isolate_);
Handle<Code> handler =
compiler.CompileLoadCallback(receiver, holder, name, call_optimization);
JSObject::UpdateMapCodeCache(stub_holder, name, handler);
return handler;
}
Handle<Code> StubCache::ComputeStoreField(Handle<Name> name,
Handle<JSObject> receiver,
LookupResult* lookup,
......@@ -1957,23 +1873,15 @@ void StubCompiler::TailCallBuiltin(MacroAssembler* masm, Builtins::Name name) {
}
void LoadStubCompiler::JitEvent(Handle<Name> name, Handle<Code> code) {
GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code));
}
void KeyedLoadStubCompiler::JitEvent(Handle<Name> name, Handle<Code> code) {
GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code));
}
void StoreStubCompiler::JitEvent(Handle<Name> name, Handle<Code> code) {
GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code));
}
void KeyedStoreStubCompiler::JitEvent(Handle<Name> name, Handle<Code> code) {
GDBJIT(AddCode(GDBJITInterface::KEYED_STORE_IC, *name, *code));
Register* BaseLoadStoreStubCompiler::GetRegisters(Code::Kind kind) {
switch (kind) {
case Code::LOAD_IC: return LoadStubCompiler::registers();
case Code::STORE_IC: return StoreStubCompiler::registers();
case Code::KEYED_LOAD_IC: return KeyedLoadStubCompiler::registers();
case Code::KEYED_STORE_IC: return KeyedStoreStubCompiler::registers();
default: UNREACHABLE();
}
return NULL;
}
......
This diff is collapsed.
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