Commit 562047df authored by zhengxing.li's avatar zhengxing.li Committed by Commit bot

X87: Vector ICs: Get rid of stack arguments on ia32 transitioning stores.

    port 2d4aeaad (r31204).

    original commit message:
    The stack manipulation was expensive. Two virtual registers are better.

BUG=

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

Cr-Commit-Position: refs/heads/master@{#31504}
parent b64c1f02
......@@ -362,18 +362,16 @@ void NamedStoreHandlerCompiler::GenerateRestoreName(Handle<Name> name) {
}
void NamedStoreHandlerCompiler::GeneratePushMap(Register map_reg,
Register scratch) {
// current after GeneratePushMap
// -------------------------------------------------
// ret addr slot
// vector vector
// sp -> slot map
// sp -> ret addr
//
__ xchg(map_reg, Operand(esp, 0));
__ xchg(map_reg, Operand(esp, 2 * kPointerSize));
__ push(map_reg);
void NamedStoreHandlerCompiler::RearrangeVectorAndSlot(
Register current_map, Register destination_map) {
DCHECK(destination_map.is(StoreTransitionHelper::MapRegister()));
DCHECK(current_map.is(StoreTransitionHelper::VectorRegister()));
ExternalReference virtual_slot =
ExternalReference::virtual_slot_register(isolate());
__ mov(destination_map, current_map);
__ pop(current_map);
__ mov(Operand::StaticVariable(virtual_slot), current_map);
__ pop(current_map); // put vector in place.
}
......
......@@ -24,7 +24,7 @@ static void ProbeTable(Isolate* isolate, MacroAssembler* masm,
ExternalReference value_offset(isolate->stub_cache()->value_reference(table));
ExternalReference map_offset(isolate->stub_cache()->map_reference(table));
ExternalReference virtual_register =
ExternalReference::vector_store_virtual_register(masm->isolate());
ExternalReference::virtual_handler_register(masm->isolate());
Label miss;
bool is_vector_store =
......
......@@ -4260,7 +4260,7 @@ static void HandlePolymorphicStoreCase(MacroAssembler* masm, Register receiver,
Label start_polymorphic;
Label pop_and_miss;
ExternalReference virtual_register =
ExternalReference::vector_store_virtual_register(masm->isolate());
ExternalReference::virtual_handler_register(masm->isolate());
__ push(receiver);
__ push(vector);
......@@ -4344,7 +4344,7 @@ static void HandleMonomorphicStoreCase(MacroAssembler* masm, Register receiver,
// The store ic value is on the stack.
DCHECK(weak_cell.is(VectorStoreICDescriptor::ValueRegister()));
ExternalReference virtual_register =
ExternalReference::vector_store_virtual_register(masm->isolate());
ExternalReference::virtual_handler_register(masm->isolate());
// feedback initially contains the feedback array
Label compare_smi_map;
......@@ -4452,13 +4452,16 @@ static void HandlePolymorphicKeyedStoreCase(MacroAssembler* masm,
Label transition_call;
Label pop_and_miss;
ExternalReference virtual_register =
ExternalReference::vector_store_virtual_register(masm->isolate());
ExternalReference::virtual_handler_register(masm->isolate());
ExternalReference virtual_slot =
ExternalReference::virtual_slot_register(masm->isolate());
__ push(receiver);
__ push(vector);
Register receiver_map = receiver;
Register cached_map = vector;
Register value = StoreDescriptor::ValueRegister();
// Receiver might not be a heap object.
__ JumpIfSmi(receiver, &load_smi_map);
......@@ -4467,11 +4470,17 @@ static void HandlePolymorphicKeyedStoreCase(MacroAssembler* masm,
// Polymorphic, we have to loop from 0 to N - 1
__ push(key);
// On the stack we have:
// key (esp)
// vector
// receiver
// value
// Current stack layout:
// - esp[0] -- key
// - esp[4] -- vector
// - esp[8] -- receiver
// - esp[12] -- value
// - esp[16] -- return address
//
// Required stack layout for handler call:
// - esp[0] -- return address
// - receiver, key, value, vector, slot in registers.
// - handler in virtual register.
Register counter = key;
__ mov(counter, Immediate(Smi::FromInt(0)));
__ bind(&next_loop);
......@@ -4490,32 +4499,39 @@ static void HandlePolymorphicKeyedStoreCase(MacroAssembler* masm,
__ pop(receiver);
__ lea(feedback, FieldOperand(feedback, Code::kHeaderSize));
__ mov(Operand::StaticVariable(virtual_register), feedback);
__ pop(feedback); // Pop "value".
__ pop(value);
__ jmp(Operand::StaticVariable(virtual_register));
__ bind(&transition_call);
// Oh holy hell this will be tough.
// The map goes in vector register.
__ mov(receiver, FieldOperand(cached_map, WeakCell::kValueOffset));
// The weak cell may have been cleared.
__ JumpIfSmi(receiver, &pop_and_miss);
// slot goes on the stack, and holds return address.
__ xchg(slot, Operand(esp, 4 * kPointerSize));
// Get the handler in value.
// Current stack layout:
// - esp[0] -- key
// - esp[4] -- vector
// - esp[8] -- receiver
// - esp[12] -- value
// - esp[16] -- return address
//
// Required stack layout for handler call:
// - esp[0] -- return address
// - receiver, key, value, map, vector in registers.
// - handler and slot in virtual registers.
__ mov(Operand::StaticVariable(virtual_slot), slot);
__ mov(feedback, FieldOperand(feedback, counter, times_half_pointer_size,
FixedArray::kHeaderSize + 2 * kPointerSize));
__ lea(feedback, FieldOperand(feedback, Code::kHeaderSize));
__ mov(Operand::StaticVariable(virtual_register), feedback);
__ mov(cached_map, FieldOperand(cached_map, WeakCell::kValueOffset));
// The weak cell may have been cleared.
__ JumpIfSmi(cached_map, &pop_and_miss);
DCHECK(!cached_map.is(VectorStoreTransitionDescriptor::MapRegister()));
__ mov(VectorStoreTransitionDescriptor::MapRegister(), cached_map);
// Pop key into place.
__ pop(key);
// Put the return address on top of stack, vector goes in slot.
__ xchg(slot, Operand(esp, 0));
// put the map on the stack, receiver holds receiver.
__ xchg(receiver, Operand(esp, 1 * kPointerSize));
// put the vector on the stack, slot holds value.
__ xchg(slot, Operand(esp, 2 * kPointerSize));
// feedback (value) = value, slot = handler.
__ xchg(feedback, slot);
__ jmp(slot);
__ pop(vector);
__ pop(receiver);
__ pop(value);
__ jmp(Operand::StaticVariable(virtual_register));
__ bind(&prepare_next);
__ add(counter, Immediate(Smi::FromInt(3)));
......
......@@ -35,12 +35,10 @@ const Register VectorStoreTransitionDescriptor::SlotRegister() {
}
const Register VectorStoreTransitionDescriptor::VectorRegister() {
return no_reg;
}
const Register VectorStoreTransitionDescriptor::VectorRegister() { return ebx; }
const Register VectorStoreTransitionDescriptor::MapRegister() { return no_reg; }
const Register VectorStoreTransitionDescriptor::MapRegister() { return edi; }
const Register StoreTransitionDescriptor::MapRegister() { return ebx; }
......@@ -85,14 +83,6 @@ const Register GrowArrayElementsDescriptor::ObjectRegister() { return eax; }
const Register GrowArrayElementsDescriptor::KeyRegister() { return ebx; }
void VectorStoreTransitionDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {ReceiverRegister(), NameRegister(), ValueRegister()};
// The other three parameters are on the stack in ia32.
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void FastNewClosureDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {ebx};
......
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