Added LoadIC stub for getters.

Removed some dead constants on the way.

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@11735 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 81e8aa00
......@@ -2835,6 +2835,43 @@ Handle<Code> LoadStubCompiler::CompileLoadCallback(
}
Handle<Code> LoadStubCompiler::CompileLoadViaGetter(
Handle<String> name,
Handle<JSObject> receiver,
Handle<JSObject> holder,
Handle<JSFunction> getter) {
// ----------- S t a t e -------------
// -- r0 : receiver
// -- r2 : name
// -- lr : return address
// -----------------------------------
Label miss;
// Check that the maps haven't changed.
__ JumpIfSmi(r0, &miss);
CheckPrototypes(receiver, r0, holder, r3, r4, r1, name, &miss);
{
FrameScope scope(masm(), StackFrame::INTERNAL);
// Call the JavaScript getter with the receiver on the stack.
__ push(r0);
__ InvokeFunction(getter, ParameterCount(0), CALL_FUNCTION,
NullCallWrapper(), CALL_AS_METHOD);
// Restore context register.
__ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
}
__ Ret();
__ bind(&miss);
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
return GetCode(CALLBACKS, name);
}
Handle<Code> LoadStubCompiler::CompileLoadConstant(Handle<JSObject> object,
Handle<JSObject> holder,
Handle<JSFunction> value,
......
......@@ -2860,6 +2860,43 @@ Handle<Code> LoadStubCompiler::CompileLoadCallback(
}
Handle<Code> LoadStubCompiler::CompileLoadViaGetter(
Handle<String> name,
Handle<JSObject> receiver,
Handle<JSObject> holder,
Handle<JSFunction> getter) {
// ----------- S t a t e -------------
// -- ecx : name
// -- edx : receiver
// -- esp[0] : return address
// -----------------------------------
Label miss;
// Check that the maps haven't changed.
__ JumpIfSmi(edx, &miss);
CheckPrototypes(receiver, edx, holder, ebx, eax, edi, name, &miss);
{
FrameScope scope(masm(), StackFrame::INTERNAL);
// Call the JavaScript getter with the receiver on the stack.
__ push(edx);
__ InvokeFunction(getter, ParameterCount(0), CALL_FUNCTION,
NullCallWrapper(), CALL_AS_METHOD);
// Restore context register.
__ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
}
__ ret(0);
__ bind(&miss);
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
return GetCode(CALLBACKS, name);
}
Handle<Code> LoadStubCompiler::CompileLoadConstant(Handle<JSObject> object,
Handle<JSObject> holder,
Handle<JSFunction> value,
......
......@@ -988,14 +988,25 @@ void LoadIC::UpdateCaches(LookupResult* lookup,
}
break;
case CALLBACKS: {
Handle<Object> callback_object(lookup->GetCallbackObject());
if (!callback_object->IsAccessorInfo()) return;
Handle<AccessorInfo> callback =
Handle<AccessorInfo>::cast(callback_object);
if (v8::ToCData<Address>(callback->getter()) == 0) return;
if (!callback->IsCompatibleReceiver(*receiver)) return;
code = isolate()->stub_cache()->ComputeLoadCallback(
name, receiver, holder, callback);
Handle<Object> callback(lookup->GetCallbackObject());
if (callback->IsAccessorInfo()) {
Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(callback);
if (v8::ToCData<Address>(info->getter()) == 0) return;
if (!info->IsCompatibleReceiver(*receiver)) return;
code = isolate()->stub_cache()->ComputeLoadCallback(
name, receiver, holder, info);
} else if (callback->IsAccessorPair()) {
Handle<Object> getter(Handle<AccessorPair>::cast(callback)->getter());
if (!getter->IsJSFunction()) return;
if (holder->IsGlobalObject()) return;
if (!receiver->HasFastProperties()) return;
code = isolate()->stub_cache()->ComputeLoadViaGetter(
name, receiver, holder, Handle<JSFunction>::cast(getter));
} else {
ASSERT(callback->IsForeign());
// No IC support for old-style native accessors.
return;
}
break;
}
case INTERCEPTOR:
......
......@@ -2839,6 +2839,43 @@ Handle<Code> LoadStubCompiler::CompileLoadCallback(
}
Handle<Code> LoadStubCompiler::CompileLoadViaGetter(
Handle<String> name,
Handle<JSObject> receiver,
Handle<JSObject> holder,
Handle<JSFunction> getter) {
// ----------- S t a t e -------------
// -- a0 : receiver
// -- a2 : name
// -- ra : return address
// -----------------------------------
Label miss;
// Check that the maps haven't changed.
__ JumpIfSmi(a0, &miss);
CheckPrototypes(receiver, a0, holder, a3, t0, a1, name, &miss);
{
FrameScope scope(masm(), StackFrame::INTERNAL);
// Call the JavaScript getter with the receiver on the stack.
__ push(a0);
__ InvokeFunction(getter, ParameterCount(0), CALL_FUNCTION,
NullCallWrapper(), CALL_AS_METHOD);
// Restore context register.
__ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
}
__ Ret();
__ bind(&miss);
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
return GetCode(CALLBACKS, name);
}
Handle<Code> LoadStubCompiler::CompileLoadConstant(Handle<JSObject> object,
Handle<JSObject> holder,
Handle<JSFunction> value,
......
......@@ -5010,11 +5010,6 @@ class Map: public HeapObject {
static const int kFunctionWithPrototype = 1;
static const int kUsedForPrototype = 2;
// Layout of the default cache. It holds alternating name and code objects.
static const int kCodeCacheEntrySize = 2;
static const int kCodeCacheEntryNameOffset = 0;
static const int kCodeCacheEntryCodeOffset = 1;
typedef FixedBodyDescriptor<kPointerFieldsBeginOffset,
kPointerFieldsEndOffset,
kSize> BodyDescriptor;
......
......@@ -171,6 +171,25 @@ Handle<Code> StubCache::ComputeLoadCallback(Handle<String> name,
}
Handle<Code> StubCache::ComputeLoadViaGetter(Handle<String> name,
Handle<JSObject> receiver,
Handle<JSObject> holder,
Handle<JSFunction> getter) {
ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, CALLBACKS);
Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
if (probe->IsCode()) return Handle<Code>::cast(probe);
LoadStubCompiler compiler(isolate_);
Handle<Code> code =
compiler.CompileLoadViaGetter(name, receiver, holder, getter);
PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name));
GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code));
JSObject::UpdateMapCodeCache(receiver, name, code);
return code;
}
Handle<Code> StubCache::ComputeLoadConstant(Handle<String> name,
Handle<JSObject> receiver,
Handle<JSObject> holder,
......
......@@ -90,6 +90,11 @@ class StubCache {
Handle<JSObject> holder,
Handle<AccessorInfo> callback);
Handle<Code> ComputeLoadViaGetter(Handle<String> name,
Handle<JSObject> receiver,
Handle<JSObject> holder,
Handle<JSFunction> getter);
Handle<Code> ComputeLoadConstant(Handle<String> name,
Handle<JSObject> receiver,
Handle<JSObject> holder,
......@@ -596,6 +601,11 @@ class LoadStubCompiler: public StubCompiler {
Handle<JSObject> holder,
Handle<AccessorInfo> callback);
Handle<Code> CompileLoadViaGetter(Handle<String> name,
Handle<JSObject> receiver,
Handle<JSObject> holder,
Handle<JSFunction> getter);
Handle<Code> CompileLoadConstant(Handle<JSObject> object,
Handle<JSObject> holder,
Handle<JSFunction> value,
......
......@@ -2698,6 +2698,43 @@ Handle<Code> LoadStubCompiler::CompileLoadCallback(
}
Handle<Code> LoadStubCompiler::CompileLoadViaGetter(
Handle<String> name,
Handle<JSObject> receiver,
Handle<JSObject> holder,
Handle<JSFunction> getter) {
// ----------- S t a t e -------------
// -- rax : receiver
// -- rcx : name
// -- rsp[0] : return address
// -----------------------------------
Label miss;
// Check that the maps haven't changed.
__ JumpIfSmi(rax, &miss);
CheckPrototypes(receiver, rax, holder, rbx, rdx, rdi, name, &miss);
{
FrameScope scope(masm(), StackFrame::INTERNAL);
// Call the JavaScript getter with the receiver on the stack.
__ push(rax);
__ InvokeFunction(getter, ParameterCount(0), CALL_FUNCTION,
NullCallWrapper(), CALL_AS_METHOD);
// Restore context register.
__ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
}
__ ret(0);
__ bind(&miss);
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
return GetCode(CALLBACKS, name);
}
Handle<Code> LoadStubCompiler::CompileLoadConstant(Handle<JSObject> object,
Handle<JSObject> holder,
Handle<JSFunction> value,
......
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