X87: Vector ICs: Get rid of stack arguments on ia32 transitioning stores.
port 2d4aeaad2f
(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}
This commit is contained in:
parent
b64c1f02ad
commit
562047df0f
@ -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};
|
||||
|
Loading…
Reference in New Issue
Block a user