Commit cd351559 authored by mvstanton's avatar mvstanton Committed by Commit bot

VectorICs: New interface descriptor for vector transitioning stores.

BUG=

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

Cr-Commit-Position: refs/heads/master@{#30284}
parent 4c5efa99
......@@ -31,6 +31,11 @@ const Register VectorStoreICTrampolineDescriptor::SlotRegister() { return r4; }
const Register VectorStoreICDescriptor::VectorRegister() { return r3; }
const Register VectorStoreTransitionDescriptor::SlotRegister() { return r4; }
const Register VectorStoreTransitionDescriptor::VectorRegister() { return r3; }
const Register VectorStoreTransitionDescriptor::MapRegister() { return r5; }
const Register StoreTransitionDescriptor::MapRegister() { return r3; }
......@@ -64,10 +69,10 @@ const Register GrowArrayElementsDescriptor::ObjectRegister() { return r0; }
const Register GrowArrayElementsDescriptor::KeyRegister() { return r3; }
void StoreTransitionDescriptor::InitializePlatformSpecific(
void VectorStoreTransitionDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {ReceiverRegister(), NameRegister(), ValueRegister(),
MapRegister()};
Register registers[] = {ReceiverRegister(), NameRegister(), ValueRegister(),
SlotRegister(), VectorRegister(), MapRegister()};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
......
......@@ -31,6 +31,11 @@ const Register VectorStoreICTrampolineDescriptor::SlotRegister() { return x4; }
const Register VectorStoreICDescriptor::VectorRegister() { return x3; }
const Register VectorStoreTransitionDescriptor::SlotRegister() { return x4; }
const Register VectorStoreTransitionDescriptor::VectorRegister() { return x3; }
const Register VectorStoreTransitionDescriptor::MapRegister() { return x5; }
const Register StoreTransitionDescriptor::MapRegister() { return x3; }
......@@ -70,10 +75,10 @@ const Register GrowArrayElementsDescriptor::ObjectRegister() { return x0; }
const Register GrowArrayElementsDescriptor::KeyRegister() { return x3; }
void StoreTransitionDescriptor::InitializePlatformSpecific(
void VectorStoreTransitionDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {ReceiverRegister(), NameRegister(), ValueRegister(),
MapRegister()};
Register registers[] = {ReceiverRegister(), NameRegister(), ValueRegister(),
SlotRegister(), VectorRegister(), MapRegister()};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
......
......@@ -155,8 +155,8 @@ bool CodeStubGraphBuilderBase::BuildGraph() {
HParameter::STACK_PARAMETER, r);
} else {
param = Add<HParameter>(i, HParameter::REGISTER_PARAMETER, r);
start_environment->Bind(i, param);
}
start_environment->Bind(i, param);
parameters_[i] = param;
if (i < register_param_count && IsParameterCountRegister(i)) {
param->set_type(HType::Smi());
......@@ -1015,7 +1015,7 @@ Handle<Code> StoreFieldStub::GenerateCode() { return DoGenerateCode(this); }
template <>
HValue* CodeStubGraphBuilder<StoreTransitionStub>::BuildCodeStub() {
HValue* object = GetParameter(StoreTransitionDescriptor::kReceiverIndex);
HValue* object = GetParameter(StoreTransitionHelper::ReceiverIndex());
switch (casted_stub()->store_mode()) {
case StoreTransitionStub::ExtendStorageAndStoreMapAndValue: {
......@@ -1046,17 +1046,17 @@ HValue* CodeStubGraphBuilder<StoreTransitionStub>::BuildCodeStub() {
case StoreTransitionStub::StoreMapAndValue:
// Store the new value into the "extended" object.
BuildStoreNamedField(
object, GetParameter(StoreTransitionDescriptor::kValueIndex),
object, GetParameter(StoreTransitionHelper::ValueIndex()),
casted_stub()->index(), casted_stub()->representation(), true);
// Fall through.
case StoreTransitionStub::StoreMapOnly:
// And finally update the map.
Add<HStoreNamedField>(object, HObjectAccess::ForMap(),
GetParameter(StoreTransitionDescriptor::kMapIndex));
GetParameter(StoreTransitionHelper::MapIndex()));
break;
}
return GetParameter(StoreTransitionDescriptor::kValueIndex);
return GetParameter(StoreTransitionHelper::ValueIndex());
}
......@@ -1609,10 +1609,10 @@ Handle<Code> StoreGlobalStub::GenerateCode() {
template <>
HValue* CodeStubGraphBuilder<ElementsTransitionAndStoreStub>::BuildCodeStub() {
HValue* object = GetParameter(StoreTransitionDescriptor::kReceiverIndex);
HValue* key = GetParameter(StoreTransitionDescriptor::kNameIndex);
HValue* value = GetParameter(StoreTransitionDescriptor::kValueIndex);
HValue* map = GetParameter(StoreTransitionDescriptor::kMapIndex);
HValue* object = GetParameter(StoreTransitionHelper::ReceiverIndex());
HValue* key = GetParameter(StoreTransitionHelper::NameIndex());
HValue* value = GetParameter(StoreTransitionHelper::ValueIndex());
HValue* map = GetParameter(StoreTransitionHelper::MapIndex());
if (FLAG_trace_elements_transitions) {
// Tracing elements transitions is the job of the runtime.
......
......@@ -653,7 +653,8 @@ CallInterfaceDescriptor HandlerStub::GetCallInterfaceDescriptor() const {
return LoadWithVectorDescriptor(isolate());
} else {
DCHECK(kind() == Code::STORE_IC || kind() == Code::KEYED_STORE_IC);
return StoreDescriptor(isolate());
return FLAG_vector_stores ? VectorStoreICDescriptor(isolate())
: StoreDescriptor(isolate());
}
}
......@@ -679,6 +680,18 @@ void ToObjectStub::InitializeDescriptor(CodeStubDescriptor* descriptor) {
CallInterfaceDescriptor StoreTransitionStub::GetCallInterfaceDescriptor()
const {
if (FLAG_vector_stores) {
return VectorStoreTransitionDescriptor(isolate());
}
return StoreTransitionDescriptor(isolate());
}
CallInterfaceDescriptor
ElementsTransitionAndStoreStub::GetCallInterfaceDescriptor() const {
if (FLAG_vector_stores) {
return VectorStoreTransitionDescriptor(isolate());
}
return StoreTransitionDescriptor(isolate());
}
......
......@@ -329,8 +329,7 @@ struct FakeStubForTesting : public CodeStub {
Major MajorKey() const override { return CodeStub::NoCache; }
CallInterfaceDescriptor GetCallInterfaceDescriptor() const override {
UNREACHABLE();
return CallInterfaceDescriptor();
return ContextOnlyDescriptor(isolate());
}
Handle<Code> GenerateCode() override {
......@@ -1278,6 +1277,69 @@ class StoreFieldStub : public HandlerStub {
};
// Register and parameter access methods are specified here instead of in
// the CallInterfaceDescriptor because the stub uses a different descriptor
// if FLAG_vector_stores is on.
class StoreTransitionHelper {
public:
static Register ReceiverRegister() {
return StoreTransitionDescriptor::ReceiverRegister();
}
static Register NameRegister() {
return StoreTransitionDescriptor::NameRegister();
}
static Register ValueRegister() {
return StoreTransitionDescriptor::ValueRegister();
}
static Register SlotRegister() {
DCHECK(FLAG_vector_stores);
return VectorStoreTransitionDescriptor::SlotRegister();
}
static Register VectorRegister() {
DCHECK(FLAG_vector_stores);
return VectorStoreTransitionDescriptor::VectorRegister();
}
static Register MapRegister() {
return FLAG_vector_stores ? VectorStoreTransitionDescriptor::MapRegister()
: StoreTransitionDescriptor::MapRegister();
}
static int ReceiverIndex() {
return StoreTransitionDescriptor::kReceiverIndex;
}
static int NameIndex() { return StoreTransitionDescriptor::kReceiverIndex; }
static int ValueIndex() { return StoreTransitionDescriptor::kValueIndex; }
static int SlotIndex() {
DCHECK(FLAG_vector_stores);
return VectorStoreTransitionDescriptor::kSlotIndex;
}
static int VectorIndex() {
DCHECK(FLAG_vector_stores);
return VectorStoreTransitionDescriptor::kVectorIndex;
}
static int MapIndex() {
if (FLAG_vector_stores) {
return VectorStoreTransitionDescriptor::kMapIndex;
}
return StoreTransitionDescriptor::kMapIndex;
}
// Some platforms push Slot, Vector, Map on the stack instead of in
// registers.
static bool UsesStackArgs() { return MapRegister().is(no_reg); }
};
class StoreTransitionStub : public HandlerStub {
public:
enum StoreMode {
......@@ -2606,12 +2668,18 @@ class StoreFastElementStub : public HydrogenCodeStub {
return StoreModeBits::decode(sub_minor_key());
}
CallInterfaceDescriptor GetCallInterfaceDescriptor() const override {
if (FLAG_vector_stores) {
return VectorStoreICDescriptor(isolate());
}
return StoreDescriptor(isolate());
}
private:
class ElementsKindBits: public BitField<ElementsKind, 0, 8> {};
class StoreModeBits: public BitField<KeyedAccessStoreMode, 8, 4> {};
class IsJSArrayBits: public BitField<bool, 12, 1> {};
DEFINE_CALL_INTERFACE_DESCRIPTOR(Store);
DEFINE_HYDROGEN_CODE_STUB(StoreFastElement, HydrogenCodeStub);
};
......@@ -2829,6 +2897,13 @@ class StoreElementStub : public PlatformCodeStub {
minor_key_ = ElementsKindBits::encode(elements_kind);
}
CallInterfaceDescriptor GetCallInterfaceDescriptor() const override {
if (FLAG_vector_stores) {
return VectorStoreICDescriptor(isolate());
}
return StoreDescriptor(isolate());
}
private:
ElementsKind elements_kind() const {
return ElementsKindBits::decode(minor_key_);
......@@ -2836,7 +2911,6 @@ class StoreElementStub : public PlatformCodeStub {
class ElementsKindBits : public BitField<ElementsKind, 0, 8> {};
DEFINE_CALL_INTERFACE_DESCRIPTOR(Store);
DEFINE_PLATFORM_CODE_STUB(StoreElement, PlatformCodeStub);
};
......@@ -2951,13 +3025,14 @@ class ElementsTransitionAndStoreStub : public HydrogenCodeStub {
return StoreModeBits::decode(sub_minor_key());
}
CallInterfaceDescriptor GetCallInterfaceDescriptor() const override;
private:
class FromBits : public BitField<ElementsKind, 0, 8> {};
class ToBits : public BitField<ElementsKind, 8, 8> {};
class IsJSArrayBits : public BitField<bool, 16, 1> {};
class StoreModeBits : public BitField<KeyedAccessStoreMode, 17, 4> {};
DEFINE_CALL_INTERFACE_DESCRIPTOR(StoreTransition);
DEFINE_HYDROGEN_CODE_STUB(ElementsTransitionAndStore, HydrogenCodeStub);
};
......
......@@ -173,7 +173,16 @@ CompilationInfo::CompilationInfo(ParseInfo* parse_info, CodeStub* code_stub,
parameter_count_(0),
optimization_id_(-1),
osr_expr_stack_height_(0),
function_type_(nullptr) {}
function_type_(nullptr) {
// Parameter count is number of stack parameters.
if (code_stub_ != NULL) {
CodeStubDescriptor descriptor(code_stub_);
parameter_count_ = descriptor.GetStackParameterCount();
if (descriptor.function_mode() == NOT_JS_FUNCTION_STUB_MODE) {
parameter_count_--;
}
}
}
CompilationInfo::~CompilationInfo() {
......
......@@ -30,11 +30,22 @@ const Register VectorStoreICTrampolineDescriptor::SlotRegister() { return edi; }
const Register VectorStoreICDescriptor::VectorRegister() { return ebx; }
const Register StoreTransitionDescriptor::MapRegister() {
return FLAG_vector_stores ? no_reg : ebx;
const Register VectorStoreTransitionDescriptor::SlotRegister() {
return no_reg;
}
const Register VectorStoreTransitionDescriptor::VectorRegister() {
return no_reg;
}
const Register VectorStoreTransitionDescriptor::MapRegister() { return no_reg; }
const Register StoreTransitionDescriptor::MapRegister() { return ebx; }
const Register LoadGlobalViaContextDescriptor::SlotRegister() { return ebx; }
......@@ -65,17 +76,11 @@ const Register GrowArrayElementsDescriptor::ObjectRegister() { return eax; }
const Register GrowArrayElementsDescriptor::KeyRegister() { return ebx; }
void StoreTransitionDescriptor::InitializePlatformSpecific(
void VectorStoreTransitionDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {ReceiverRegister(), NameRegister(), ValueRegister(),
MapRegister()};
// When FLAG_vector_stores is true, we want to pass the map register on the
// stack instead of in a register.
DCHECK(FLAG_vector_stores || !MapRegister().is(no_reg));
int register_count = FLAG_vector_stores ? 3 : 4;
data->InitializePlatformSpecific(register_count, registers);
Register registers[] = {ReceiverRegister(), NameRegister(), ValueRegister()};
// The other three parameters are on the stack in ia32.
data->InitializePlatformSpecific(arraysize(registers), registers);
}
......
......@@ -98,6 +98,15 @@ void StoreDescriptor::InitializePlatformSpecific(
}
void StoreTransitionDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {ReceiverRegister(), NameRegister(), ValueRegister(),
MapRegister()};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
Type::FunctionType*
StoreTransitionDescriptor::BuildCallInterfaceDescriptorFunctionType(
Isolate* isolate, int paramater_count) {
......@@ -195,6 +204,21 @@ void LoadWithVectorDescriptor::InitializePlatformSpecific(
}
Type::FunctionType*
VectorStoreTransitionDescriptor::BuildCallInterfaceDescriptorFunctionType(
Isolate* isolate, int paramater_count) {
Type::FunctionType* function = Type::FunctionType::New(
AnyTagged(), Type::Undefined(), 6, isolate->interface_descriptor_zone());
function->InitParameter(0, AnyTagged()); // receiver
function->InitParameter(1, AnyTagged()); // name
function->InitParameter(2, AnyTagged()); // value
function->InitParameter(3, SmiType()); // slot
function->InitParameter(4, AnyTagged()); // vector
function->InitParameter(5, AnyTagged()); // map
return function;
}
Type::FunctionType*
VectorStoreICDescriptor::BuildCallInterfaceDescriptorFunctionType(
Isolate* isolate, int paramater_count) {
......
......@@ -17,6 +17,7 @@ class PlatformInterfaceDescriptor;
V(Load) \
V(Store) \
V(StoreTransition) \
V(VectorStoreTransition) \
V(VectorStoreICTrampoline) \
V(VectorStoreIC) \
V(Instanceof) \
......@@ -263,7 +264,29 @@ class StoreTransitionDescriptor : public StoreDescriptor {
kParameterCount
};
// MapRegister() is no_reg on ia32, instead it's on the stack.
static const Register MapRegister();
};
class VectorStoreTransitionDescriptor : public StoreDescriptor {
public:
DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(VectorStoreTransitionDescriptor,
StoreDescriptor)
// Extends StoreDescriptor with Map parameter.
enum ParameterIndices {
kReceiverIndex,
kNameIndex,
kValueIndex,
kSlotIndex,
kVectorIndex,
kMapIndex,
kParameterCount
};
// These registers are no_reg for ia32, using the stack instead.
static const Register SlotRegister();
static const Register VectorRegister();
static const Register MapRegister();
};
......
......@@ -31,6 +31,11 @@ const Register VectorStoreICTrampolineDescriptor::SlotRegister() { return t0; }
const Register VectorStoreICDescriptor::VectorRegister() { return a3; }
const Register VectorStoreTransitionDescriptor::SlotRegister() { return t0; }
const Register VectorStoreTransitionDescriptor::VectorRegister() { return a3; }
const Register VectorStoreTransitionDescriptor::MapRegister() { return t1; }
const Register StoreTransitionDescriptor::MapRegister() { return a3; }
......@@ -64,10 +69,10 @@ const Register GrowArrayElementsDescriptor::ObjectRegister() { return a0; }
const Register GrowArrayElementsDescriptor::KeyRegister() { return a3; }
void StoreTransitionDescriptor::InitializePlatformSpecific(
void VectorStoreTransitionDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {ReceiverRegister(), NameRegister(), ValueRegister(),
MapRegister()};
Register registers[] = {ReceiverRegister(), NameRegister(), ValueRegister(),
SlotRegister(), VectorRegister(), MapRegister()};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
......
......@@ -31,6 +31,11 @@ const Register VectorStoreICTrampolineDescriptor::SlotRegister() { return a4; }
const Register VectorStoreICDescriptor::VectorRegister() { return a3; }
const Register VectorStoreTransitionDescriptor::SlotRegister() { return a4; }
const Register VectorStoreTransitionDescriptor::VectorRegister() { return a3; }
const Register VectorStoreTransitionDescriptor::MapRegister() { return a5; }
const Register StoreTransitionDescriptor::MapRegister() { return a3; }
......@@ -64,10 +69,10 @@ const Register GrowArrayElementsDescriptor::ObjectRegister() { return a0; }
const Register GrowArrayElementsDescriptor::KeyRegister() { return a3; }
void StoreTransitionDescriptor::InitializePlatformSpecific(
void VectorStoreTransitionDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {ReceiverRegister(), NameRegister(), ValueRegister(),
MapRegister()};
Register registers[] = {ReceiverRegister(), NameRegister(), ValueRegister(),
SlotRegister(), VectorRegister(), MapRegister()};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
......
......@@ -31,6 +31,11 @@ const Register VectorStoreICTrampolineDescriptor::SlotRegister() { return rdi; }
const Register VectorStoreICDescriptor::VectorRegister() { return rbx; }
const Register VectorStoreTransitionDescriptor::SlotRegister() { return rdi; }
const Register VectorStoreTransitionDescriptor::VectorRegister() { return rbx; }
const Register VectorStoreTransitionDescriptor::MapRegister() { return r11; }
const Register StoreTransitionDescriptor::MapRegister() { return rbx; }
......@@ -64,10 +69,10 @@ const Register GrowArrayElementsDescriptor::ObjectRegister() { return rax; }
const Register GrowArrayElementsDescriptor::KeyRegister() { return rbx; }
void StoreTransitionDescriptor::InitializePlatformSpecific(
void VectorStoreTransitionDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {ReceiverRegister(), NameRegister(), ValueRegister(),
MapRegister()};
Register registers[] = {ReceiverRegister(), NameRegister(), ValueRegister(),
SlotRegister(), VectorRegister(), MapRegister()};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
......
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