Commit 2d4aeaad authored by mvstanton's avatar mvstanton Committed by Commit bot

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

The stack manipulation was expensive. Two virtual registers are better.

BUG=

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

Cr-Commit-Position: refs/heads/master@{#31204}
parent f7e9094f
...@@ -80,14 +80,6 @@ const Register GrowArrayElementsDescriptor::ObjectRegister() { return r0; } ...@@ -80,14 +80,6 @@ const Register GrowArrayElementsDescriptor::ObjectRegister() { return r0; }
const Register GrowArrayElementsDescriptor::KeyRegister() { return r3; } const Register GrowArrayElementsDescriptor::KeyRegister() { return r3; }
void VectorStoreTransitionDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {ReceiverRegister(), NameRegister(), ValueRegister(),
SlotRegister(), VectorRegister(), MapRegister()};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void FastNewClosureDescriptor::InitializePlatformSpecific( void FastNewClosureDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
Register registers[] = {r2}; Register registers[] = {r2};
......
...@@ -78,14 +78,6 @@ const Register GrowArrayElementsDescriptor::ObjectRegister() { return x0; } ...@@ -78,14 +78,6 @@ const Register GrowArrayElementsDescriptor::ObjectRegister() { return x0; }
const Register GrowArrayElementsDescriptor::KeyRegister() { return x3; } const Register GrowArrayElementsDescriptor::KeyRegister() { return x3; }
void VectorStoreTransitionDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {ReceiverRegister(), NameRegister(), ValueRegister(),
SlotRegister(), VectorRegister(), MapRegister()};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void FastNewClosureDescriptor::InitializePlatformSpecific( void FastNewClosureDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
// x2: function info // x2: function info
......
...@@ -1439,9 +1439,14 @@ ExternalReference ...@@ -1439,9 +1439,14 @@ ExternalReference
} }
ExternalReference ExternalReference::vector_store_virtual_register( ExternalReference ExternalReference::virtual_handler_register(
Isolate* isolate) { Isolate* isolate) {
return ExternalReference(isolate->vector_store_virtual_register_address()); return ExternalReference(isolate->virtual_handler_register_address());
}
ExternalReference ExternalReference::virtual_slot_register(Isolate* isolate) {
return ExternalReference(isolate->virtual_slot_register_address());
} }
......
...@@ -993,7 +993,8 @@ class ExternalReference BASE_EMBEDDED { ...@@ -993,7 +993,8 @@ class ExternalReference BASE_EMBEDDED {
static ExternalReference invoke_function_callback(Isolate* isolate); static ExternalReference invoke_function_callback(Isolate* isolate);
static ExternalReference invoke_accessor_getter_callback(Isolate* isolate); static ExternalReference invoke_accessor_getter_callback(Isolate* isolate);
static ExternalReference vector_store_virtual_register(Isolate* isolate); static ExternalReference virtual_handler_register(Isolate* isolate);
static ExternalReference virtual_slot_register(Isolate* isolate);
static ExternalReference runtime_function_table_address(Isolate* isolate); static ExternalReference runtime_function_table_address(Isolate* isolate);
......
...@@ -1244,8 +1244,10 @@ class StoreTransitionHelper { ...@@ -1244,8 +1244,10 @@ class StoreTransitionHelper {
} }
static Register MapRegister() { static Register MapRegister() {
return FLAG_vector_stores ? VectorStoreTransitionDescriptor::MapRegister() if (FLAG_vector_stores) {
: StoreTransitionDescriptor::MapRegister(); return VectorStoreTransitionDescriptor::MapRegister();
}
return StoreTransitionDescriptor::MapRegister();
} }
static int ReceiverIndex() { static int ReceiverIndex() {
...@@ -1256,26 +1258,25 @@ class StoreTransitionHelper { ...@@ -1256,26 +1258,25 @@ class StoreTransitionHelper {
static int ValueIndex() { return StoreTransitionDescriptor::kValueIndex; } static int ValueIndex() { return StoreTransitionDescriptor::kValueIndex; }
static int SlotIndex() { static int MapIndex() {
DCHECK(FLAG_vector_stores); DCHECK(static_cast<int>(VectorStoreTransitionDescriptor::kMapIndex) ==
return VectorStoreTransitionDescriptor::kSlotIndex; static_cast<int>(StoreTransitionDescriptor::kMapIndex));
return StoreTransitionDescriptor::kMapIndex;
} }
static int VectorIndex() { static int VectorIndex() {
DCHECK(FLAG_vector_stores); DCHECK(FLAG_vector_stores);
if (HasVirtualSlotArg()) {
return VectorStoreTransitionDescriptor::kVirtualSlotVectorIndex;
}
return VectorStoreTransitionDescriptor::kVectorIndex; return VectorStoreTransitionDescriptor::kVectorIndex;
} }
static int MapIndex() { // Some platforms don't have a slot arg.
if (FLAG_vector_stores) { static bool HasVirtualSlotArg() {
return VectorStoreTransitionDescriptor::kMapIndex; if (!FLAG_vector_stores) return false;
} return SlotRegister().is(no_reg);
return StoreTransitionDescriptor::kMapIndex;
} }
// Some platforms push Slot, Vector, Map on the stack instead of in
// registers.
static bool UsesStackArgs() { return MapRegister().is(no_reg); }
}; };
......
...@@ -4579,7 +4579,7 @@ static void HandlePolymorphicStoreCase(MacroAssembler* masm, Register receiver, ...@@ -4579,7 +4579,7 @@ static void HandlePolymorphicStoreCase(MacroAssembler* masm, Register receiver,
Label load_smi_map, compare_map; Label load_smi_map, compare_map;
Label start_polymorphic; Label start_polymorphic;
ExternalReference virtual_register = ExternalReference virtual_register =
ExternalReference::vector_store_virtual_register(masm->isolate()); ExternalReference::virtual_handler_register(masm->isolate());
__ push(receiver); __ push(receiver);
__ push(vector); __ push(vector);
...@@ -4660,7 +4660,7 @@ static void HandleMonomorphicStoreCase(MacroAssembler* masm, Register receiver, ...@@ -4660,7 +4660,7 @@ static void HandleMonomorphicStoreCase(MacroAssembler* masm, Register receiver,
// The store ic value is on the stack. // The store ic value is on the stack.
DCHECK(weak_cell.is(VectorStoreICDescriptor::ValueRegister())); DCHECK(weak_cell.is(VectorStoreICDescriptor::ValueRegister()));
ExternalReference virtual_register = ExternalReference virtual_register =
ExternalReference::vector_store_virtual_register(masm->isolate()); ExternalReference::virtual_handler_register(masm->isolate());
// feedback initially contains the feedback array // feedback initially contains the feedback array
Label compare_smi_map; Label compare_smi_map;
...@@ -4767,13 +4767,16 @@ static void HandlePolymorphicKeyedStoreCase(MacroAssembler* masm, ...@@ -4767,13 +4767,16 @@ static void HandlePolymorphicKeyedStoreCase(MacroAssembler* masm,
Label transition_call; Label transition_call;
Label pop_and_miss; Label pop_and_miss;
ExternalReference virtual_register = 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(receiver);
__ push(vector); __ push(vector);
Register receiver_map = receiver; Register receiver_map = receiver;
Register cached_map = vector; Register cached_map = vector;
Register value = StoreDescriptor::ValueRegister();
// Receiver might not be a heap object. // Receiver might not be a heap object.
__ JumpIfSmi(receiver, &load_smi_map); __ JumpIfSmi(receiver, &load_smi_map);
...@@ -4782,11 +4785,17 @@ static void HandlePolymorphicKeyedStoreCase(MacroAssembler* masm, ...@@ -4782,11 +4785,17 @@ static void HandlePolymorphicKeyedStoreCase(MacroAssembler* masm,
// Polymorphic, we have to loop from 0 to N - 1 // Polymorphic, we have to loop from 0 to N - 1
__ push(key); __ push(key);
// On the stack we have: // Current stack layout:
// key (esp) // - esp[0] -- key
// vector // - esp[4] -- vector
// receiver // - esp[8] -- receiver
// value // - 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; Register counter = key;
__ mov(counter, Immediate(Smi::FromInt(0))); __ mov(counter, Immediate(Smi::FromInt(0)));
__ bind(&next_loop); __ bind(&next_loop);
...@@ -4805,32 +4814,39 @@ static void HandlePolymorphicKeyedStoreCase(MacroAssembler* masm, ...@@ -4805,32 +4814,39 @@ static void HandlePolymorphicKeyedStoreCase(MacroAssembler* masm,
__ pop(receiver); __ pop(receiver);
__ lea(feedback, FieldOperand(feedback, Code::kHeaderSize)); __ lea(feedback, FieldOperand(feedback, Code::kHeaderSize));
__ mov(Operand::StaticVariable(virtual_register), feedback); __ mov(Operand::StaticVariable(virtual_register), feedback);
__ pop(feedback); // Pop "value". __ pop(value);
__ jmp(Operand::StaticVariable(virtual_register)); __ jmp(Operand::StaticVariable(virtual_register));
__ bind(&transition_call); __ bind(&transition_call);
// Oh holy hell this will be tough. // Current stack layout:
// The map goes in vector register. // - esp[0] -- key
__ mov(receiver, FieldOperand(cached_map, WeakCell::kValueOffset)); // - esp[4] -- vector
// The weak cell may have been cleared. // - esp[8] -- receiver
__ JumpIfSmi(receiver, &pop_and_miss); // - esp[12] -- value
// slot goes on the stack, and holds return address. // - esp[16] -- return address
__ xchg(slot, Operand(esp, 4 * kPointerSize)); //
// Get the handler in value. // 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, __ mov(feedback, FieldOperand(feedback, counter, times_half_pointer_size,
FixedArray::kHeaderSize + 2 * kPointerSize)); FixedArray::kHeaderSize + 2 * kPointerSize));
__ lea(feedback, FieldOperand(feedback, Code::kHeaderSize)); __ 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 into place.
__ pop(key); __ pop(key);
// Put the return address on top of stack, vector goes in slot. __ pop(vector);
__ xchg(slot, Operand(esp, 0)); __ pop(receiver);
// put the map on the stack, receiver holds receiver. __ pop(value);
__ xchg(receiver, Operand(esp, 1 * kPointerSize)); __ jmp(Operand::StaticVariable(virtual_register));
// 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);
__ bind(&prepare_next); __ bind(&prepare_next);
__ add(counter, Immediate(Smi::FromInt(3))); __ add(counter, Immediate(Smi::FromInt(3)));
......
...@@ -35,12 +35,10 @@ const Register VectorStoreTransitionDescriptor::SlotRegister() { ...@@ -35,12 +35,10 @@ const Register VectorStoreTransitionDescriptor::SlotRegister() {
} }
const Register VectorStoreTransitionDescriptor::VectorRegister() { const Register VectorStoreTransitionDescriptor::VectorRegister() { return ebx; }
return no_reg;
}
const Register VectorStoreTransitionDescriptor::MapRegister() { return no_reg; } const Register VectorStoreTransitionDescriptor::MapRegister() { return edi; }
const Register StoreTransitionDescriptor::MapRegister() { return ebx; } const Register StoreTransitionDescriptor::MapRegister() { return ebx; }
...@@ -85,14 +83,6 @@ const Register GrowArrayElementsDescriptor::ObjectRegister() { return eax; } ...@@ -85,14 +83,6 @@ const Register GrowArrayElementsDescriptor::ObjectRegister() { return eax; }
const Register GrowArrayElementsDescriptor::KeyRegister() { return ebx; } 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( void FastNewClosureDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
Register registers[] = {ebx}; Register registers[] = {ebx};
......
...@@ -356,8 +356,8 @@ void NamedStoreHandlerCompiler::GenerateRestoreName(Handle<Name> name) { ...@@ -356,8 +356,8 @@ void NamedStoreHandlerCompiler::GenerateRestoreName(Handle<Name> name) {
} }
void NamedStoreHandlerCompiler::GeneratePushMap(Register map_reg, void NamedStoreHandlerCompiler::RearrangeVectorAndSlot(
Register scratch) { Register current_map, Register destination_map) {
DCHECK(false); // Not implemented. DCHECK(false); // Not implemented.
} }
......
...@@ -404,8 +404,8 @@ void NamedStoreHandlerCompiler::GenerateRestoreName(Handle<Name> name) { ...@@ -404,8 +404,8 @@ void NamedStoreHandlerCompiler::GenerateRestoreName(Handle<Name> name) {
} }
void NamedStoreHandlerCompiler::GeneratePushMap(Register map_reg, void NamedStoreHandlerCompiler::RearrangeVectorAndSlot(
Register scratch) { Register current_map, Register destination_map) {
DCHECK(false); // Not implemented. DCHECK(false); // Not implemented.
} }
......
...@@ -456,17 +456,18 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreTransition( ...@@ -456,17 +456,18 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreTransition(
DCHECK(!transition->is_access_check_needed()); DCHECK(!transition->is_access_check_needed());
// Call to respective StoreTransitionStub. // Call to respective StoreTransitionStub.
Register transition_map_reg = StoreTransitionHelper::MapRegister(); bool virtual_args = StoreTransitionHelper::HasVirtualSlotArg();
bool stack_args = StoreTransitionHelper::UsesStackArgs(); Register map_reg = StoreTransitionHelper::MapRegister();
Register map_reg = stack_args ? scratch1() : transition_map_reg;
if (details.type() == DATA_CONSTANT) { if (details.type() == DATA_CONSTANT) {
DCHECK(descriptors->GetValue(descriptor)->IsJSFunction()); DCHECK(descriptors->GetValue(descriptor)->IsJSFunction());
GenerateRestoreMap(transition, map_reg, scratch2(), &miss); Register tmp =
GenerateConstantCheck(map_reg, descriptor, value(), scratch2(), &miss); virtual_args ? VectorStoreICDescriptor::VectorRegister() : map_reg;
if (stack_args) { GenerateRestoreMap(transition, tmp, scratch2(), &miss);
// Also pushes vector and slot. GenerateConstantCheck(tmp, descriptor, value(), scratch2(), &miss);
GeneratePushMap(map_reg, scratch2()); if (virtual_args) {
// This will move the map from tmp into map_reg.
RearrangeVectorAndSlot(tmp, map_reg);
} else if (FLAG_vector_stores) { } else if (FLAG_vector_stores) {
PopVectorAndSlot(); PopVectorAndSlot();
} }
...@@ -484,10 +485,11 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreTransition( ...@@ -484,10 +485,11 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreTransition(
? StoreTransitionStub::ExtendStorageAndStoreMapAndValue ? StoreTransitionStub::ExtendStorageAndStoreMapAndValue
: StoreTransitionStub::StoreMapAndValue; : StoreTransitionStub::StoreMapAndValue;
GenerateRestoreMap(transition, map_reg, scratch2(), &miss); Register tmp =
if (stack_args) { virtual_args ? VectorStoreICDescriptor::VectorRegister() : map_reg;
// Also pushes vector and slot. GenerateRestoreMap(transition, tmp, scratch2(), &miss);
GeneratePushMap(map_reg, scratch2()); if (virtual_args) {
RearrangeVectorAndSlot(tmp, map_reg);
} else if (FLAG_vector_stores) { } else if (FLAG_vector_stores) {
PopVectorAndSlot(); PopVectorAndSlot();
} }
......
...@@ -251,7 +251,10 @@ class NamedStoreHandlerCompiler : public PropertyHandlerCompiler { ...@@ -251,7 +251,10 @@ class NamedStoreHandlerCompiler : public PropertyHandlerCompiler {
virtual void FrontendFooter(Handle<Name> name, Label* miss); virtual void FrontendFooter(Handle<Name> name, Label* miss);
void GenerateRestoreName(Label* label, Handle<Name> name); void GenerateRestoreName(Label* label, Handle<Name> name);
void GeneratePushMap(Register map_reg, Register scratch);
// Pop the vector and slot into appropriate registers, moving the map in
// the process. (This is an accomodation for register pressure on ia32).
void RearrangeVectorAndSlot(Register current_map, Register destination_map);
private: private:
void GenerateRestoreName(Handle<Name> name); void GenerateRestoreName(Handle<Name> name);
......
...@@ -362,18 +362,16 @@ void NamedStoreHandlerCompiler::GenerateRestoreName(Handle<Name> name) { ...@@ -362,18 +362,16 @@ void NamedStoreHandlerCompiler::GenerateRestoreName(Handle<Name> name) {
} }
void NamedStoreHandlerCompiler::GeneratePushMap(Register map_reg, void NamedStoreHandlerCompiler::RearrangeVectorAndSlot(
Register scratch) { Register current_map, Register destination_map) {
// current after GeneratePushMap DCHECK(destination_map.is(StoreTransitionHelper::MapRegister()));
// ------------------------------------------------- DCHECK(current_map.is(StoreTransitionHelper::VectorRegister()));
// ret addr slot ExternalReference virtual_slot =
// vector vector ExternalReference::virtual_slot_register(isolate());
// sp -> slot map __ mov(destination_map, current_map);
// sp -> ret addr __ pop(current_map);
// __ mov(Operand::StaticVariable(virtual_slot), current_map);
__ xchg(map_reg, Operand(esp, 0)); __ pop(current_map); // put vector in place.
__ xchg(map_reg, Operand(esp, 2 * kPointerSize));
__ push(map_reg);
} }
......
...@@ -24,7 +24,7 @@ static void ProbeTable(Isolate* isolate, MacroAssembler* masm, ...@@ -24,7 +24,7 @@ static void ProbeTable(Isolate* isolate, MacroAssembler* masm,
ExternalReference value_offset(isolate->stub_cache()->value_reference(table)); ExternalReference value_offset(isolate->stub_cache()->value_reference(table));
ExternalReference map_offset(isolate->stub_cache()->map_reference(table)); ExternalReference map_offset(isolate->stub_cache()->map_reference(table));
ExternalReference virtual_register = ExternalReference virtual_register =
ExternalReference::vector_store_virtual_register(masm->isolate()); ExternalReference::virtual_handler_register(masm->isolate());
Label miss; Label miss;
bool is_vector_store = bool is_vector_store =
......
...@@ -2478,9 +2478,29 @@ RUNTIME_FUNCTION(Runtime_StoreIC_MissFromStubFailure) { ...@@ -2478,9 +2478,29 @@ RUNTIME_FUNCTION(Runtime_StoreIC_MissFromStubFailure) {
Handle<Object> result; Handle<Object> result;
if (FLAG_vector_stores) { if (FLAG_vector_stores) {
DCHECK(args.length() == 5 || args.length() == 6); int length = args.length();
Handle<Smi> slot = args.at<Smi>(3); DCHECK(length == 5 || length == 6);
Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(4); // We might have slot and vector, for a normal miss (slot(3), vector(4)).
// Or, map and vector for a transitioning store miss (map(3), vector(4)).
// In this case, we need to recover the slot from a virtual register.
// If length == 6, then a map is included (map(3), slot(4), vector(5)).
Handle<Smi> slot;
Handle<TypeFeedbackVector> vector;
if (length == 5) {
if (args.at<Object>(3)->IsMap()) {
vector = args.at<TypeFeedbackVector>(4);
slot = handle(
*reinterpret_cast<Smi**>(isolate->virtual_slot_register_address()),
isolate);
} else {
vector = args.at<TypeFeedbackVector>(4);
slot = args.at<Smi>(3);
}
} else {
vector = args.at<TypeFeedbackVector>(5);
slot = args.at<Smi>(4);
}
FeedbackVectorSlot vector_slot = vector->ToSlot(slot->value()); FeedbackVectorSlot vector_slot = vector->ToSlot(slot->value());
if (vector->GetKind(vector_slot) == FeedbackVectorSlotKind::STORE_IC) { if (vector->GetKind(vector_slot) == FeedbackVectorSlotKind::STORE_IC) {
StoreICNexus nexus(vector, vector_slot); StoreICNexus nexus(vector, vector_slot);
...@@ -2616,11 +2636,14 @@ RUNTIME_FUNCTION(Runtime_KeyedStoreIC_Slow) { ...@@ -2616,11 +2636,14 @@ RUNTIME_FUNCTION(Runtime_KeyedStoreIC_Slow) {
RUNTIME_FUNCTION(Runtime_ElementsTransitionAndStoreIC_Miss) { RUNTIME_FUNCTION(Runtime_ElementsTransitionAndStoreIC_Miss) {
TimerEventScope<TimerEventIcMiss> timer(isolate); TimerEventScope<TimerEventIcMiss> timer(isolate);
HandleScope scope(isolate); HandleScope scope(isolate);
DCHECK(args.length() == (FLAG_vector_stores ? 6 : 4)); // Without vector stores, length == 4.
// With vector stores, length == 5 or 6, depending on whether the vector slot
// is passed in a virtual register or not.
DCHECK(!FLAG_vector_stores || args.length() == 5 || args.length() == 6);
Handle<Object> object = args.at<Object>(0); Handle<Object> object = args.at<Object>(0);
Handle<Object> key = args.at<Object>(1); Handle<Object> key = args.at<Object>(1);
Handle<Object> value = args.at<Object>(2); Handle<Object> value = args.at<Object>(2);
Handle<Map> map = args.at<Map>(FLAG_vector_stores ? 5 : 3); Handle<Map> map = args.at<Map>(3);
LanguageMode language_mode; LanguageMode language_mode;
if (FLAG_vector_stores) { if (FLAG_vector_stores) {
KeyedStoreICNexus nexus(isolate); KeyedStoreICNexus nexus(isolate);
......
...@@ -346,8 +346,8 @@ void NamedStoreHandlerCompiler::GenerateRestoreName(Handle<Name> name) { ...@@ -346,8 +346,8 @@ void NamedStoreHandlerCompiler::GenerateRestoreName(Handle<Name> name) {
} }
void NamedStoreHandlerCompiler::GeneratePushMap(Register map_reg, void NamedStoreHandlerCompiler::RearrangeVectorAndSlot(
Register scratch) { Register current_map, Register destination_map) {
DCHECK(false); // Not implemented. DCHECK(false); // Not implemented.
} }
......
...@@ -347,8 +347,8 @@ void NamedStoreHandlerCompiler::GenerateRestoreName(Handle<Name> name) { ...@@ -347,8 +347,8 @@ void NamedStoreHandlerCompiler::GenerateRestoreName(Handle<Name> name) {
} }
void NamedStoreHandlerCompiler::GeneratePushMap(Register map_reg, void NamedStoreHandlerCompiler::RearrangeVectorAndSlot(
Register scratch) { Register current_map, Register destination_map) {
DCHECK(false); // Not implemented. DCHECK(false); // Not implemented.
} }
......
...@@ -364,8 +364,8 @@ void NamedStoreHandlerCompiler::GenerateRestoreName(Handle<Name> name) { ...@@ -364,8 +364,8 @@ void NamedStoreHandlerCompiler::GenerateRestoreName(Handle<Name> name) {
} }
void NamedStoreHandlerCompiler::GeneratePushMap(Register map_reg, void NamedStoreHandlerCompiler::RearrangeVectorAndSlot(
Register scratch) { Register current_map, Register destination_map) {
DCHECK(false); // Not implemented. DCHECK(false); // Not implemented.
} }
......
...@@ -109,6 +109,21 @@ void StoreTransitionDescriptor::InitializePlatformSpecific( ...@@ -109,6 +109,21 @@ void StoreTransitionDescriptor::InitializePlatformSpecific(
} }
void VectorStoreTransitionDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
if (SlotRegister().is(no_reg)) {
Register registers[] = {ReceiverRegister(), NameRegister(), ValueRegister(),
MapRegister(), VectorRegister()};
data->InitializePlatformSpecific(arraysize(registers), registers);
} else {
Register registers[] = {ReceiverRegister(), NameRegister(),
ValueRegister(), MapRegister(),
SlotRegister(), VectorRegister()};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
}
Type::FunctionType* Type::FunctionType*
StoreTransitionDescriptor::BuildCallInterfaceDescriptorFunctionType( StoreTransitionDescriptor::BuildCallInterfaceDescriptorFunctionType(
Isolate* isolate, int paramater_count) { Isolate* isolate, int paramater_count) {
...@@ -228,14 +243,19 @@ Type::FunctionType* ...@@ -228,14 +243,19 @@ Type::FunctionType*
VectorStoreTransitionDescriptor::BuildCallInterfaceDescriptorFunctionType( VectorStoreTransitionDescriptor::BuildCallInterfaceDescriptorFunctionType(
Isolate* isolate, int paramater_count) { Isolate* isolate, int paramater_count) {
Zone* zone = isolate->interface_descriptor_zone(); Zone* zone = isolate->interface_descriptor_zone();
Type::FunctionType* function = bool has_slot = !VectorStoreTransitionDescriptor::SlotRegister().is(no_reg);
Type::FunctionType::New(AnyTagged(zone), Type::Undefined(), 6, zone); int arg_count = has_slot ? 6 : 5;
function->InitParameter(0, AnyTagged(zone)); // receiver Type::FunctionType* function = Type::FunctionType::New(
function->InitParameter(1, AnyTagged(zone)); // name AnyTagged(zone), Type::Undefined(), arg_count, zone);
function->InitParameter(2, AnyTagged(zone)); // value int index = 0;
function->InitParameter(3, SmiType(zone)); // slot function->InitParameter(index++, AnyTagged(zone)); // receiver
function->InitParameter(4, AnyTagged(zone)); // vector function->InitParameter(index++, AnyTagged(zone)); // name
function->InitParameter(5, AnyTagged(zone)); // map function->InitParameter(index++, AnyTagged(zone)); // value
function->InitParameter(index++, AnyTagged(zone)); // map
if (has_slot) {
function->InitParameter(index++, SmiType(zone)); // slot
}
function->InitParameter(index++, AnyTagged(zone)); // vector
return function; return function;
} }
......
...@@ -281,19 +281,21 @@ class VectorStoreTransitionDescriptor : public StoreDescriptor { ...@@ -281,19 +281,21 @@ class VectorStoreTransitionDescriptor : public StoreDescriptor {
// Extends StoreDescriptor with Map parameter. // Extends StoreDescriptor with Map parameter.
enum ParameterIndices { enum ParameterIndices {
kReceiverIndex, kReceiverIndex = 0,
kNameIndex, kNameIndex = 1,
kValueIndex, kValueIndex = 2,
kSlotIndex,
kVectorIndex, kMapIndex = 3,
kMapIndex,
kParameterCount kSlotIndex = 4, // not present on ia32.
kVirtualSlotVectorIndex = 4,
kVectorIndex = 5
}; };
// These registers are no_reg for ia32, using the stack instead. static const Register MapRegister();
static const Register SlotRegister(); static const Register SlotRegister();
static const Register VectorRegister(); static const Register VectorRegister();
static const Register MapRegister();
}; };
......
...@@ -1784,7 +1784,8 @@ Isolate::Isolate(bool enable_serializer) ...@@ -1784,7 +1784,8 @@ Isolate::Isolate(bool enable_serializer)
deferred_handles_head_(NULL), deferred_handles_head_(NULL),
optimizing_compile_dispatcher_(NULL), optimizing_compile_dispatcher_(NULL),
stress_deopt_count_(0), stress_deopt_count_(0),
vector_store_virtual_register_(NULL), virtual_handler_register_(NULL),
virtual_slot_register_(NULL),
next_optimization_id_(0), next_optimization_id_(0),
#if TRACE_MAPS #if TRACE_MAPS
next_unique_sfi_id_(0), next_unique_sfi_id_(0),
......
...@@ -1027,10 +1027,12 @@ class Isolate { ...@@ -1027,10 +1027,12 @@ class Isolate {
void* stress_deopt_count_address() { return &stress_deopt_count_; } void* stress_deopt_count_address() { return &stress_deopt_count_; }
void* vector_store_virtual_register_address() { void* virtual_handler_register_address() {
return &vector_store_virtual_register_; return &virtual_handler_register_;
} }
void* virtual_slot_register_address() { return &virtual_slot_register_; }
base::RandomNumberGenerator* random_number_generator(); base::RandomNumberGenerator* random_number_generator();
// Given an address occupied by a live code object, return that object. // Given an address occupied by a live code object, return that object.
...@@ -1306,7 +1308,8 @@ class Isolate { ...@@ -1306,7 +1308,8 @@ class Isolate {
// Counts deopt points if deopt_every_n_times is enabled. // Counts deopt points if deopt_every_n_times is enabled.
unsigned int stress_deopt_count_; unsigned int stress_deopt_count_;
Address vector_store_virtual_register_; Address virtual_handler_register_;
Address virtual_slot_register_;
int next_optimization_id_; int next_optimization_id_;
......
...@@ -78,14 +78,6 @@ const Register GrowArrayElementsDescriptor::ObjectRegister() { return a0; } ...@@ -78,14 +78,6 @@ const Register GrowArrayElementsDescriptor::ObjectRegister() { return a0; }
const Register GrowArrayElementsDescriptor::KeyRegister() { return a3; } const Register GrowArrayElementsDescriptor::KeyRegister() { return a3; }
void VectorStoreTransitionDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {ReceiverRegister(), NameRegister(), ValueRegister(),
SlotRegister(), VectorRegister(), MapRegister()};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void FastNewClosureDescriptor::InitializePlatformSpecific( void FastNewClosureDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
Register registers[] = {a2}; Register registers[] = {a2};
......
...@@ -78,14 +78,6 @@ const Register GrowArrayElementsDescriptor::ObjectRegister() { return a0; } ...@@ -78,14 +78,6 @@ const Register GrowArrayElementsDescriptor::ObjectRegister() { return a0; }
const Register GrowArrayElementsDescriptor::KeyRegister() { return a3; } const Register GrowArrayElementsDescriptor::KeyRegister() { return a3; }
void VectorStoreTransitionDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {ReceiverRegister(), NameRegister(), ValueRegister(),
SlotRegister(), VectorRegister(), MapRegister()};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void FastNewClosureDescriptor::InitializePlatformSpecific( void FastNewClosureDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
Register registers[] = {a2}; Register registers[] = {a2};
......
...@@ -129,8 +129,10 @@ ExternalReferenceTable::ExternalReferenceTable(Isolate* isolate) { ...@@ -129,8 +129,10 @@ ExternalReferenceTable::ExternalReferenceTable(Isolate* isolate) {
"double_constants.minus_one_half"); "double_constants.minus_one_half");
Add(ExternalReference::stress_deopt_count(isolate).address(), Add(ExternalReference::stress_deopt_count(isolate).address(),
"Isolate::stress_deopt_count_address()"); "Isolate::stress_deopt_count_address()");
Add(ExternalReference::vector_store_virtual_register(isolate).address(), Add(ExternalReference::virtual_handler_register(isolate).address(),
"Isolate::vector_store_virtual_register()"); "Isolate::virtual_handler_register()");
Add(ExternalReference::virtual_slot_register(isolate).address(),
"Isolate::virtual_slot_register()");
Add(ExternalReference::runtime_function_table_address(isolate).address(), Add(ExternalReference::runtime_function_table_address(isolate).address(),
"Runtime::runtime_function_table_address()"); "Runtime::runtime_function_table_address()");
......
...@@ -78,14 +78,6 @@ const Register GrowArrayElementsDescriptor::ObjectRegister() { return rax; } ...@@ -78,14 +78,6 @@ const Register GrowArrayElementsDescriptor::ObjectRegister() { return rax; }
const Register GrowArrayElementsDescriptor::KeyRegister() { return rbx; } const Register GrowArrayElementsDescriptor::KeyRegister() { return rbx; }
void VectorStoreTransitionDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {ReceiverRegister(), NameRegister(), ValueRegister(),
SlotRegister(), VectorRegister(), MapRegister()};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void FastNewClosureDescriptor::InitializePlatformSpecific( void FastNewClosureDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
Register registers[] = {rbx}; Register registers[] = {rbx};
......
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