Commit dadb5c0a authored by Leszek Swirski's avatar Leszek Swirski Committed by V8 LUCI CQ

[maglev] Support write-barrier-free field stores

For Smi values.

Bug: v8:7700
Change-Id: I903ef8aae818d64c3800206022c421c97e21a6f8
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3755143Reviewed-by: 's avatarToon Verwaest <verwaest@chromium.org>
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/main@{#81642}
parent 45867618
......@@ -882,10 +882,17 @@ bool MaglevGraphBuilder::TryBuildMonomorphicStoreFromSmiHandler(
{object}, JSReceiver::kPropertiesOrHashOffset);
}
int field_index = StoreHandler::FieldIndexBits::decode(handler);
int offset = field_index * kTaggedSize;
ValueNode* value = GetAccumulatorTagged();
if (representation == Representation::kSmi) {
AddNewNode<CheckSmi>({value});
} else if (representation == Representation::kHeapObject) {
AddNewNode<StoreTaggedFieldNoWriteBarrier>({store_target, value}, offset);
return true;
}
if (representation == Representation::kHeapObject) {
FieldType descriptors_field_type =
map.instance_descriptors().object()->GetFieldType(descriptor_idx);
if (descriptors_field_type.IsNone()) {
......@@ -908,12 +915,7 @@ bool MaglevGraphBuilder::TryBuildMonomorphicStoreFromSmiHandler(
AddNewNode<CheckHeapObject>({value});
}
}
int field_index = StoreHandler::FieldIndexBits::decode(handler);
// TODO(leszeks): Avoid write barrier for Smi stores.
AddNewNode<StoreTaggedField>({store_target, value},
field_index * kTaggedSize);
AddNewNode<StoreTaggedFieldWithWriteBarrier>({store_target, value}, offset);
return true;
}
......
......@@ -133,7 +133,9 @@ class MaglevGraphVerifier {
case Opcode::kGenericLessThanOrEqual:
case Opcode::kGenericStrictEqual:
// TODO(victorgomes): Can we check that first input is an Object?
case Opcode::kStoreTaggedField:
case Opcode::kStoreTaggedFieldNoWriteBarrier:
// TODO(victorgomes): Can we check that second input is a Smi?
case Opcode::kStoreTaggedFieldWithWriteBarrier:
case Opcode::kLoadNamedGeneric:
DCHECK_EQ(node->input_count(), 2);
CheckValueInputIs(node, 0, ValueRepresentation::kTagged);
......
......@@ -779,7 +779,26 @@ void LoadDoubleField::PrintParams(std::ostream& os,
os << "(0x" << std::hex << offset() << std::dec << ")";
}
void StoreTaggedField::AllocateVreg(MaglevVregAllocationState* vreg_state) {
void StoreTaggedFieldNoWriteBarrier::AllocateVreg(
MaglevVregAllocationState* vreg_state) {
UseRegister(object_input());
UseRegister(value_input());
}
void StoreTaggedFieldNoWriteBarrier::GenerateCode(
MaglevCodeGenState* code_gen_state, const ProcessingState& state) {
Register object = ToRegister(object_input());
Register value = ToRegister(value_input());
__ AssertNotSmi(object);
__ StoreTaggedField(FieldOperand(object, offset()), value);
}
void StoreTaggedFieldNoWriteBarrier::PrintParams(
std::ostream& os, MaglevGraphLabeller* graph_labeller) const {
os << "(" << std::hex << offset() << std::dec << ")";
}
void StoreTaggedFieldWithWriteBarrier::AllocateVreg(
MaglevVregAllocationState* vreg_state) {
UseFixed(object_input(), WriteBarrierDescriptor::ObjectRegister());
UseRegister(value_input());
// We need the slot address to be free, and an additional scratch register
......@@ -789,8 +808,8 @@ void StoreTaggedField::AllocateVreg(MaglevVregAllocationState* vreg_state) {
RequireSpecificTemporary(WriteBarrierDescriptor::SlotAddressRegister());
set_temporaries_needed(1);
}
void StoreTaggedField::GenerateCode(MaglevCodeGenState* code_gen_state,
const ProcessingState& state) {
void StoreTaggedFieldWithWriteBarrier::GenerateCode(
MaglevCodeGenState* code_gen_state, const ProcessingState& state) {
Register object = ToRegister(object_input());
Register value = ToRegister(value_input());
......@@ -809,8 +828,8 @@ void StoreTaggedField::GenerateCode(MaglevCodeGenState* code_gen_state,
WriteBarrierDescriptor::SlotAddressRegister(),
SaveFPRegsMode::kSave);
}
void StoreTaggedField::PrintParams(std::ostream& os,
MaglevGraphLabeller* graph_labeller) const {
void StoreTaggedFieldWithWriteBarrier::PrintParams(
std::ostream& os, MaglevGraphLabeller* graph_labeller) const {
os << "(" << std::hex << offset() << std::dec << ")";
}
......
......@@ -144,15 +144,16 @@ class CompactInterpreterFrameState;
V(ConstantGapMove) \
V(GapMove)
#define NODE_LIST(V) \
V(CheckMaps) \
V(CheckSmi) \
V(CheckHeapObject) \
V(CheckMapsWithMigration) \
V(StoreTaggedField) \
V(IncreaseInterruptBudget) \
V(ReduceInterruptBudget) \
GAP_MOVE_NODE_LIST(V) \
#define NODE_LIST(V) \
V(CheckMaps) \
V(CheckSmi) \
V(CheckHeapObject) \
V(CheckMapsWithMigration) \
V(StoreTaggedFieldNoWriteBarrier) \
V(StoreTaggedFieldWithWriteBarrier) \
V(IncreaseInterruptBudget) \
V(ReduceInterruptBudget) \
GAP_MOVE_NODE_LIST(V) \
VALUE_NODE_LIST(V)
#define CONDITIONAL_CONTROL_NODE_LIST(V) \
......@@ -1838,11 +1839,37 @@ class LoadDoubleField : public FixedInputValueNodeT<1, LoadDoubleField> {
const int offset_;
};
class StoreTaggedField : public FixedInputNodeT<2, StoreTaggedField> {
using Base = FixedInputNodeT<2, StoreTaggedField>;
class StoreTaggedFieldNoWriteBarrier
: public FixedInputNodeT<2, StoreTaggedFieldNoWriteBarrier> {
using Base = FixedInputNodeT<2, StoreTaggedFieldNoWriteBarrier>;
public:
explicit StoreTaggedField(uint64_t bitfield, int offset)
explicit StoreTaggedFieldNoWriteBarrier(uint64_t bitfield, int offset)
: Base(bitfield), offset_(offset) {}
static constexpr OpProperties kProperties = OpProperties::Writing();
int offset() const { return offset_; }
static constexpr int kObjectIndex = 0;
static constexpr int kValueIndex = 1;
Input& object_input() { return input(kObjectIndex); }
Input& value_input() { return input(kValueIndex); }
void AllocateVreg(MaglevVregAllocationState*);
void GenerateCode(MaglevCodeGenState*, const ProcessingState&);
void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
private:
const int offset_;
};
class StoreTaggedFieldWithWriteBarrier
: public FixedInputNodeT<2, StoreTaggedFieldWithWriteBarrier> {
using Base = FixedInputNodeT<2, StoreTaggedFieldWithWriteBarrier>;
public:
explicit StoreTaggedFieldWithWriteBarrier(uint64_t bitfield, int offset)
: Base(bitfield), offset_(offset) {}
static constexpr OpProperties kProperties = OpProperties::Writing();
......
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