allowed keyed store callbacks ic generation
R=verwaest@chromium.org BUG= Review URL: https://codereview.chromium.org/173853005 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@19744 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
469428e610
commit
132d4428e5
@ -1239,22 +1239,18 @@ Handle<Code> StoreStubCompiler::CompileStoreCallback(
|
||||
void StoreStubCompiler::GenerateStoreViaSetter(
|
||||
MacroAssembler* masm,
|
||||
Handle<HeapType> type,
|
||||
Register receiver,
|
||||
Handle<JSFunction> setter) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- x0 : value
|
||||
// -- x1 : receiver
|
||||
// -- x2 : name
|
||||
// -- lr : return address
|
||||
// -----------------------------------
|
||||
Register value = x0;
|
||||
Register receiver = x1;
|
||||
Label miss;
|
||||
|
||||
{
|
||||
FrameScope scope(masm, StackFrame::INTERNAL);
|
||||
|
||||
// Save value register, so we can restore it later.
|
||||
__ Push(value);
|
||||
__ Push(value());
|
||||
|
||||
if (!setter.is_null()) {
|
||||
// Call the JavaScript setter with receiver and value on the stack.
|
||||
@ -1264,7 +1260,7 @@ void StoreStubCompiler::GenerateStoreViaSetter(
|
||||
FieldMemOperand(
|
||||
receiver, JSGlobalObject::kGlobalReceiverOffset));
|
||||
}
|
||||
__ Push(receiver, value);
|
||||
__ Push(receiver, value());
|
||||
ParameterCount actual(1);
|
||||
ParameterCount expected(setter);
|
||||
__ InvokeFunction(setter, expected, actual,
|
||||
@ -1276,7 +1272,7 @@ void StoreStubCompiler::GenerateStoreViaSetter(
|
||||
}
|
||||
|
||||
// We have to return the passed value, not the return value of the setter.
|
||||
__ Pop(value);
|
||||
__ Pop(x0);
|
||||
|
||||
// Restore context register.
|
||||
__ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
|
||||
@ -1343,16 +1339,21 @@ Register* KeyedLoadStubCompiler::registers() {
|
||||
}
|
||||
|
||||
|
||||
Register StoreStubCompiler::value() {
|
||||
return x0;
|
||||
}
|
||||
|
||||
|
||||
Register* StoreStubCompiler::registers() {
|
||||
// receiver, name, value, scratch1, scratch2, scratch3.
|
||||
static Register registers[] = { x1, x2, x0, x3, x4, x5 };
|
||||
// receiver, value, scratch1, scratch2, scratch3.
|
||||
static Register registers[] = { x1, x2, x3, x4, x5 };
|
||||
return registers;
|
||||
}
|
||||
|
||||
|
||||
Register* KeyedStoreStubCompiler::registers() {
|
||||
// receiver, name, value, scratch1, scratch2, scratch3.
|
||||
static Register registers[] = { x2, x1, x0, x3, x4, x5 };
|
||||
// receiver, name, scratch1, scratch2, scratch3.
|
||||
static Register registers[] = { x2, x1, x3, x4, x5 };
|
||||
return registers;
|
||||
}
|
||||
|
||||
|
@ -1256,20 +1256,16 @@ Handle<Code> StoreStubCompiler::CompileStoreCallback(
|
||||
void StoreStubCompiler::GenerateStoreViaSetter(
|
||||
MacroAssembler* masm,
|
||||
Handle<HeapType> type,
|
||||
Register receiver,
|
||||
Handle<JSFunction> setter) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- r0 : value
|
||||
// -- r1 : receiver
|
||||
// -- r2 : name
|
||||
// -- lr : return address
|
||||
// -----------------------------------
|
||||
{
|
||||
FrameScope scope(masm, StackFrame::INTERNAL);
|
||||
Register receiver = r1;
|
||||
Register value = r0;
|
||||
|
||||
// Save value register, so we can restore it later.
|
||||
__ push(value);
|
||||
__ push(value());
|
||||
|
||||
if (!setter.is_null()) {
|
||||
// Call the JavaScript setter with receiver and value on the stack.
|
||||
@ -1279,7 +1275,7 @@ void StoreStubCompiler::GenerateStoreViaSetter(
|
||||
FieldMemOperand(
|
||||
receiver, JSGlobalObject::kGlobalReceiverOffset));
|
||||
}
|
||||
__ Push(receiver, value);
|
||||
__ Push(receiver, value());
|
||||
ParameterCount actual(1);
|
||||
ParameterCount expected(setter);
|
||||
__ InvokeFunction(setter, expected, actual,
|
||||
@ -1367,16 +1363,21 @@ Register* KeyedLoadStubCompiler::registers() {
|
||||
}
|
||||
|
||||
|
||||
Register StoreStubCompiler::value() {
|
||||
return r0;
|
||||
}
|
||||
|
||||
|
||||
Register* StoreStubCompiler::registers() {
|
||||
// receiver, name, value, scratch1, scratch2, scratch3.
|
||||
static Register registers[] = { r1, r2, r0, r3, r4, r5 };
|
||||
// receiver, name, scratch1, scratch2, scratch3.
|
||||
static Register registers[] = { r1, r2, r3, r4, r5 };
|
||||
return registers;
|
||||
}
|
||||
|
||||
|
||||
Register* KeyedStoreStubCompiler::registers() {
|
||||
// receiver, name, value, scratch1, scratch2, scratch3.
|
||||
static Register registers[] = { r2, r1, r0, r3, r4, r5 };
|
||||
// receiver, name, scratch1, scratch2, scratch3.
|
||||
static Register registers[] = { r2, r1, r3, r4, r5 };
|
||||
return registers;
|
||||
}
|
||||
|
||||
|
@ -1320,9 +1320,7 @@ static void Generate_LoadIC_Normal(MacroAssembler* masm) {
|
||||
|
||||
|
||||
static void Generate_LoadIC_Getter_ForDeopt(MacroAssembler* masm) {
|
||||
LoadStubCompiler::GenerateLoadViaGetter(
|
||||
masm, Handle<HeapType>::null(),
|
||||
LoadStubCompiler::registers()[0], Handle<JSFunction>());
|
||||
LoadStubCompiler::GenerateLoadViaGetterForDeopt(masm);
|
||||
}
|
||||
|
||||
|
||||
@ -1387,8 +1385,7 @@ static void Generate_StoreIC_Normal(MacroAssembler* masm) {
|
||||
|
||||
|
||||
static void Generate_StoreIC_Setter_ForDeopt(MacroAssembler* masm) {
|
||||
StoreStubCompiler::GenerateStoreViaSetter(
|
||||
masm, Handle<HeapType>::null(), Handle<JSFunction>());
|
||||
StoreStubCompiler::GenerateStoreViaSetterForDeopt(masm);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1259,30 +1259,26 @@ Handle<Code> StoreStubCompiler::CompileStoreCallback(
|
||||
void StoreStubCompiler::GenerateStoreViaSetter(
|
||||
MacroAssembler* masm,
|
||||
Handle<HeapType> type,
|
||||
Register receiver,
|
||||
Handle<JSFunction> setter) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- eax : value
|
||||
// -- ecx : name
|
||||
// -- edx : receiver
|
||||
// -- esp[0] : return address
|
||||
// -----------------------------------
|
||||
{
|
||||
FrameScope scope(masm, StackFrame::INTERNAL);
|
||||
Register receiver = edx;
|
||||
Register value = eax;
|
||||
|
||||
// Save value register, so we can restore it later.
|
||||
__ push(value);
|
||||
__ push(value());
|
||||
|
||||
if (!setter.is_null()) {
|
||||
// Call the JavaScript setter with receiver and value on the stack.
|
||||
if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
|
||||
// Swap in the global receiver.
|
||||
__ mov(receiver,
|
||||
FieldOperand(receiver, JSGlobalObject::kGlobalReceiverOffset));
|
||||
FieldOperand(receiver, JSGlobalObject::kGlobalReceiverOffset));
|
||||
}
|
||||
__ push(receiver);
|
||||
__ push(value);
|
||||
__ push(value());
|
||||
ParameterCount actual(1);
|
||||
ParameterCount expected(setter);
|
||||
__ InvokeFunction(setter, expected, actual,
|
||||
@ -1383,16 +1379,21 @@ Register* KeyedLoadStubCompiler::registers() {
|
||||
}
|
||||
|
||||
|
||||
Register StoreStubCompiler::value() {
|
||||
return eax;
|
||||
}
|
||||
|
||||
|
||||
Register* StoreStubCompiler::registers() {
|
||||
// receiver, name, value, scratch1, scratch2, scratch3.
|
||||
static Register registers[] = { edx, ecx, eax, ebx, edi, no_reg };
|
||||
// receiver, name, scratch1, scratch2, scratch3.
|
||||
static Register registers[] = { edx, ecx, ebx, edi, no_reg };
|
||||
return registers;
|
||||
}
|
||||
|
||||
|
||||
Register* KeyedStoreStubCompiler::registers() {
|
||||
// receiver, name, value, scratch1, scratch2, scratch3.
|
||||
static Register registers[] = { edx, ecx, eax, ebx, edi, no_reg };
|
||||
// receiver, name, scratch1, scratch2, scratch3.
|
||||
static Register registers[] = { edx, ecx, ebx, edi, no_reg };
|
||||
return registers;
|
||||
}
|
||||
|
||||
|
@ -1353,7 +1353,6 @@ Handle<Code> StoreIC::CompileHandler(LookupResult* lookup,
|
||||
ASSERT(holder.is_identical_to(receiver));
|
||||
return isolate()->builtins()->StoreIC_Normal();
|
||||
case CALLBACKS: {
|
||||
if (kind() == Code::KEYED_STORE_IC) break;
|
||||
Handle<Object> callback(lookup->GetCallbackObject(), isolate());
|
||||
if (callback->IsExecutableAccessorInfo()) {
|
||||
Handle<ExecutableAccessorInfo> info =
|
||||
|
@ -1125,7 +1125,7 @@ Handle<Code> StoreStubCompiler::CompileStoreViaSetter(
|
||||
Handle<JSFunction> setter) {
|
||||
Handle<HeapType> type = IC::CurrentTypeOf(object, isolate());
|
||||
HandlerFrontend(type, receiver(), holder, name);
|
||||
GenerateStoreViaSetter(masm(), type, setter);
|
||||
GenerateStoreViaSetter(masm(), type, receiver(), setter);
|
||||
|
||||
return GetCode(kind(), Code::FAST, name);
|
||||
}
|
||||
|
@ -522,11 +522,11 @@ class BaseLoadStoreStubCompiler: public StubCompiler {
|
||||
}
|
||||
void JitEvent(Handle<Name> name, Handle<Code> code);
|
||||
|
||||
virtual Register receiver() = 0;
|
||||
virtual Register name() = 0;
|
||||
virtual Register scratch1() = 0;
|
||||
virtual Register scratch2() = 0;
|
||||
virtual Register scratch3() = 0;
|
||||
Register receiver() { return registers_[0]; }
|
||||
Register name() { return registers_[1]; }
|
||||
Register scratch1() { return registers_[2]; }
|
||||
Register scratch2() { return registers_[3]; }
|
||||
Register scratch3() { return registers_[4]; }
|
||||
|
||||
void InitializeRegisters();
|
||||
|
||||
@ -583,6 +583,11 @@ class LoadStubCompiler: public BaseLoadStoreStubCompiler {
|
||||
Register receiver,
|
||||
Handle<JSFunction> getter);
|
||||
|
||||
static void GenerateLoadViaGetterForDeopt(MacroAssembler* masm) {
|
||||
GenerateLoadViaGetter(
|
||||
masm, Handle<HeapType>::null(), no_reg, Handle<JSFunction>());
|
||||
}
|
||||
|
||||
Handle<Code> CompileLoadNonexistent(Handle<HeapType> type,
|
||||
Handle<JSObject> last,
|
||||
Handle<Name> name);
|
||||
@ -593,8 +598,6 @@ class LoadStubCompiler: public BaseLoadStoreStubCompiler {
|
||||
Handle<Name> name,
|
||||
bool is_dont_delete);
|
||||
|
||||
static Register* registers();
|
||||
|
||||
protected:
|
||||
ContextualMode contextual_mode() {
|
||||
return LoadIC::GetContextualMode(extra_state());
|
||||
@ -636,12 +639,10 @@ class LoadStubCompiler: public BaseLoadStoreStubCompiler {
|
||||
Handle<Name> name,
|
||||
LookupResult* lookup);
|
||||
|
||||
virtual Register receiver() { return registers_[0]; }
|
||||
virtual Register name() { return registers_[1]; }
|
||||
virtual Register scratch1() { return registers_[2]; }
|
||||
virtual Register scratch2() { return registers_[3]; }
|
||||
virtual Register scratch3() { return registers_[4]; }
|
||||
private:
|
||||
static Register* registers();
|
||||
Register scratch4() { return registers_[5]; }
|
||||
friend class BaseLoadStoreStubCompiler;
|
||||
};
|
||||
|
||||
|
||||
@ -726,8 +727,14 @@ class StoreStubCompiler: public BaseLoadStoreStubCompiler {
|
||||
|
||||
static void GenerateStoreViaSetter(MacroAssembler* masm,
|
||||
Handle<HeapType> type,
|
||||
Register receiver,
|
||||
Handle<JSFunction> setter);
|
||||
|
||||
static void GenerateStoreViaSetterForDeopt(MacroAssembler* masm) {
|
||||
GenerateStoreViaSetter(
|
||||
masm, Handle<HeapType>::null(), no_reg, Handle<JSFunction>());
|
||||
}
|
||||
|
||||
Handle<Code> CompileStoreViaSetter(Handle<JSObject> object,
|
||||
Handle<JSObject> holder,
|
||||
Handle<Name> name,
|
||||
@ -757,17 +764,9 @@ class StoreStubCompiler: public BaseLoadStoreStubCompiler {
|
||||
Label* label,
|
||||
Handle<Name> name);
|
||||
|
||||
virtual Register receiver() { return registers_[0]; }
|
||||
virtual Register name() { return registers_[1]; }
|
||||
Register value() { return registers_[2]; }
|
||||
virtual Register scratch1() { return registers_[3]; }
|
||||
virtual Register scratch2() { return registers_[4]; }
|
||||
virtual Register scratch3() { return registers_[5]; }
|
||||
|
||||
protected:
|
||||
static Register* registers();
|
||||
|
||||
private:
|
||||
static Register* registers();
|
||||
static Register value();
|
||||
friend class BaseLoadStoreStubCompiler;
|
||||
};
|
||||
|
||||
@ -795,9 +794,7 @@ class KeyedStoreStubCompiler: public StoreStubCompiler {
|
||||
return KeyedStoreIC::GetKeyedAccessStoreMode(extra_state());
|
||||
}
|
||||
|
||||
Register transition_map() {
|
||||
return registers()[3];
|
||||
}
|
||||
Register transition_map() { return scratch1(); }
|
||||
|
||||
friend class BaseLoadStoreStubCompiler;
|
||||
};
|
||||
|
@ -1154,20 +1154,16 @@ Handle<Code> StoreStubCompiler::CompileStoreCallback(
|
||||
void StoreStubCompiler::GenerateStoreViaSetter(
|
||||
MacroAssembler* masm,
|
||||
Handle<HeapType> type,
|
||||
Register receiver,
|
||||
Handle<JSFunction> setter) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- rax : value
|
||||
// -- rcx : name
|
||||
// -- rdx : receiver
|
||||
// -- rsp[0] : return address
|
||||
// -----------------------------------
|
||||
{
|
||||
FrameScope scope(masm, StackFrame::INTERNAL);
|
||||
Register receiver = rdx;
|
||||
Register value = rax;
|
||||
|
||||
// Save value register, so we can restore it later.
|
||||
__ push(value);
|
||||
__ push(value());
|
||||
|
||||
if (!setter.is_null()) {
|
||||
// Call the JavaScript setter with receiver and value on the stack.
|
||||
@ -1177,7 +1173,7 @@ void StoreStubCompiler::GenerateStoreViaSetter(
|
||||
FieldOperand(receiver, JSGlobalObject::kGlobalReceiverOffset));
|
||||
}
|
||||
__ push(receiver);
|
||||
__ push(value);
|
||||
__ push(value());
|
||||
ParameterCount actual(1);
|
||||
ParameterCount expected(setter);
|
||||
__ InvokeFunction(setter, expected, actual,
|
||||
@ -1285,16 +1281,21 @@ Register* KeyedLoadStubCompiler::registers() {
|
||||
}
|
||||
|
||||
|
||||
Register StoreStubCompiler::value() {
|
||||
return rax;
|
||||
}
|
||||
|
||||
|
||||
Register* StoreStubCompiler::registers() {
|
||||
// receiver, name, value, scratch1, scratch2, scratch3.
|
||||
static Register registers[] = { rdx, rcx, rax, rbx, rdi, r8 };
|
||||
// receiver, name, scratch1, scratch2, scratch3.
|
||||
static Register registers[] = { rdx, rcx, rbx, rdi, r8 };
|
||||
return registers;
|
||||
}
|
||||
|
||||
|
||||
Register* KeyedStoreStubCompiler::registers() {
|
||||
// receiver, name, value, scratch1, scratch2, scratch3.
|
||||
static Register registers[] = { rdx, rcx, rax, rbx, rdi, r8 };
|
||||
// receiver, name, scratch1, scratch2, scratch3.
|
||||
static Register registers[] = { rdx, rcx, rbx, rdi, r8 };
|
||||
return registers;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user