Commit 76cfb388 authored by ishell's avatar ishell Committed by Commit bot

[ic][ia32][x87] Pass value, slot and vector to StoreIC and KeyedStoreIC through the stack.

The handlers cleanup will be done in a follow-up CL.

BUG=v8:5407

Review-Url: https://codereview.chromium.org/2357163003
Cr-Commit-Position: refs/heads/master@{#39617}
parent 502b9aa7
...@@ -88,8 +88,10 @@ void JSGenericLowering::ReplaceWithStubCall(Node* node, Callable callable, ...@@ -88,8 +88,10 @@ void JSGenericLowering::ReplaceWithStubCall(Node* node, Callable callable,
void JSGenericLowering::ReplaceWithStubCall(Node* node, Callable callable, void JSGenericLowering::ReplaceWithStubCall(Node* node, Callable callable,
CallDescriptor::Flags flags, CallDescriptor::Flags flags,
Operator::Properties properties) { Operator::Properties properties) {
const CallInterfaceDescriptor& descriptor = callable.descriptor();
CallDescriptor* desc = Linkage::GetStubCallDescriptor( CallDescriptor* desc = Linkage::GetStubCallDescriptor(
isolate(), zone(), callable.descriptor(), 0, flags, properties); isolate(), zone(), descriptor, descriptor.GetStackParameterCount(), flags,
properties);
Node* stub_code = jsgraph()->HeapConstant(callable.code()); Node* stub_code = jsgraph()->HeapConstant(callable.code());
node->InsertInput(zone(), 0, stub_code); node->InsertInput(zone(), 0, stub_code);
NodeProperties::ChangeOp(node, common()->Call(desc)); NodeProperties::ChangeOp(node, common()->Call(desc));
......
...@@ -237,6 +237,14 @@ void FullCodeGenerator::CallLoadGlobalIC(TypeofMode typeof_mode, ...@@ -237,6 +237,14 @@ void FullCodeGenerator::CallLoadGlobalIC(TypeofMode typeof_mode,
void FullCodeGenerator::CallStoreIC(TypeFeedbackId id) { void FullCodeGenerator::CallStoreIC(TypeFeedbackId id) {
Handle<Code> ic = CodeFactory::StoreIC(isolate(), language_mode()).code(); Handle<Code> ic = CodeFactory::StoreIC(isolate(), language_mode()).code();
STATIC_ASSERT(!StoreDescriptor::kPassLastArgsOnStack ||
StoreDescriptor::kStackArgumentsCount == 2);
if (StoreDescriptor::kPassLastArgsOnStack) {
__ Push(StoreDescriptor::ValueRegister());
__ Push(StoreDescriptor::SlotRegister());
}
CallIC(ic, id); CallIC(ic, id);
RestoreContext(); RestoreContext();
} }
...@@ -244,6 +252,14 @@ void FullCodeGenerator::CallStoreIC(TypeFeedbackId id) { ...@@ -244,6 +252,14 @@ void FullCodeGenerator::CallStoreIC(TypeFeedbackId id) {
void FullCodeGenerator::CallKeyedStoreIC() { void FullCodeGenerator::CallKeyedStoreIC() {
Handle<Code> ic = Handle<Code> ic =
CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
STATIC_ASSERT(!StoreDescriptor::kPassLastArgsOnStack ||
StoreDescriptor::kStackArgumentsCount == 2);
if (StoreDescriptor::kPassLastArgsOnStack) {
__ Push(StoreDescriptor::ValueRegister());
__ Push(StoreDescriptor::SlotRegister());
}
CallIC(ic); CallIC(ic);
RestoreContext(); RestoreContext();
} }
......
...@@ -3671,6 +3671,28 @@ void StoreICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) { ...@@ -3671,6 +3671,28 @@ void StoreICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) {
Register slot = StoreWithVectorDescriptor::SlotRegister(); // edi Register slot = StoreWithVectorDescriptor::SlotRegister(); // edi
Label miss; Label miss;
if (StoreWithVectorDescriptor::kPassLastArgsOnStack) {
// Current stack layout:
// - esp[8] -- value
// - esp[4] -- slot
// - esp[0] -- return address
STATIC_ASSERT(StoreDescriptor::kStackArgumentsCount == 2);
STATIC_ASSERT(StoreWithVectorDescriptor::kStackArgumentsCount == 3);
if (in_frame) {
__ RecordComment("[ StoreDescriptor -> StoreWithVectorDescriptor");
// If the vector is not on the stack, then insert the vector beneath
// return address in order to prepare for calling handler with
// StoreWithVector calling convention.
__ push(Operand(esp, 0));
__ mov(Operand(esp, 4), StoreWithVectorDescriptor::VectorRegister());
__ RecordComment("]");
} else {
__ mov(vector, Operand(esp, 1 * kPointerSize));
}
__ mov(slot, Operand(esp, 2 * kPointerSize));
__ mov(value, Operand(esp, 3 * kPointerSize));
}
__ push(value); __ push(value);
Register scratch = value; Register scratch = value;
...@@ -3812,12 +3834,23 @@ static void HandlePolymorphicKeyedStoreCase(MacroAssembler* masm, ...@@ -3812,12 +3834,23 @@ static void HandlePolymorphicKeyedStoreCase(MacroAssembler* masm,
__ pop(vector); __ pop(vector);
__ pop(receiver); __ pop(receiver);
__ pop(value); __ pop(value);
{ // Ensure that the transition handler we are going to call has the same
// Put vector and slot beneath return address. // number of stack arguments which means that we don't have to adapt them
__ push(vector); // before the call.
__ push(Operand(esp, 1 * kPointerSize)); // push return address STATIC_ASSERT(StoreWithVectorDescriptor::kStackArgumentsCount == 3);
__ mov(Operand(esp, 2 * kPointerSize), slot); STATIC_ASSERT(StoreTransitionDescriptor::kStackArgumentsCount == 3);
} STATIC_ASSERT(StoreWithVectorDescriptor::kParameterCount -
StoreWithVectorDescriptor::kValue ==
StoreTransitionDescriptor::kParameterCount -
StoreTransitionDescriptor::kValue);
STATIC_ASSERT(StoreWithVectorDescriptor::kParameterCount -
StoreWithVectorDescriptor::kSlot ==
StoreTransitionDescriptor::kParameterCount -
StoreTransitionDescriptor::kSlot);
STATIC_ASSERT(StoreWithVectorDescriptor::kParameterCount -
StoreWithVectorDescriptor::kVector ==
StoreTransitionDescriptor::kParameterCount -
StoreTransitionDescriptor::kVector);
__ jmp(Operand::StaticVariable(virtual_register)); __ jmp(Operand::StaticVariable(virtual_register));
__ bind(&prepare_next); __ bind(&prepare_next);
...@@ -3845,6 +3878,28 @@ void KeyedStoreICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) { ...@@ -3845,6 +3878,28 @@ void KeyedStoreICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) {
Register slot = StoreWithVectorDescriptor::SlotRegister(); // edi Register slot = StoreWithVectorDescriptor::SlotRegister(); // edi
Label miss; Label miss;
if (StoreWithVectorDescriptor::kPassLastArgsOnStack) {
// Current stack layout:
// - esp[8] -- value
// - esp[4] -- slot
// - esp[0] -- return address
STATIC_ASSERT(StoreDescriptor::kStackArgumentsCount == 2);
STATIC_ASSERT(StoreWithVectorDescriptor::kStackArgumentsCount == 3);
if (in_frame) {
__ RecordComment("[ StoreDescriptor -> StoreWithVectorDescriptor");
// If the vector is not on the stack, then insert the vector beneath
// return address in order to prepare for calling handler with
// StoreWithVector calling convention.
__ push(Operand(esp, 0));
__ mov(Operand(esp, 4), StoreWithVectorDescriptor::VectorRegister());
__ RecordComment("]");
} else {
__ mov(vector, Operand(esp, 1 * kPointerSize));
}
__ mov(slot, Operand(esp, 2 * kPointerSize));
__ mov(value, Operand(esp, 3 * kPointerSize));
}
__ push(value); __ push(value);
Register scratch = value; Register scratch = value;
......
...@@ -129,13 +129,13 @@ Register NamedStoreHandlerCompiler::FrontendHeader(Register object_reg, ...@@ -129,13 +129,13 @@ Register NamedStoreHandlerCompiler::FrontendHeader(Register object_reg,
Register PropertyHandlerCompiler::Frontend(Handle<Name> name) { Register PropertyHandlerCompiler::Frontend(Handle<Name> name) {
Label miss; Label miss;
if (IC::ICUseVector(kind())) { if (IC::ShouldPushPopSlotAndVector(kind())) {
PushVectorAndSlot(); PushVectorAndSlot();
} }
Register reg = FrontendHeader(receiver(), name, &miss, RETURN_HOLDER); Register reg = FrontendHeader(receiver(), name, &miss, RETURN_HOLDER);
FrontendFooter(name, &miss); FrontendFooter(name, &miss);
// The footer consumes the vector and slot from the stack if miss occurs. // The footer consumes the vector and slot from the stack if miss occurs.
if (IC::ICUseVector(kind())) { if (IC::ShouldPushPopSlotAndVector(kind())) {
DiscardVectorAndSlot(); DiscardVectorAndSlot();
} }
return reg; return reg;
...@@ -209,12 +209,12 @@ Handle<Code> NamedLoadHandlerCompiler::CompileLoadConstant(Handle<Name> name, ...@@ -209,12 +209,12 @@ Handle<Code> NamedLoadHandlerCompiler::CompileLoadConstant(Handle<Name> name,
Handle<Code> NamedLoadHandlerCompiler::CompileLoadNonexistent( Handle<Code> NamedLoadHandlerCompiler::CompileLoadNonexistent(
Handle<Name> name) { Handle<Name> name) {
Label miss; Label miss;
if (IC::ICUseVector(kind())) { if (IC::ShouldPushPopSlotAndVector(kind())) {
DCHECK(kind() == Code::LOAD_IC); DCHECK(kind() == Code::LOAD_IC);
PushVectorAndSlot(); PushVectorAndSlot();
} }
NonexistentFrontendHeader(name, &miss, scratch2(), scratch3()); NonexistentFrontendHeader(name, &miss, scratch2(), scratch3());
if (IC::ICUseVector(kind())) { if (IC::ShouldPushPopSlotAndVector(kind())) {
DiscardVectorAndSlot(); DiscardVectorAndSlot();
} }
GenerateLoadConstant(isolate()->factory()->undefined_value()); GenerateLoadConstant(isolate()->factory()->undefined_value());
...@@ -247,7 +247,7 @@ Handle<Code> NamedLoadHandlerCompiler::CompileLoadCallback( ...@@ -247,7 +247,7 @@ Handle<Code> NamedLoadHandlerCompiler::CompileLoadCallback(
void NamedLoadHandlerCompiler::InterceptorVectorSlotPush(Register holder_reg) { void NamedLoadHandlerCompiler::InterceptorVectorSlotPush(Register holder_reg) {
if (IC::ICUseVector(kind())) { if (IC::ShouldPushPopSlotAndVector(kind())) {
if (holder_reg.is(receiver())) { if (holder_reg.is(receiver())) {
PushVectorAndSlot(); PushVectorAndSlot();
} else { } else {
...@@ -260,7 +260,7 @@ void NamedLoadHandlerCompiler::InterceptorVectorSlotPush(Register holder_reg) { ...@@ -260,7 +260,7 @@ void NamedLoadHandlerCompiler::InterceptorVectorSlotPush(Register holder_reg) {
void NamedLoadHandlerCompiler::InterceptorVectorSlotPop(Register holder_reg, void NamedLoadHandlerCompiler::InterceptorVectorSlotPop(Register holder_reg,
PopMode mode) { PopMode mode) {
if (IC::ICUseVector(kind())) { if (IC::ShouldPushPopSlotAndVector(kind())) {
if (mode == DISCARD) { if (mode == DISCARD) {
DiscardVectorAndSlot(); DiscardVectorAndSlot();
} else { } else {
...@@ -438,16 +438,28 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreTransition( ...@@ -438,16 +438,28 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreTransition(
Handle<Map> transition, Handle<Name> name) { Handle<Map> transition, Handle<Name> name) {
Label miss; Label miss;
bool vector_and_slot_on_stack = // Ensure that the StoreTransitionStub we are going to call has the same
StoreTransitionDescriptor::PassVectorAndSlotOnStack(); // number of stack arguments. This means that we don't have to adapt them
if (vector_and_slot_on_stack) { // if we decide to call the transition or miss stub.
// Speculatively prepare for calling StoreTransitionStub by converting STATIC_ASSERT(StoreWithVectorDescriptor::kStackArgumentsCount ==
// StoreWithVectorDescriptor arguments to StoreTransitionDescriptor StoreTransitionDescriptor::kStackArgumentsCount);
// arguments. STATIC_ASSERT(StoreWithVectorDescriptor::kStackArgumentsCount == 0 ||
PopReturnAddress(this->name()); StoreWithVectorDescriptor::kStackArgumentsCount == 3);
PushVectorAndSlot(); STATIC_ASSERT(StoreWithVectorDescriptor::kParameterCount -
PushReturnAddress(this->name()); StoreWithVectorDescriptor::kValue ==
} else { StoreTransitionDescriptor::kParameterCount -
StoreTransitionDescriptor::kValue);
STATIC_ASSERT(StoreWithVectorDescriptor::kParameterCount -
StoreWithVectorDescriptor::kSlot ==
StoreTransitionDescriptor::kParameterCount -
StoreTransitionDescriptor::kSlot);
STATIC_ASSERT(StoreWithVectorDescriptor::kParameterCount -
StoreWithVectorDescriptor::kVector ==
StoreTransitionDescriptor::kParameterCount -
StoreTransitionDescriptor::kVector);
bool need_save_restore = IC::ShouldPushPopSlotAndVector(kind());
if (need_save_restore) {
PushVectorAndSlot(); PushVectorAndSlot();
} }
...@@ -487,7 +499,7 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreTransition( ...@@ -487,7 +499,7 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreTransition(
DCHECK(descriptors->GetValue(descriptor)->IsJSFunction()); DCHECK(descriptors->GetValue(descriptor)->IsJSFunction());
GenerateRestoreMap(transition, map_reg, scratch1(), &miss); GenerateRestoreMap(transition, map_reg, scratch1(), &miss);
GenerateConstantCheck(map_reg, descriptor, value(), scratch1(), &miss); GenerateConstantCheck(map_reg, descriptor, value(), scratch1(), &miss);
if (!vector_and_slot_on_stack) { if (need_save_restore) {
PopVectorAndSlot(); PopVectorAndSlot();
} }
GenerateRestoreName(name); GenerateRestoreName(name);
...@@ -504,7 +516,7 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreTransition( ...@@ -504,7 +516,7 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreTransition(
? StoreTransitionStub::ExtendStorageAndStoreMapAndValue ? StoreTransitionStub::ExtendStorageAndStoreMapAndValue
: StoreTransitionStub::StoreMapAndValue; : StoreTransitionStub::StoreMapAndValue;
GenerateRestoreMap(transition, map_reg, scratch1(), &miss); GenerateRestoreMap(transition, map_reg, scratch1(), &miss);
if (!vector_and_slot_on_stack) { if (need_save_restore) {
PopVectorAndSlot(); PopVectorAndSlot();
} }
GenerateRestoreName(name); GenerateRestoreName(name);
...@@ -515,12 +527,7 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreTransition( ...@@ -515,12 +527,7 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreTransition(
} }
__ bind(&miss); __ bind(&miss);
if (vector_and_slot_on_stack) { if (need_save_restore) {
// Prepare for calling miss builtin with StoreWithVectorDescriptor.
PopReturnAddress(this->name());
PopVectorAndSlot();
PushReturnAddress(this->name());
} else {
PopVectorAndSlot(); PopVectorAndSlot();
} }
GenerateRestoreName(name); GenerateRestoreName(name);
...@@ -542,7 +549,7 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreField(LookupIterator* it) { ...@@ -542,7 +549,7 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreField(LookupIterator* it) {
FieldType* field_type = *it->GetFieldType(); FieldType* field_type = *it->GetFieldType();
bool need_save_restore = false; bool need_save_restore = false;
if (RequiresFieldTypeChecks(field_type)) { if (RequiresFieldTypeChecks(field_type)) {
need_save_restore = IC::ICUseVector(kind()); need_save_restore = IC::ShouldPushPopSlotAndVector(kind());
if (need_save_restore) PushVectorAndSlot(); if (need_save_restore) PushVectorAndSlot();
GenerateFieldTypeChecks(field_type, value(), &miss); GenerateFieldTypeChecks(field_type, value(), &miss);
if (need_save_restore) PopVectorAndSlot(); if (need_save_restore) PopVectorAndSlot();
......
...@@ -165,6 +165,13 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall( ...@@ -165,6 +165,13 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
DCHECK(!accessor_holder.is(scratch)); DCHECK(!accessor_holder.is(scratch));
// Copy return value. // Copy return value.
__ pop(scratch); __ pop(scratch);
if (is_store) {
// Discard stack arguments.
__ add(esp, Immediate(StoreWithVectorDescriptor::kStackArgumentsCount *
kPointerSize));
}
// receiver // receiver
__ push(receiver); __ push(receiver);
// Write the arguments to stack frame. // Write the arguments to stack frame.
...@@ -305,7 +312,14 @@ void NamedStoreHandlerCompiler::GenerateStoreViaSetter( ...@@ -305,7 +312,14 @@ void NamedStoreHandlerCompiler::GenerateStoreViaSetter(
// Restore context register. // Restore context register.
__ pop(esi); __ pop(esi);
} }
if (accessor_index >= 0) {
__ ret(StoreWithVectorDescriptor::kStackArgumentsCount * kPointerSize);
} else {
// If we generate a global code snippet for deoptimization only, don't try
// to drop stack arguments for the StoreIC because they are not a part of
// expression stack and deoptimizer does not reconstruct them.
__ ret(0); __ ret(0);
}
} }
...@@ -508,7 +522,7 @@ void NamedLoadHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) { ...@@ -508,7 +522,7 @@ void NamedLoadHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) {
Label success; Label success;
__ jmp(&success); __ jmp(&success);
__ bind(miss); __ bind(miss);
if (IC::ICUseVector(kind())) { if (IC::ShouldPushPopSlotAndVector(kind())) {
DCHECK(kind() == Code::LOAD_IC); DCHECK(kind() == Code::LOAD_IC);
PopVectorAndSlot(); PopVectorAndSlot();
} }
...@@ -523,7 +537,7 @@ void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) { ...@@ -523,7 +537,7 @@ void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) {
Label success; Label success;
__ jmp(&success); __ jmp(&success);
GenerateRestoreName(miss, name); GenerateRestoreName(miss, name);
if (IC::ICUseVector(kind())) PopVectorAndSlot(); DCHECK(!IC::ShouldPushPopSlotAndVector(kind()));
TailCallBuiltin(masm(), MissBuiltin(kind())); TailCallBuiltin(masm(), MissBuiltin(kind()));
__ bind(&success); __ bind(&success);
} }
...@@ -624,6 +638,9 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback( ...@@ -624,6 +638,9 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
Register holder_reg = Frontend(name); Register holder_reg = Frontend(name);
__ pop(scratch1()); // remove the return address __ pop(scratch1()); // remove the return address
// Discard stack arguments.
__ add(esp, Immediate(StoreWithVectorDescriptor::kStackArgumentsCount *
kPointerSize));
__ push(receiver()); __ push(receiver());
__ push(holder_reg); __ push(holder_reg);
// If the callback cannot leak, then push the callback directly, // If the callback cannot leak, then push the callback directly,
...@@ -655,7 +672,7 @@ Register NamedStoreHandlerCompiler::value() { ...@@ -655,7 +672,7 @@ Register NamedStoreHandlerCompiler::value() {
Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal( Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal(
Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) { Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) {
Label miss; Label miss;
if (IC::ICUseVector(kind())) { if (IC::ShouldPushPopSlotAndVector(kind())) {
PushVectorAndSlot(); PushVectorAndSlot();
} }
FrontendHeader(receiver(), name, &miss, DONT_RETURN_ANYTHING); FrontendHeader(receiver(), name, &miss, DONT_RETURN_ANYTHING);
...@@ -677,7 +694,7 @@ Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal( ...@@ -677,7 +694,7 @@ Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal(
Counters* counters = isolate()->counters(); Counters* counters = isolate()->counters();
__ IncrementCounter(counters->ic_named_load_global_stub(), 1); __ IncrementCounter(counters->ic_named_load_global_stub(), 1);
// The code above already loads the result into the return register. // The code above already loads the result into the return register.
if (IC::ICUseVector(kind())) { if (IC::ShouldPushPopSlotAndVector(kind())) {
DiscardVectorAndSlot(); DiscardVectorAndSlot();
} }
__ ret(0); __ ret(0);
......
...@@ -15,14 +15,17 @@ namespace internal { ...@@ -15,14 +15,17 @@ namespace internal {
void PropertyICCompiler::GenerateRuntimeSetProperty( void PropertyICCompiler::GenerateRuntimeSetProperty(
MacroAssembler* masm, LanguageMode language_mode) { MacroAssembler* masm, LanguageMode language_mode) {
// Return address is on the stack. STATIC_ASSERT(StoreWithVectorDescriptor::kStackArgumentsCount == 3);
DCHECK(!ebx.is(StoreDescriptor::ReceiverRegister()) && // Current stack layout:
!ebx.is(StoreDescriptor::NameRegister()) && // - esp[12] -- value
!ebx.is(StoreDescriptor::ValueRegister())); // - esp[8] -- slot
// - esp[4] -- vector
// - esp[0] -- return address
__ mov(Operand(esp, 12), StoreDescriptor::ReceiverRegister());
__ mov(Operand(esp, 8), StoreDescriptor::NameRegister());
__ mov(Operand(esp, 4), StoreDescriptor::ValueRegister());
__ pop(ebx); __ pop(ebx);
__ push(StoreDescriptor::ReceiverRegister());
__ push(StoreDescriptor::NameRegister());
__ push(StoreDescriptor::ValueRegister());
__ push(Immediate(Smi::FromInt(language_mode))); __ push(Immediate(Smi::FromInt(language_mode)));
__ push(ebx); // return address __ push(ebx); // return address
......
...@@ -409,7 +409,7 @@ static void KeyedStoreGenerateMegamorphicHelper( ...@@ -409,7 +409,7 @@ static void KeyedStoreGenerateMegamorphicHelper(
} }
// It's irrelevant whether array is smi-only or not when writing a smi. // It's irrelevant whether array is smi-only or not when writing a smi.
__ mov(FixedArrayElementOperand(ebx, key), value); __ mov(FixedArrayElementOperand(ebx, key), value);
__ ret(0); __ ret(StoreWithVectorDescriptor::kStackArgumentsCount * kPointerSize);
__ bind(&non_smi_value); __ bind(&non_smi_value);
// Escape to elements kind transition case. // Escape to elements kind transition case.
...@@ -428,7 +428,7 @@ static void KeyedStoreGenerateMegamorphicHelper( ...@@ -428,7 +428,7 @@ static void KeyedStoreGenerateMegamorphicHelper(
__ mov(edx, value); // Preserve the value which is returned. __ mov(edx, value); // Preserve the value which is returned.
__ RecordWriteArray(ebx, edx, key, kDontSaveFPRegs, EMIT_REMEMBERED_SET, __ RecordWriteArray(ebx, edx, key, kDontSaveFPRegs, EMIT_REMEMBERED_SET,
OMIT_SMI_CHECK); OMIT_SMI_CHECK);
__ ret(0); __ ret(StoreWithVectorDescriptor::kStackArgumentsCount * kPointerSize);
__ bind(fast_double); __ bind(fast_double);
if (check_map == kCheckMap) { if (check_map == kCheckMap) {
...@@ -457,7 +457,7 @@ static void KeyedStoreGenerateMegamorphicHelper( ...@@ -457,7 +457,7 @@ static void KeyedStoreGenerateMegamorphicHelper(
__ add(FieldOperand(receiver, JSArray::kLengthOffset), __ add(FieldOperand(receiver, JSArray::kLengthOffset),
Immediate(Smi::FromInt(1))); Immediate(Smi::FromInt(1)));
} }
__ ret(0); __ ret(StoreWithVectorDescriptor::kStackArgumentsCount * kPointerSize);
__ bind(&transition_smi_elements); __ bind(&transition_smi_elements);
__ mov(ebx, FieldOperand(receiver, HeapObject::kMapOffset)); __ mov(ebx, FieldOperand(receiver, HeapObject::kMapOffset));
...@@ -705,18 +705,21 @@ void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { ...@@ -705,18 +705,21 @@ void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
} }
static void StoreIC_PushArgs(MacroAssembler* masm) { static void StoreIC_PushArgs(MacroAssembler* masm) {
Register receiver = StoreDescriptor::ReceiverRegister(); Register receiver = StoreWithVectorDescriptor::ReceiverRegister();
Register name = StoreDescriptor::NameRegister(); Register name = StoreWithVectorDescriptor::NameRegister();
Register value = StoreDescriptor::ValueRegister();
Register slot = StoreWithVectorDescriptor::SlotRegister(); STATIC_ASSERT(StoreWithVectorDescriptor::kStackArgumentsCount == 3);
Register vector = StoreWithVectorDescriptor::VectorRegister(); // Current stack layout:
// - esp[12] -- value
__ xchg(value, Operand(esp, 0)); // - esp[8] -- slot
__ push(slot); // - esp[4] -- vector
__ push(vector); // - esp[0] -- return address
Register return_address = StoreWithVectorDescriptor::SlotRegister();
__ pop(return_address);
__ push(receiver); __ push(receiver);
__ push(name); __ push(name);
__ push(value); // Contains the return address. __ push(return_address);
} }
...@@ -751,7 +754,7 @@ void StoreIC::GenerateNormal(MacroAssembler* masm) { ...@@ -751,7 +754,7 @@ void StoreIC::GenerateNormal(MacroAssembler* masm) {
__ Drop(3); __ Drop(3);
Counters* counters = masm->isolate()->counters(); Counters* counters = masm->isolate()->counters();
__ IncrementCounter(counters->ic_store_normal_hit(), 1); __ IncrementCounter(counters->ic_store_normal_hit(), 1);
__ ret(0); __ ret(StoreWithVectorDescriptor::kStackArgumentsCount * kPointerSize);
__ bind(&restore_miss); __ bind(&restore_miss);
__ pop(slot); __ pop(slot);
......
...@@ -183,6 +183,19 @@ IC::IC(FrameDepth depth, Isolate* isolate, FeedbackNexus* nexus) ...@@ -183,6 +183,19 @@ IC::IC(FrameDepth depth, Isolate* isolate, FeedbackNexus* nexus)
extra_ic_state_ = target->extra_ic_state(); extra_ic_state_ = target->extra_ic_state();
} }
// The ICs that don't pass slot and vector through the stack have to
// save/restore them in the dispatcher.
bool IC::ShouldPushPopSlotAndVector(Code::Kind kind) {
if (kind == Code::LOAD_IC || kind == Code::LOAD_GLOBAL_IC ||
kind == Code::KEYED_LOAD_IC || kind == Code::CALL_IC) {
return true;
}
if (kind == Code::STORE_IC || kind == Code::KEYED_STORE_IC) {
return !StoreWithVectorDescriptor::kPassLastArgsOnStack;
}
return false;
}
InlineCacheState IC::StateFromCode(Code* code) { InlineCacheState IC::StateFromCode(Code* code) {
Isolate* isolate = code->GetIsolate(); Isolate* isolate = code->GetIsolate();
switch (code->kind()) { switch (code->kind()) {
......
...@@ -75,6 +75,10 @@ class IC { ...@@ -75,6 +75,10 @@ class IC {
kind == Code::STORE_IC || kind == Code::KEYED_STORE_IC; kind == Code::STORE_IC || kind == Code::KEYED_STORE_IC;
} }
// The ICs that don't pass slot and vector through the stack have to
// save/restore them in the dispatcher.
static bool ShouldPushPopSlotAndVector(Code::Kind kind);
static InlineCacheState StateFromCode(Code* code); static InlineCacheState StateFromCode(Code* code);
protected: protected:
......
...@@ -165,6 +165,13 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall( ...@@ -165,6 +165,13 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
DCHECK(!accessor_holder.is(scratch)); DCHECK(!accessor_holder.is(scratch));
// Copy return value. // Copy return value.
__ pop(scratch); __ pop(scratch);
if (is_store) {
// Discard stack arguments.
__ add(esp, Immediate(StoreWithVectorDescriptor::kStackArgumentsCount *
kPointerSize));
}
// receiver // receiver
__ push(receiver); __ push(receiver);
// Write the arguments to stack frame. // Write the arguments to stack frame.
...@@ -305,7 +312,14 @@ void NamedStoreHandlerCompiler::GenerateStoreViaSetter( ...@@ -305,7 +312,14 @@ void NamedStoreHandlerCompiler::GenerateStoreViaSetter(
// Restore context register. // Restore context register.
__ pop(esi); __ pop(esi);
} }
if (accessor_index >= 0) {
__ ret(StoreWithVectorDescriptor::kStackArgumentsCount * kPointerSize);
} else {
// If we generate a global code snippet for deoptimization only, don't try
// to drop stack arguments for the StoreIC because they are not a part of
// expression stack and deoptimizer does not reconstruct them.
__ ret(0); __ ret(0);
}
} }
...@@ -508,7 +522,7 @@ void NamedLoadHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) { ...@@ -508,7 +522,7 @@ void NamedLoadHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) {
Label success; Label success;
__ jmp(&success); __ jmp(&success);
__ bind(miss); __ bind(miss);
if (IC::ICUseVector(kind())) { if (IC::ShouldPushPopSlotAndVector(kind())) {
DCHECK(kind() == Code::LOAD_IC); DCHECK(kind() == Code::LOAD_IC);
PopVectorAndSlot(); PopVectorAndSlot();
} }
...@@ -523,7 +537,7 @@ void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) { ...@@ -523,7 +537,7 @@ void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) {
Label success; Label success;
__ jmp(&success); __ jmp(&success);
GenerateRestoreName(miss, name); GenerateRestoreName(miss, name);
if (IC::ICUseVector(kind())) PopVectorAndSlot(); DCHECK(!IC::ShouldPushPopSlotAndVector(kind()));
TailCallBuiltin(masm(), MissBuiltin(kind())); TailCallBuiltin(masm(), MissBuiltin(kind()));
__ bind(&success); __ bind(&success);
} }
...@@ -624,6 +638,9 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback( ...@@ -624,6 +638,9 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
Register holder_reg = Frontend(name); Register holder_reg = Frontend(name);
__ pop(scratch1()); // remove the return address __ pop(scratch1()); // remove the return address
// Discard stack arguments.
__ add(esp, Immediate(StoreWithVectorDescriptor::kStackArgumentsCount *
kPointerSize));
__ push(receiver()); __ push(receiver());
__ push(holder_reg); __ push(holder_reg);
// If the callback cannot leak, then push the callback directly, // If the callback cannot leak, then push the callback directly,
...@@ -655,7 +672,7 @@ Register NamedStoreHandlerCompiler::value() { ...@@ -655,7 +672,7 @@ Register NamedStoreHandlerCompiler::value() {
Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal( Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal(
Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) { Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) {
Label miss; Label miss;
if (IC::ICUseVector(kind())) { if (IC::ShouldPushPopSlotAndVector(kind())) {
PushVectorAndSlot(); PushVectorAndSlot();
} }
FrontendHeader(receiver(), name, &miss, DONT_RETURN_ANYTHING); FrontendHeader(receiver(), name, &miss, DONT_RETURN_ANYTHING);
...@@ -677,7 +694,7 @@ Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal( ...@@ -677,7 +694,7 @@ Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal(
Counters* counters = isolate()->counters(); Counters* counters = isolate()->counters();
__ IncrementCounter(counters->ic_named_load_global_stub(), 1); __ IncrementCounter(counters->ic_named_load_global_stub(), 1);
// The code above already loads the result into the return register. // The code above already loads the result into the return register.
if (IC::ICUseVector(kind())) { if (IC::ShouldPushPopSlotAndVector(kind())) {
DiscardVectorAndSlot(); DiscardVectorAndSlot();
} }
__ ret(0); __ ret(0);
......
...@@ -15,14 +15,17 @@ namespace internal { ...@@ -15,14 +15,17 @@ namespace internal {
void PropertyICCompiler::GenerateRuntimeSetProperty( void PropertyICCompiler::GenerateRuntimeSetProperty(
MacroAssembler* masm, LanguageMode language_mode) { MacroAssembler* masm, LanguageMode language_mode) {
// Return address is on the stack. STATIC_ASSERT(StoreWithVectorDescriptor::kStackArgumentsCount == 3);
DCHECK(!ebx.is(StoreDescriptor::ReceiverRegister()) && // Current stack layout:
!ebx.is(StoreDescriptor::NameRegister()) && // - esp[12] -- value
!ebx.is(StoreDescriptor::ValueRegister())); // - esp[8] -- slot
// - esp[4] -- vector
// - esp[0] -- return address
__ mov(Operand(esp, 12), StoreDescriptor::ReceiverRegister());
__ mov(Operand(esp, 8), StoreDescriptor::NameRegister());
__ mov(Operand(esp, 4), StoreDescriptor::ValueRegister());
__ pop(ebx); __ pop(ebx);
__ push(StoreDescriptor::ReceiverRegister());
__ push(StoreDescriptor::NameRegister());
__ push(StoreDescriptor::ValueRegister());
__ push(Immediate(Smi::FromInt(language_mode))); __ push(Immediate(Smi::FromInt(language_mode)));
__ push(ebx); // return address __ push(ebx); // return address
......
...@@ -409,7 +409,7 @@ static void KeyedStoreGenerateMegamorphicHelper( ...@@ -409,7 +409,7 @@ static void KeyedStoreGenerateMegamorphicHelper(
} }
// It's irrelevant whether array is smi-only or not when writing a smi. // It's irrelevant whether array is smi-only or not when writing a smi.
__ mov(FixedArrayElementOperand(ebx, key), value); __ mov(FixedArrayElementOperand(ebx, key), value);
__ ret(0); __ ret(StoreWithVectorDescriptor::kStackArgumentsCount * kPointerSize);
__ bind(&non_smi_value); __ bind(&non_smi_value);
// Escape to elements kind transition case. // Escape to elements kind transition case.
...@@ -428,7 +428,7 @@ static void KeyedStoreGenerateMegamorphicHelper( ...@@ -428,7 +428,7 @@ static void KeyedStoreGenerateMegamorphicHelper(
__ mov(edx, value); // Preserve the value which is returned. __ mov(edx, value); // Preserve the value which is returned.
__ RecordWriteArray(ebx, edx, key, kDontSaveFPRegs, EMIT_REMEMBERED_SET, __ RecordWriteArray(ebx, edx, key, kDontSaveFPRegs, EMIT_REMEMBERED_SET,
OMIT_SMI_CHECK); OMIT_SMI_CHECK);
__ ret(0); __ ret(StoreWithVectorDescriptor::kStackArgumentsCount * kPointerSize);
__ bind(fast_double); __ bind(fast_double);
if (check_map == kCheckMap) { if (check_map == kCheckMap) {
...@@ -457,7 +457,7 @@ static void KeyedStoreGenerateMegamorphicHelper( ...@@ -457,7 +457,7 @@ static void KeyedStoreGenerateMegamorphicHelper(
__ add(FieldOperand(receiver, JSArray::kLengthOffset), __ add(FieldOperand(receiver, JSArray::kLengthOffset),
Immediate(Smi::FromInt(1))); Immediate(Smi::FromInt(1)));
} }
__ ret(0); __ ret(StoreWithVectorDescriptor::kStackArgumentsCount * kPointerSize);
__ bind(&transition_smi_elements); __ bind(&transition_smi_elements);
__ mov(ebx, FieldOperand(receiver, HeapObject::kMapOffset)); __ mov(ebx, FieldOperand(receiver, HeapObject::kMapOffset));
...@@ -705,18 +705,21 @@ void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { ...@@ -705,18 +705,21 @@ void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
} }
static void StoreIC_PushArgs(MacroAssembler* masm) { static void StoreIC_PushArgs(MacroAssembler* masm) {
Register receiver = StoreDescriptor::ReceiverRegister(); Register receiver = StoreWithVectorDescriptor::ReceiverRegister();
Register name = StoreDescriptor::NameRegister(); Register name = StoreWithVectorDescriptor::NameRegister();
Register value = StoreDescriptor::ValueRegister();
Register slot = StoreWithVectorDescriptor::SlotRegister(); STATIC_ASSERT(StoreWithVectorDescriptor::kStackArgumentsCount == 3);
Register vector = StoreWithVectorDescriptor::VectorRegister(); // Current stack layout:
// - esp[12] -- value
__ xchg(value, Operand(esp, 0)); // - esp[8] -- slot
__ push(slot); // - esp[4] -- vector
__ push(vector); // - esp[0] -- return address
Register return_address = StoreWithVectorDescriptor::SlotRegister();
__ pop(return_address);
__ push(receiver); __ push(receiver);
__ push(name); __ push(name);
__ push(value); // Contains the return address. __ push(return_address);
} }
...@@ -751,7 +754,7 @@ void StoreIC::GenerateNormal(MacroAssembler* masm) { ...@@ -751,7 +754,7 @@ void StoreIC::GenerateNormal(MacroAssembler* masm) {
__ Drop(3); __ Drop(3);
Counters* counters = masm->isolate()->counters(); Counters* counters = masm->isolate()->counters();
__ IncrementCounter(counters->ic_store_normal_hit(), 1); __ IncrementCounter(counters->ic_store_normal_hit(), 1);
__ ret(0); __ ret(StoreWithVectorDescriptor::kStackArgumentsCount * kPointerSize);
__ bind(&restore_miss); __ bind(&restore_miss);
__ pop(slot); __ pop(slot);
......
...@@ -134,15 +134,9 @@ void StoreDescriptor::InitializePlatformSpecific( ...@@ -134,15 +134,9 @@ void StoreDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
Register registers[] = {ReceiverRegister(), NameRegister(), ValueRegister(), Register registers[] = {ReceiverRegister(), NameRegister(), ValueRegister(),
SlotRegister()}; SlotRegister()};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
bool StoreTransitionDescriptor::PassVectorAndSlotOnStack() { int len = arraysize(registers) - kStackArgumentsCount;
#if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X87 data->InitializePlatformSpecific(len, registers);
return true;
#else
return false;
#endif
} }
void StoreTransitionDescriptor::InitializePlatformSpecific( void StoreTransitionDescriptor::InitializePlatformSpecific(
...@@ -151,11 +145,7 @@ void StoreTransitionDescriptor::InitializePlatformSpecific( ...@@ -151,11 +145,7 @@ void StoreTransitionDescriptor::InitializePlatformSpecific(
ReceiverRegister(), NameRegister(), MapRegister(), ReceiverRegister(), NameRegister(), MapRegister(),
ValueRegister(), SlotRegister(), VectorRegister(), ValueRegister(), SlotRegister(), VectorRegister(),
}; };
int len = arraysize(registers); int len = arraysize(registers) - kStackArgumentsCount;
if (PassVectorAndSlotOnStack()) {
// Pass slot and vector on the stack.
len -= 2;
}
data->InitializePlatformSpecific(len, registers); data->InitializePlatformSpecific(len, registers);
} }
...@@ -243,7 +233,8 @@ void StoreWithVectorDescriptor::InitializePlatformSpecific( ...@@ -243,7 +233,8 @@ void StoreWithVectorDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
Register registers[] = {ReceiverRegister(), NameRegister(), ValueRegister(), Register registers[] = {ReceiverRegister(), NameRegister(), ValueRegister(),
SlotRegister(), VectorRegister()}; SlotRegister(), VectorRegister()};
data->InitializePlatformSpecific(arraysize(registers), registers); int len = arraysize(registers) - kStackArgumentsCount;
data->InitializePlatformSpecific(len, registers);
} }
void BinaryOpWithVectorDescriptor::InitializePlatformIndependent( void BinaryOpWithVectorDescriptor::InitializePlatformIndependent(
......
...@@ -324,6 +324,15 @@ class StoreDescriptor : public CallInterfaceDescriptor { ...@@ -324,6 +324,15 @@ class StoreDescriptor : public CallInterfaceDescriptor {
static const Register NameRegister(); static const Register NameRegister();
static const Register ValueRegister(); static const Register ValueRegister();
static const Register SlotRegister(); static const Register SlotRegister();
#if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X87
static const bool kPassLastArgsOnStack = true;
#else
static const bool kPassLastArgsOnStack = false;
#endif
// Pass value and slot through the stack.
static const int kStackArgumentsCount = kPassLastArgsOnStack ? 2 : 0;
}; };
class StoreTransitionDescriptor : public StoreDescriptor { class StoreTransitionDescriptor : public StoreDescriptor {
...@@ -336,7 +345,8 @@ class StoreTransitionDescriptor : public StoreDescriptor { ...@@ -336,7 +345,8 @@ class StoreTransitionDescriptor : public StoreDescriptor {
static const Register SlotRegister(); static const Register SlotRegister();
static const Register VectorRegister(); static const Register VectorRegister();
static bool PassVectorAndSlotOnStack(); // Pass value, slot and vector through the stack.
static const int kStackArgumentsCount = kPassLastArgsOnStack ? 3 : 0;
}; };
class StoreWithVectorDescriptor : public StoreDescriptor { class StoreWithVectorDescriptor : public StoreDescriptor {
...@@ -346,6 +356,9 @@ class StoreWithVectorDescriptor : public StoreDescriptor { ...@@ -346,6 +356,9 @@ class StoreWithVectorDescriptor : public StoreDescriptor {
StoreDescriptor) StoreDescriptor)
static const Register VectorRegister(); static const Register VectorRegister();
// Pass value, slot and vector through the stack.
static const int kStackArgumentsCount = kPassLastArgsOnStack ? 3 : 0;
}; };
class LoadWithVectorDescriptor : public LoadDescriptor { class LoadWithVectorDescriptor : public LoadDescriptor {
......
...@@ -3483,6 +3483,28 @@ void StoreICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) { ...@@ -3483,6 +3483,28 @@ void StoreICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) {
Register slot = StoreWithVectorDescriptor::SlotRegister(); // edi Register slot = StoreWithVectorDescriptor::SlotRegister(); // edi
Label miss; Label miss;
if (StoreWithVectorDescriptor::kPassLastArgsOnStack) {
// Current stack layout:
// - esp[8] -- value
// - esp[4] -- slot
// - esp[0] -- return address
STATIC_ASSERT(StoreDescriptor::kStackArgumentsCount == 2);
STATIC_ASSERT(StoreWithVectorDescriptor::kStackArgumentsCount == 3);
if (in_frame) {
__ RecordComment("[ StoreDescriptor -> StoreWithVectorDescriptor");
// If the vector is not on the stack, then insert the vector beneath
// return address in order to prepare for calling handler with
// StoreWithVector calling convention.
__ push(Operand(esp, 0));
__ mov(Operand(esp, 4), StoreWithVectorDescriptor::VectorRegister());
__ RecordComment("]");
} else {
__ mov(vector, Operand(esp, 1 * kPointerSize));
}
__ mov(slot, Operand(esp, 2 * kPointerSize));
__ mov(value, Operand(esp, 3 * kPointerSize));
}
__ push(value); __ push(value);
Register scratch = value; Register scratch = value;
...@@ -3624,12 +3646,23 @@ static void HandlePolymorphicKeyedStoreCase(MacroAssembler* masm, ...@@ -3624,12 +3646,23 @@ static void HandlePolymorphicKeyedStoreCase(MacroAssembler* masm,
__ pop(vector); __ pop(vector);
__ pop(receiver); __ pop(receiver);
__ pop(value); __ pop(value);
{ // Ensure that the transition handler we are going to call has the same
// Put vector and slot beneath return address. // number of stack arguments which means that we don't have to adapt them
__ push(vector); // before the call.
__ push(Operand(esp, 1 * kPointerSize)); // push return address STATIC_ASSERT(StoreWithVectorDescriptor::kStackArgumentsCount == 3);
__ mov(Operand(esp, 2 * kPointerSize), slot); STATIC_ASSERT(StoreTransitionDescriptor::kStackArgumentsCount == 3);
} STATIC_ASSERT(StoreWithVectorDescriptor::kParameterCount -
StoreWithVectorDescriptor::kValue ==
StoreTransitionDescriptor::kParameterCount -
StoreTransitionDescriptor::kValue);
STATIC_ASSERT(StoreWithVectorDescriptor::kParameterCount -
StoreWithVectorDescriptor::kSlot ==
StoreTransitionDescriptor::kParameterCount -
StoreTransitionDescriptor::kSlot);
STATIC_ASSERT(StoreWithVectorDescriptor::kParameterCount -
StoreWithVectorDescriptor::kVector ==
StoreTransitionDescriptor::kParameterCount -
StoreTransitionDescriptor::kVector);
__ jmp(Operand::StaticVariable(virtual_register)); __ jmp(Operand::StaticVariable(virtual_register));
__ bind(&prepare_next); __ bind(&prepare_next);
...@@ -3657,6 +3690,28 @@ void KeyedStoreICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) { ...@@ -3657,6 +3690,28 @@ void KeyedStoreICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) {
Register slot = StoreWithVectorDescriptor::SlotRegister(); // edi Register slot = StoreWithVectorDescriptor::SlotRegister(); // edi
Label miss; Label miss;
if (StoreWithVectorDescriptor::kPassLastArgsOnStack) {
// Current stack layout:
// - esp[8] -- value
// - esp[4] -- slot
// - esp[0] -- return address
STATIC_ASSERT(StoreDescriptor::kStackArgumentsCount == 2);
STATIC_ASSERT(StoreWithVectorDescriptor::kStackArgumentsCount == 3);
if (in_frame) {
__ RecordComment("[ StoreDescriptor -> StoreWithVectorDescriptor");
// If the vector is not on the stack, then insert the vector beneath
// return address in order to prepare for calling handler with
// StoreWithVector calling convention.
__ push(Operand(esp, 0));
__ mov(Operand(esp, 4), StoreWithVectorDescriptor::VectorRegister());
__ RecordComment("]");
} else {
__ mov(vector, Operand(esp, 1 * kPointerSize));
}
__ mov(slot, Operand(esp, 2 * kPointerSize));
__ mov(value, Operand(esp, 3 * kPointerSize));
}
__ push(value); __ push(value);
Register scratch = value; Register scratch = 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