Commit 93fc4fea authored by ishell's avatar ishell Committed by Commit bot

[stubs] Port StoreFieldStub to TurboFan.

BUG=v8:5269

Review-Url: https://codereview.chromium.org/2325013003
Cr-Commit-Position: refs/heads/master@{#39350}
parent 4cf5ee6b
......@@ -47,7 +47,7 @@ Node* CodeStubAssembler::EmptyStringConstant() {
}
Node* CodeStubAssembler::HeapNumberMapConstant() {
return HeapConstant(isolate()->factory()->heap_number_map());
return LoadRoot(Heap::kHeapNumberMapRootIndex);
}
Node* CodeStubAssembler::NoContextConstant() {
......@@ -1241,14 +1241,19 @@ Node* CodeStubAssembler::StoreFixedDoubleArrayElement(
return StoreNoWriteBarrier(rep, object, offset, value);
}
Node* CodeStubAssembler::AllocateHeapNumber() {
Node* CodeStubAssembler::AllocateHeapNumber(MutableMode mode) {
Node* result = Allocate(HeapNumber::kSize, kNone);
StoreMapNoWriteBarrier(result, HeapNumberMapConstant());
Heap::RootListIndex heap_map_index =
mode == IMMUTABLE ? Heap::kHeapNumberMapRootIndex
: Heap::kMutableHeapNumberMapRootIndex;
Node* map = LoadRoot(heap_map_index);
StoreMapNoWriteBarrier(result, map);
return result;
}
Node* CodeStubAssembler::AllocateHeapNumberWithValue(Node* value) {
Node* result = AllocateHeapNumber();
Node* CodeStubAssembler::AllocateHeapNumberWithValue(Node* value,
MutableMode mode) {
Node* result = AllocateHeapNumber(mode);
StoreHeapNumberValue(result, value);
return result;
}
......@@ -4443,6 +4448,76 @@ void CodeStubAssembler::LoadGlobalIC(const LoadICParameters* p) {
}
}
Node* CodeStubAssembler::PrepareValueForWrite(Node* value,
Representation representation,
Label* bailout) {
if (representation.IsDouble()) {
Variable var_value(this, MachineRepresentation::kFloat64);
Label if_smi(this), if_heap_object(this), done(this);
Branch(WordIsSmi(value), &if_smi, &if_heap_object);
Bind(&if_smi);
{
var_value.Bind(SmiToFloat64(value));
Goto(&done);
}
Bind(&if_heap_object);
{
GotoUnless(
Word32Equal(LoadInstanceType(value), Int32Constant(HEAP_NUMBER_TYPE)),
bailout);
var_value.Bind(LoadHeapNumberValue(value));
Goto(&done);
}
Bind(&done);
value = var_value.value();
} else if (representation.IsHeapObject()) {
// Field type is checked by the handler, here we only check if the value
// is a heap object.
GotoIf(WordIsSmi(value), bailout);
} else if (representation.IsSmi()) {
GotoUnless(WordIsSmi(value), bailout);
} else {
DCHECK(representation.IsTagged());
}
return value;
}
void CodeStubAssembler::StoreNamedField(Node* object, FieldIndex index,
Representation representation,
Node* value, bool transition_to_field) {
DCHECK_EQ(index.is_double(), representation.IsDouble());
bool store_value_as_double = representation.IsDouble();
int offset = index.offset();
Node* property_storage = object;
if (!index.is_inobject()) {
property_storage = LoadProperties(object);
}
if (representation.IsDouble()) {
if (!FLAG_unbox_double_fields || !index.is_inobject()) {
if (transition_to_field) {
Node* heap_number = AllocateHeapNumberWithValue(value, MUTABLE);
// Store the new mutable heap number into the object.
value = heap_number;
store_value_as_double = false;
} else {
// Load the heap number.
property_storage = LoadObjectField(property_storage, offset);
// Store the double value into it.
offset = HeapNumber::kValueOffset;
}
}
}
if (store_value_as_double) {
StoreObjectFieldNoWriteBarrier(property_storage, offset, value,
MachineRepresentation::kFloat64);
} else {
StoreObjectField(property_storage, offset, value);
}
}
Node* CodeStubAssembler::EnumLength(Node* map) {
Node* bitfield_3 = LoadMapBitField3(map);
Node* enum_length = BitFieldDecode<Map::EnumLengthBits>(bitfield_3);
......
......@@ -304,9 +304,10 @@ class CodeStubAssembler : public compiler::CodeAssembler {
ParameterMode parameter_mode = INTEGER_PARAMETERS);
// Allocate a HeapNumber without initializing its value.
compiler::Node* AllocateHeapNumber();
compiler::Node* AllocateHeapNumber(MutableMode mode = IMMUTABLE);
// Allocate a HeapNumber with a specific value.
compiler::Node* AllocateHeapNumberWithValue(compiler::Node* value);
compiler::Node* AllocateHeapNumberWithValue(compiler::Node* value,
MutableMode mode = IMMUTABLE);
// Allocate a SeqOneByteString with the given length.
compiler::Node* AllocateSeqOneByteString(int length);
compiler::Node* AllocateSeqOneByteString(compiler::Node* context,
......@@ -635,6 +636,14 @@ class CodeStubAssembler : public compiler::CodeAssembler {
compiler::Node* name, Label* if_handler,
Variable* var_handler, Label* if_miss);
compiler::Node* PrepareValueForWrite(compiler::Node* value,
Representation representation,
Label* bailout);
void StoreNamedField(compiler::Node* object, FieldIndex index,
Representation representation, compiler::Node* value,
bool transition_to_field);
void LoadIC(const LoadICParameters* p);
void LoadGlobalIC(const LoadICParameters* p);
void KeyedLoadIC(const LoadICParameters* p);
......
......@@ -1099,18 +1099,6 @@ void CodeStubGraphBuilderBase::BuildStoreNamedField(
}
template <>
HValue* CodeStubGraphBuilder<StoreFieldStub>::BuildCodeStub() {
BuildStoreNamedField(GetParameter(Descriptor::kReceiver),
GetParameter(Descriptor::kValue), casted_stub()->index(),
casted_stub()->representation(), false);
return GetParameter(Descriptor::kValue);
}
Handle<Code> StoreFieldStub::GenerateCode() { return DoGenerateCode(this); }
template <>
HValue* CodeStubGraphBuilder<StoreTransitionStub>::BuildCodeStub() {
HValue* object = GetParameter(StoreTransitionHelper::ReceiverIndex());
......
......@@ -4434,6 +4434,43 @@ void LoadApiGetterStub::GenerateAssembly(CodeStubAssembler* assembler) const {
holder, callback);
}
void StoreFieldStub::GenerateAssembly(CodeStubAssembler* assembler) const {
typedef CodeStubAssembler::Label Label;
typedef compiler::Node Node;
FieldIndex index = this->index();
Representation representation = this->representation();
assembler->Comment("StoreFieldStub: inobject=%d, offset=%d, rep=%s",
index.is_inobject(), index.offset(),
representation.Mnemonic());
Node* receiver = assembler->Parameter(Descriptor::kReceiver);
Node* name = assembler->Parameter(Descriptor::kName);
Node* value = assembler->Parameter(Descriptor::kValue);
Node* slot = assembler->Parameter(Descriptor::kSlot);
Node* vector = assembler->Parameter(Descriptor::kVector);
Node* context = assembler->Parameter(Descriptor::kContext);
Label miss(assembler);
Node* prepared_value =
assembler->PrepareValueForWrite(value, representation, &miss);
assembler->StoreNamedField(receiver, index, representation, prepared_value,
false);
assembler->Return(value);
// Only stores to tagged field can't bailout.
if (!representation.IsTagged()) {
assembler->Bind(&miss);
{
assembler->Comment("Miss");
assembler->TailCallRuntime(Runtime::kStoreIC_Miss, context, receiver,
name, value, slot, vector);
}
}
}
// static
compiler::Node* LessThanStub::Generate(CodeStubAssembler* assembler,
compiler::Node* lhs, compiler::Node* rhs,
......
......@@ -90,7 +90,6 @@ class ObjectLiteral;
V(LoadField) \
V(LoadScriptContextField) \
V(StoreFastElement) \
V(StoreField) \
V(StoreGlobal) \
V(StoreScriptContextField) \
V(StoreTransition) \
......@@ -167,6 +166,7 @@ class ObjectLiteral;
V(GetProperty) \
V(LoadICTF) \
V(KeyedLoadICTF) \
V(StoreField) \
V(StoreInterceptor) \
V(LoadApiGetter) \
V(LoadIndexedInterceptor) \
......@@ -1631,37 +1631,38 @@ class LoadApiGetterStub : public TurboFanCodeStub {
DEFINE_TURBOFAN_CODE_STUB(LoadApiGetter, TurboFanCodeStub);
};
class StoreFieldStub : public HandlerStub {
class StoreFieldStub : public TurboFanCodeStub {
public:
StoreFieldStub(Isolate* isolate, FieldIndex index,
Representation representation)
: HandlerStub(isolate) {
: TurboFanCodeStub(isolate) {
int property_index_key = index.GetFieldAccessStubKey();
uint8_t repr = PropertyDetails::EncodeRepresentation(representation);
set_sub_minor_key(StoreFieldByIndexBits::encode(property_index_key) |
RepresentationBits::encode(repr));
minor_key_ = StoreFieldByIndexBits::encode(property_index_key) |
RepresentationBits::encode(representation.kind());
}
Code::Kind GetCodeKind() const override { return Code::HANDLER; }
ExtraICState GetExtraICState() const override { return Code::STORE_IC; }
FieldIndex index() const {
int property_index_key = StoreFieldByIndexBits::decode(sub_minor_key());
int property_index_key = StoreFieldByIndexBits::decode(minor_key_);
return FieldIndex::FromFieldAccessStubKey(property_index_key);
}
Representation representation() {
uint8_t repr = RepresentationBits::decode(sub_minor_key());
return PropertyDetails::DecodeRepresentation(repr);
Representation representation() const {
return Representation::FromKind(RepresentationBits::decode(minor_key_));
}
protected:
Code::Kind kind() const override { return Code::STORE_IC; }
private:
class StoreFieldByIndexBits : public BitField<int, 0, 13> {};
class RepresentationBits : public BitField<uint8_t, 13, 4> {};
class RepresentationBits
: public BitField<Representation::Kind, StoreFieldByIndexBits::kNext, 4> {
};
STATIC_ASSERT(Representation::kNumRepresentations - 1 <
RepresentationBits::kMax);
// TODO(ishell): The stub uses only kReceiver and kValue parameters.
DEFINE_CALL_INTERFACE_DESCRIPTOR(StoreWithVector);
DEFINE_HANDLER_CODE_STUB(StoreField, HandlerStub);
DEFINE_TURBOFAN_CODE_STUB(StoreField, TurboFanCodeStub);
};
......
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