Commit 360ee4f9 authored by ishell's avatar ishell Committed by Commit bot

[stubs] Reduce number of StoreTransitionStub instances.

... by passing a field offset as a runtime parameter.

This CL also introduces a StoreMapStub - a special case of a store transition
that used to be handled by old StoreTransitionStub.

BUG=chromium:648545

Review-Url: https://codereview.chromium.org/2397573004
Cr-Commit-Position: refs/heads/master@{#39997}
parent bf1a94f1
...@@ -1115,12 +1115,32 @@ Node* CodeStubAssembler::StoreObjectField( ...@@ -1115,12 +1115,32 @@ Node* CodeStubAssembler::StoreObjectField(
IntPtrConstant(offset - kHeapObjectTag), value); IntPtrConstant(offset - kHeapObjectTag), value);
} }
Node* CodeStubAssembler::StoreObjectField(Node* object, Node* offset,
Node* value) {
int const_offset;
if (ToInt32Constant(offset, const_offset)) {
return StoreObjectField(object, const_offset, value);
}
return Store(MachineRepresentation::kTagged, object,
IntPtrSub(offset, IntPtrConstant(kHeapObjectTag)), value);
}
Node* CodeStubAssembler::StoreObjectFieldNoWriteBarrier( Node* CodeStubAssembler::StoreObjectFieldNoWriteBarrier(
Node* object, int offset, Node* value, MachineRepresentation rep) { Node* object, int offset, Node* value, MachineRepresentation rep) {
return StoreNoWriteBarrier(rep, object, return StoreNoWriteBarrier(rep, object,
IntPtrConstant(offset - kHeapObjectTag), value); IntPtrConstant(offset - kHeapObjectTag), value);
} }
Node* CodeStubAssembler::StoreObjectFieldNoWriteBarrier(
Node* object, Node* offset, Node* value, MachineRepresentation rep) {
int const_offset;
if (ToInt32Constant(offset, const_offset)) {
return StoreObjectFieldNoWriteBarrier(object, const_offset, value, rep);
}
return StoreNoWriteBarrier(
rep, object, IntPtrSub(offset, IntPtrConstant(kHeapObjectTag)), value);
}
Node* CodeStubAssembler::StoreMapNoWriteBarrier(Node* object, Node* map) { Node* CodeStubAssembler::StoreMapNoWriteBarrier(Node* object, Node* map) {
return StoreNoWriteBarrier( return StoreNoWriteBarrier(
MachineRepresentation::kTagged, object, MachineRepresentation::kTagged, object,
...@@ -5121,15 +5141,22 @@ void CodeStubAssembler::StoreNamedField(Node* object, FieldIndex index, ...@@ -5121,15 +5141,22 @@ void CodeStubAssembler::StoreNamedField(Node* object, FieldIndex index,
Node* value, bool transition_to_field) { Node* value, bool transition_to_field) {
DCHECK_EQ(index.is_double(), representation.IsDouble()); DCHECK_EQ(index.is_double(), representation.IsDouble());
StoreNamedField(object, IntPtrConstant(index.offset()), index.is_inobject(),
representation, value, transition_to_field);
}
void CodeStubAssembler::StoreNamedField(Node* object, Node* offset,
bool is_inobject,
Representation representation,
Node* value, bool transition_to_field) {
bool store_value_as_double = representation.IsDouble(); bool store_value_as_double = representation.IsDouble();
int offset = index.offset();
Node* property_storage = object; Node* property_storage = object;
if (!index.is_inobject()) { if (!is_inobject) {
property_storage = LoadProperties(object); property_storage = LoadProperties(object);
} }
if (representation.IsDouble()) { if (representation.IsDouble()) {
if (!FLAG_unbox_double_fields || !index.is_inobject()) { if (!FLAG_unbox_double_fields || !is_inobject) {
if (transition_to_field) { if (transition_to_field) {
Node* heap_number = AllocateHeapNumberWithValue(value, MUTABLE); Node* heap_number = AllocateHeapNumberWithValue(value, MUTABLE);
// Store the new mutable heap number into the object. // Store the new mutable heap number into the object.
...@@ -5139,7 +5166,7 @@ void CodeStubAssembler::StoreNamedField(Node* object, FieldIndex index, ...@@ -5139,7 +5166,7 @@ void CodeStubAssembler::StoreNamedField(Node* object, FieldIndex index,
// Load the heap number. // Load the heap number.
property_storage = LoadObjectField(property_storage, offset); property_storage = LoadObjectField(property_storage, offset);
// Store the double value into it. // Store the double value into it.
offset = HeapNumber::kValueOffset; offset = IntPtrConstant(HeapNumber::kValueOffset);
} }
} }
} }
......
...@@ -313,9 +313,15 @@ class CodeStubAssembler : public compiler::CodeAssembler { ...@@ -313,9 +313,15 @@ class CodeStubAssembler : public compiler::CodeAssembler {
// Store a field to an object on the heap. // Store a field to an object on the heap.
compiler::Node* StoreObjectField( compiler::Node* StoreObjectField(
compiler::Node* object, int offset, compiler::Node* value); compiler::Node* object, int offset, compiler::Node* value);
compiler::Node* StoreObjectField(compiler::Node* object,
compiler::Node* offset,
compiler::Node* value);
compiler::Node* StoreObjectFieldNoWriteBarrier( compiler::Node* StoreObjectFieldNoWriteBarrier(
compiler::Node* object, int offset, compiler::Node* value, compiler::Node* object, int offset, compiler::Node* value,
MachineRepresentation rep = MachineRepresentation::kTagged); MachineRepresentation rep = MachineRepresentation::kTagged);
compiler::Node* StoreObjectFieldNoWriteBarrier(
compiler::Node* object, compiler::Node* offset, compiler::Node* value,
MachineRepresentation rep = MachineRepresentation::kTagged);
// Store the Map of an HeapObject. // Store the Map of an HeapObject.
compiler::Node* StoreMapNoWriteBarrier(compiler::Node* object, compiler::Node* StoreMapNoWriteBarrier(compiler::Node* object,
compiler::Node* map); compiler::Node* map);
...@@ -754,6 +760,10 @@ class CodeStubAssembler : public compiler::CodeAssembler { ...@@ -754,6 +760,10 @@ class CodeStubAssembler : public compiler::CodeAssembler {
Representation representation, compiler::Node* value, Representation representation, compiler::Node* value,
bool transition_to_field); bool transition_to_field);
void StoreNamedField(compiler::Node* object, compiler::Node* offset,
bool is_inobject, Representation representation,
compiler::Node* value, bool transition_to_field);
// Emits keyed sloppy arguments load. Returns either the loaded value. // Emits keyed sloppy arguments load. Returns either the loaded value.
compiler::Node* LoadKeyedSloppyArguments(compiler::Node* receiver, compiler::Node* LoadKeyedSloppyArguments(compiler::Node* receiver,
compiler::Node* key, compiler::Node* key,
......
...@@ -529,57 +529,59 @@ void StoreICTFStub::GenerateAssembly(CodeStubAssembler* assembler) const { ...@@ -529,57 +529,59 @@ void StoreICTFStub::GenerateAssembly(CodeStubAssembler* assembler) const {
assembler->StoreIC(&p); assembler->StoreIC(&p);
} }
void StoreMapStub::GenerateAssembly(CodeStubAssembler* assembler) const {
typedef compiler::Node Node;
Node* receiver = assembler->Parameter(Descriptor::kReceiver);
Node* map = assembler->Parameter(Descriptor::kMap);
Node* value = assembler->Parameter(Descriptor::kValue);
assembler->StoreObjectField(receiver, JSObject::kMapOffset, map);
assembler->Return(value);
}
void StoreTransitionStub::GenerateAssembly(CodeStubAssembler* assembler) const { void StoreTransitionStub::GenerateAssembly(CodeStubAssembler* assembler) const {
typedef CodeStubAssembler::Label Label; typedef CodeStubAssembler::Label Label;
typedef compiler::Node Node; typedef compiler::Node Node;
Node* receiver = assembler->Parameter(Descriptor::kReceiver); Node* receiver = assembler->Parameter(Descriptor::kReceiver);
Node* name = assembler->Parameter(Descriptor::kName); Node* name = assembler->Parameter(Descriptor::kName);
Node* offset =
assembler->SmiUntag(assembler->Parameter(Descriptor::kFieldOffset));
Node* value = assembler->Parameter(Descriptor::kValue); Node* value = assembler->Parameter(Descriptor::kValue);
Node* map = assembler->Parameter(Descriptor::kMap); Node* map = assembler->Parameter(Descriptor::kMap);
Node* slot = assembler->Parameter(Descriptor::kSlot); Node* slot = assembler->Parameter(Descriptor::kSlot);
Node* vector = assembler->Parameter(Descriptor::kVector); Node* vector = assembler->Parameter(Descriptor::kVector);
Node* context = assembler->Parameter(Descriptor::kContext); Node* context = assembler->Parameter(Descriptor::kContext);
StoreMode store_mode = this->store_mode();
Node* prepared_value = value;
Label miss(assembler); Label miss(assembler);
bool needs_miss_case = false;
if (store_mode != StoreTransitionStub::StoreMapOnly) {
Representation representation = this->representation();
FieldIndex index = this->index();
assembler->Comment(
"Prepare value for write: representation: %s, index.is_inobject: %d, "
"index.offset: %d",
representation.Mnemonic(), index.is_inobject(), index.offset());
prepared_value =
assembler->PrepareValueForWrite(prepared_value, representation, &miss);
// Only store to tagged field never bails out.
needs_miss_case |= !representation.IsTagged();
}
switch (store_mode) { Representation representation = this->representation();
case StoreTransitionStub::ExtendStorageAndStoreMapAndValue: assembler->Comment("StoreTransitionStub: is_inobject: %d: representation: %s",
assembler->Comment("Extend storage"); is_inobject(), representation.Mnemonic());
assembler->ExtendPropertiesBackingStore(receiver);
// Fall through. Node* prepared_value =
case StoreTransitionStub::StoreMapAndValue: assembler->PrepareValueForWrite(value, representation, &miss);
assembler->Comment("Store value");
// Store the new value into the "extended" object. if (store_mode() == StoreTransitionStub::ExtendStorageAndStoreMapAndValue) {
assembler->StoreNamedField(receiver, index(), representation(), assembler->Comment("Extend storage");
prepared_value, true); assembler->ExtendPropertiesBackingStore(receiver);
// Fall through. } else {
case StoreTransitionStub::StoreMapOnly: DCHECK(store_mode() == StoreTransitionStub::StoreMapAndValue);
assembler->Comment("Store map");
// And finally update the map.
assembler->StoreObjectField(receiver, JSObject::kMapOffset, map);
break;
} }
// Store the new value into the "extended" object.
assembler->Comment("Store value");
assembler->StoreNamedField(receiver, offset, is_inobject(), representation,
prepared_value, true);
// And finally update the map.
assembler->Comment("Store map");
assembler->StoreObjectField(receiver, JSObject::kMapOffset, map);
assembler->Return(value); assembler->Return(value);
if (needs_miss_case) { // Only store to tagged field never bails out.
if (!representation.IsTagged()) {
assembler->Bind(&miss); assembler->Bind(&miss);
{ {
assembler->Comment("Miss"); assembler->Comment("Miss");
......
...@@ -159,6 +159,7 @@ class ObjectLiteral; ...@@ -159,6 +159,7 @@ class ObjectLiteral;
V(StoreGlobal) \ V(StoreGlobal) \
V(StoreICTF) \ V(StoreICTF) \
V(StoreInterceptor) \ V(StoreInterceptor) \
V(StoreMap) \
V(StoreTransition) \ V(StoreTransition) \
V(LoadApiGetter) \ V(LoadApiGetter) \
V(LoadIndexedInterceptor) \ V(LoadIndexedInterceptor) \
...@@ -1610,24 +1611,29 @@ class StoreFieldStub : public TurboFanCodeStub { ...@@ -1610,24 +1611,29 @@ class StoreFieldStub : public TurboFanCodeStub {
DEFINE_TURBOFAN_CODE_STUB(StoreField, TurboFanCodeStub); DEFINE_TURBOFAN_CODE_STUB(StoreField, TurboFanCodeStub);
}; };
class StoreMapStub : public TurboFanCodeStub {
public:
explicit StoreMapStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
Code::Kind GetCodeKind() const override { return Code::HANDLER; }
ExtraICState GetExtraICState() const override { return Code::STORE_IC; }
private:
DEFINE_CALL_INTERFACE_DESCRIPTOR(StoreTransition);
DEFINE_TURBOFAN_CODE_STUB(StoreMap, TurboFanCodeStub);
};
class StoreTransitionStub : public TurboFanCodeStub { class StoreTransitionStub : public TurboFanCodeStub {
public: public:
enum StoreMode { enum StoreMode {
StoreMapOnly,
StoreMapAndValue, StoreMapAndValue,
ExtendStorageAndStoreMapAndValue ExtendStorageAndStoreMapAndValue
}; };
explicit StoreTransitionStub(Isolate* isolate) : TurboFanCodeStub(isolate) { StoreTransitionStub(Isolate* isolate, bool is_inobject,
minor_key_ = StoreModeBits::encode(StoreMapOnly);
}
StoreTransitionStub(Isolate* isolate, FieldIndex index,
Representation representation, StoreMode store_mode) Representation representation, StoreMode store_mode)
: TurboFanCodeStub(isolate) { : TurboFanCodeStub(isolate) {
DCHECK(store_mode != StoreMapOnly); minor_key_ = IsInobjectBits::encode(is_inobject) |
int property_index_key = index.GetFieldAccessStubKey();
minor_key_ = StoreFieldByIndexBits::encode(property_index_key) |
RepresentationBits::encode(representation.kind()) | RepresentationBits::encode(representation.kind()) |
StoreModeBits::encode(store_mode); StoreModeBits::encode(store_mode);
} }
...@@ -1635,27 +1641,24 @@ class StoreTransitionStub : public TurboFanCodeStub { ...@@ -1635,27 +1641,24 @@ class StoreTransitionStub : public TurboFanCodeStub {
Code::Kind GetCodeKind() const override { return Code::HANDLER; } Code::Kind GetCodeKind() const override { return Code::HANDLER; }
ExtraICState GetExtraICState() const override { return Code::STORE_IC; } ExtraICState GetExtraICState() const override { return Code::STORE_IC; }
FieldIndex index() const { bool is_inobject() const { return IsInobjectBits::decode(minor_key_); }
DCHECK(store_mode() != StoreMapOnly);
int property_index_key = StoreFieldByIndexBits::decode(minor_key_);
return FieldIndex::FromFieldAccessStubKey(property_index_key);
}
Representation representation() const { Representation representation() const {
DCHECK(store_mode() != StoreMapOnly);
return Representation::FromKind(RepresentationBits::decode(minor_key_)); return Representation::FromKind(RepresentationBits::decode(minor_key_));
} }
StoreMode store_mode() const { return StoreModeBits::decode(minor_key_); } StoreMode store_mode() const { return StoreModeBits::decode(minor_key_); }
private: private:
class StoreFieldByIndexBits : public BitField<int, 0, 13> {}; class IsInobjectBits : public BitField<bool, 0, 1> {};
class RepresentationBits : public BitField<Representation::Kind, 13, 4> {}; class RepresentationBits
: public BitField<Representation::Kind, IsInobjectBits::kNext, 4> {};
STATIC_ASSERT(Representation::kNumRepresentations - 1 < STATIC_ASSERT(Representation::kNumRepresentations - 1 <
RepresentationBits::kMax); RepresentationBits::kMax);
class StoreModeBits : public BitField<StoreMode, 17, 2> {}; class StoreModeBits
: public BitField<StoreMode, RepresentationBits::kNext, 1> {};
DEFINE_CALL_INTERFACE_DESCRIPTOR(StoreTransition); DEFINE_CALL_INTERFACE_DESCRIPTOR(StoreNamedTransition);
DEFINE_TURBOFAN_CODE_STUB(StoreTransition, TurboFanCodeStub); DEFINE_TURBOFAN_CODE_STUB(StoreTransition, TurboFanCodeStub);
}; };
......
...@@ -135,9 +135,13 @@ void PropertyHandlerCompiler::DiscardVectorAndSlot() { ...@@ -135,9 +135,13 @@ void PropertyHandlerCompiler::DiscardVectorAndSlot() {
__ add(sp, sp, Operand(2 * kPointerSize)); __ add(sp, sp, Operand(2 * kPointerSize));
} }
void PropertyHandlerCompiler::PushReturnAddress(Register tmp) { UNREACHABLE(); } void PropertyHandlerCompiler::PushReturnAddress(Register tmp) {
// No-op. Return address is in lr register.
}
void PropertyHandlerCompiler::PopReturnAddress(Register tmp) { UNREACHABLE(); } void PropertyHandlerCompiler::PopReturnAddress(Register tmp) {
// No-op. Return address is in lr register.
}
void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup( void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup(
MacroAssembler* masm, Label* miss_label, Register receiver, MacroAssembler* masm, Label* miss_label, Register receiver,
......
...@@ -44,9 +44,13 @@ void PropertyHandlerCompiler::DiscardVectorAndSlot() { ...@@ -44,9 +44,13 @@ void PropertyHandlerCompiler::DiscardVectorAndSlot() {
__ Drop(2); __ Drop(2);
} }
void PropertyHandlerCompiler::PushReturnAddress(Register tmp) { UNREACHABLE(); } void PropertyHandlerCompiler::PushReturnAddress(Register tmp) {
// No-op. Return address is in lr register.
}
void PropertyHandlerCompiler::PopReturnAddress(Register tmp) { UNREACHABLE(); } void PropertyHandlerCompiler::PopReturnAddress(Register tmp) {
// No-op. Return address is in lr register.
}
void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup( void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup(
MacroAssembler* masm, Label* miss_label, Register receiver, MacroAssembler* masm, Label* miss_label, Register receiver,
......
...@@ -504,7 +504,7 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreTransition( ...@@ -504,7 +504,7 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreTransition(
PopVectorAndSlot(); PopVectorAndSlot();
} }
GenerateRestoreName(name); GenerateRestoreName(name);
StoreTransitionStub stub(isolate()); StoreMapStub stub(isolate());
GenerateTailCall(masm(), stub.GetCode()); GenerateTailCall(masm(), stub.GetCode());
} else { } else {
...@@ -520,10 +520,17 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreTransition( ...@@ -520,10 +520,17 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreTransition(
if (need_save_restore) { if (need_save_restore) {
PopVectorAndSlot(); PopVectorAndSlot();
} }
GenerateRestoreName(name); // We need to pass name on the stack.
StoreTransitionStub stub(isolate(), PopReturnAddress(this->name());
FieldIndex::ForDescriptor(*transition, descriptor), __ Push(name);
representation, store_mode); PushReturnAddress(this->name());
FieldIndex index = FieldIndex::ForDescriptor(*transition, descriptor);
__ Move(StoreNamedTransitionDescriptor::FieldOffsetRegister(),
Smi::FromInt(index.index() << kPointerSizeLog2));
StoreTransitionStub stub(isolate(), index.is_inobject(), representation,
store_mode);
GenerateTailCall(masm(), stub.GetCode()); GenerateTailCall(masm(), stub.GetCode());
} }
......
...@@ -129,9 +129,13 @@ void PropertyHandlerCompiler::DiscardVectorAndSlot() { ...@@ -129,9 +129,13 @@ void PropertyHandlerCompiler::DiscardVectorAndSlot() {
__ Addu(sp, sp, Operand(2 * kPointerSize)); __ Addu(sp, sp, Operand(2 * kPointerSize));
} }
void PropertyHandlerCompiler::PushReturnAddress(Register tmp) { UNREACHABLE(); } void PropertyHandlerCompiler::PushReturnAddress(Register tmp) {
// No-op. Return address is in ra register.
}
void PropertyHandlerCompiler::PopReturnAddress(Register tmp) { UNREACHABLE(); } void PropertyHandlerCompiler::PopReturnAddress(Register tmp) {
// No-op. Return address is in ra register.
}
void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup( void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup(
MacroAssembler* masm, Label* miss_label, Register receiver, MacroAssembler* masm, Label* miss_label, Register receiver,
......
...@@ -129,9 +129,13 @@ void PropertyHandlerCompiler::DiscardVectorAndSlot() { ...@@ -129,9 +129,13 @@ void PropertyHandlerCompiler::DiscardVectorAndSlot() {
__ Daddu(sp, sp, Operand(2 * kPointerSize)); __ Daddu(sp, sp, Operand(2 * kPointerSize));
} }
void PropertyHandlerCompiler::PushReturnAddress(Register tmp) { UNREACHABLE(); } void PropertyHandlerCompiler::PushReturnAddress(Register tmp) {
// No-op. Return address is in ra register.
}
void PropertyHandlerCompiler::PopReturnAddress(Register tmp) { UNREACHABLE(); } void PropertyHandlerCompiler::PopReturnAddress(Register tmp) {
// No-op. Return address is in ra register.
}
void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup( void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup(
MacroAssembler* masm, Label* miss_label, Register receiver, MacroAssembler* masm, Label* miss_label, Register receiver,
......
...@@ -130,9 +130,13 @@ void PropertyHandlerCompiler::DiscardVectorAndSlot() { ...@@ -130,9 +130,13 @@ void PropertyHandlerCompiler::DiscardVectorAndSlot() {
__ addi(sp, sp, Operand(2 * kPointerSize)); __ addi(sp, sp, Operand(2 * kPointerSize));
} }
void PropertyHandlerCompiler::PushReturnAddress(Register tmp) { UNREACHABLE(); } void PropertyHandlerCompiler::PushReturnAddress(Register tmp) {
// No-op. Return address is in lr register.
}
void PropertyHandlerCompiler::PopReturnAddress(Register tmp) { UNREACHABLE(); } void PropertyHandlerCompiler::PopReturnAddress(Register tmp) {
// No-op. Return address is in lr register.
}
void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup( void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup(
MacroAssembler* masm, Label* miss_label, Register receiver, MacroAssembler* masm, Label* miss_label, Register receiver,
......
...@@ -125,9 +125,13 @@ void PropertyHandlerCompiler::DiscardVectorAndSlot() { ...@@ -125,9 +125,13 @@ void PropertyHandlerCompiler::DiscardVectorAndSlot() {
__ la(sp, MemOperand(sp, 2 * kPointerSize)); __ la(sp, MemOperand(sp, 2 * kPointerSize));
} }
void PropertyHandlerCompiler::PushReturnAddress(Register tmp) { UNREACHABLE(); } void PropertyHandlerCompiler::PushReturnAddress(Register tmp) {
// No-op. Return address is in lr register.
}
void PropertyHandlerCompiler::PopReturnAddress(Register tmp) { UNREACHABLE(); } void PropertyHandlerCompiler::PopReturnAddress(Register tmp) {
// No-op. Return address is in lr register.
}
void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup( void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup(
MacroAssembler* masm, Label* miss_label, Register receiver, MacroAssembler* masm, Label* miss_label, Register receiver,
......
...@@ -44,9 +44,15 @@ void PropertyHandlerCompiler::DiscardVectorAndSlot() { ...@@ -44,9 +44,15 @@ void PropertyHandlerCompiler::DiscardVectorAndSlot() {
__ addp(rsp, Immediate(2 * kPointerSize)); __ addp(rsp, Immediate(2 * kPointerSize));
} }
void PropertyHandlerCompiler::PushReturnAddress(Register tmp) { UNREACHABLE(); } void PropertyHandlerCompiler::PushReturnAddress(Register tmp) {
MacroAssembler* masm = this->masm();
__ Push(tmp);
}
void PropertyHandlerCompiler::PopReturnAddress(Register tmp) { UNREACHABLE(); } void PropertyHandlerCompiler::PopReturnAddress(Register tmp) {
MacroAssembler* masm = this->masm();
__ Pop(tmp);
}
void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup( void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup(
MacroAssembler* masm, Label* miss_label, Register receiver, MacroAssembler* masm, Label* miss_label, Register receiver,
......
...@@ -160,6 +160,29 @@ void StoreTransitionDescriptor::InitializePlatformIndependent( ...@@ -160,6 +160,29 @@ void StoreTransitionDescriptor::InitializePlatformIndependent(
machine_types); machine_types);
} }
void StoreNamedTransitionDescriptor::InitializePlatformIndependent(
CallInterfaceDescriptorData* data) {
// kReceiver, kFieldOffset, kMap, kValue, kSlot, kVector, kName
MachineType machine_types[] = {
MachineType::AnyTagged(), MachineType::TaggedSigned(),
MachineType::AnyTagged(), MachineType::AnyTagged(),
MachineType::TaggedSigned(), MachineType::AnyTagged(),
MachineType::AnyTagged()};
data->InitializePlatformIndependent(arraysize(machine_types), 0,
machine_types);
}
void StoreNamedTransitionDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {
ReceiverRegister(), FieldOffsetRegister(), MapRegister(),
ValueRegister(), SlotRegister(), VectorRegister(),
NameRegister(),
};
int len = arraysize(registers) - kStackArgumentsCount;
data->InitializePlatformSpecific(len, registers);
}
void StoreGlobalViaContextDescriptor::InitializePlatformIndependent( void StoreGlobalViaContextDescriptor::InitializePlatformIndependent(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
// kSlot, kValue // kSlot, kValue
......
...@@ -24,6 +24,7 @@ class PlatformInterfaceDescriptor; ...@@ -24,6 +24,7 @@ class PlatformInterfaceDescriptor;
V(LoadGlobalWithVector) \ V(LoadGlobalWithVector) \
V(Store) \ V(Store) \
V(StoreWithVector) \ V(StoreWithVector) \
V(StoreNamedTransition) \
V(StoreTransition) \ V(StoreTransition) \
V(VarArgFunction) \ V(VarArgFunction) \
V(FastNewClosure) \ V(FastNewClosure) \
...@@ -349,6 +350,24 @@ class StoreTransitionDescriptor : public StoreDescriptor { ...@@ -349,6 +350,24 @@ class StoreTransitionDescriptor : public StoreDescriptor {
static const int kStackArgumentsCount = kPassLastArgsOnStack ? 3 : 0; static const int kStackArgumentsCount = kPassLastArgsOnStack ? 3 : 0;
}; };
class StoreNamedTransitionDescriptor : public StoreTransitionDescriptor {
public:
DEFINE_PARAMETERS(kReceiver, kFieldOffset, kMap, kValue, kSlot, kVector,
kName)
DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(StoreNamedTransitionDescriptor,
StoreTransitionDescriptor)
// Always pass name on the stack.
static const bool kPassLastArgsOnStack = true;
static const int kStackArgumentsCount =
StoreTransitionDescriptor::kStackArgumentsCount + 1;
static const Register NameRegister() { return no_reg; }
static const Register FieldOffsetRegister() {
return StoreTransitionDescriptor::NameRegister();
}
};
class StoreWithVectorDescriptor : public StoreDescriptor { class StoreWithVectorDescriptor : public StoreDescriptor {
public: public:
DEFINE_PARAMETERS(kReceiver, kName, kValue, kSlot, kVector) DEFINE_PARAMETERS(kReceiver, kName, kValue, kSlot, kVector)
......
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