Commit ad89010f authored by Toon Verwaest's avatar Toon Verwaest Committed by V8 LUCI CQ

[maglev] Inline store of smi/heapobject fields

To implement this, this cl introduces explicit check smi/heapobject
nodes that we use for the value (and also separate from CheckMaps
now). This will allow us to remove duplicate checks later.

The performance of StoreField itself isn't vastly better due to fixed
register requirements though.

Bug: v8:7700
Change-Id: I98caa290c88be64f41154fd232bde98fb46ce497
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3747870
Commit-Queue: Toon Verwaest <verwaest@chromium.org>
Reviewed-by: 's avatarLeszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/main@{#81576}
parent 1f16e67b
...@@ -686,6 +686,7 @@ MAGLEV_UNIMPLEMENTED_BYTECODE(StaLookupSlot) ...@@ -686,6 +686,7 @@ MAGLEV_UNIMPLEMENTED_BYTECODE(StaLookupSlot)
void MaglevGraphBuilder::BuildMapCheck(ValueNode* object, void MaglevGraphBuilder::BuildMapCheck(ValueNode* object,
const compiler::MapRef& map) { const compiler::MapRef& map) {
AddNewNode<CheckHeapObject>({object});
if (map.is_migration_target()) { if (map.is_migration_target()) {
AddNewNode<CheckMapsWithMigration>({object}, map); AddNewNode<CheckMapsWithMigration>({object}, map);
} else { } else {
...@@ -884,9 +885,14 @@ void MaglevGraphBuilder::VisitSetNamedProperty() { ...@@ -884,9 +885,14 @@ void MaglevGraphBuilder::VisitSetNamedProperty() {
Representation::Kind representation = Representation::Kind representation =
StoreHandler::RepresentationBits::decode(smi_handler); StoreHandler::RepresentationBits::decode(smi_handler);
if (kind == StoreHandler::Kind::kField && if (kind == StoreHandler::Kind::kField &&
representation == Representation::kTagged) { representation != Representation::kDouble) {
BuildMapCheck(object, named_feedback.maps()[0]); BuildMapCheck(object, named_feedback.maps()[0]);
ValueNode* value = GetAccumulatorTagged(); ValueNode* value = GetAccumulatorTagged();
if (representation == Representation::kSmi) {
AddNewNode<CheckSmi>({value});
} else if (representation == Representation::kHeapObject) {
AddNewNode<CheckHeapObject>({value});
}
AddNewNode<StoreField>({object, value}, smi_handler); AddNewNode<StoreField>({object, value}, smi_handler);
return; return;
} }
......
...@@ -87,8 +87,10 @@ class MaglevGraphVerifier { ...@@ -87,8 +87,10 @@ class MaglevGraphVerifier {
case Opcode::kLoadGlobal: case Opcode::kLoadGlobal:
case Opcode::kLoadTaggedField: case Opcode::kLoadTaggedField:
// TODO(victorgomes): Can we check that the input is actually a receiver? // TODO(victorgomes): Can we check that the input is actually a receiver?
case Opcode::kCheckHeapObject:
case Opcode::kCheckMaps: case Opcode::kCheckMaps:
case Opcode::kCheckMapsWithMigration: case Opcode::kCheckMapsWithMigration:
case Opcode::kCheckSmi:
// TODO(victorgomes): Can we check that the input is Boolean? // TODO(victorgomes): Can we check that the input is Boolean?
case Opcode::kBranchIfToBooleanTrue: case Opcode::kBranchIfToBooleanTrue:
case Opcode::kBranchIfTrue: case Opcode::kBranchIfTrue:
......
...@@ -612,16 +612,12 @@ void CreateShallowObjectLiteral::GenerateCode( ...@@ -612,16 +612,12 @@ void CreateShallowObjectLiteral::GenerateCode(
} }
void CheckMaps::AllocateVreg(MaglevVregAllocationState* vreg_state) { void CheckMaps::AllocateVreg(MaglevVregAllocationState* vreg_state) {
UseRegister(actual_map_input()); UseRegister(receiver_input());
set_temporaries_needed(1); set_temporaries_needed(1);
} }
void CheckMaps::GenerateCode(MaglevCodeGenState* code_gen_state, void CheckMaps::GenerateCode(MaglevCodeGenState* code_gen_state,
const ProcessingState& state) { const ProcessingState& state) {
Register object = ToRegister(actual_map_input()); Register object = ToRegister(receiver_input());
Condition is_smi = __ CheckSmi(object);
EmitEagerDeoptIf(is_smi, code_gen_state, this);
RegList temps = temporaries(); RegList temps = temporaries();
Register map_tmp = temps.PopFirst(); Register map_tmp = temps.PopFirst();
...@@ -633,19 +629,38 @@ void CheckMaps::PrintParams(std::ostream& os, ...@@ -633,19 +629,38 @@ void CheckMaps::PrintParams(std::ostream& os,
MaglevGraphLabeller* graph_labeller) const { MaglevGraphLabeller* graph_labeller) const {
os << "(" << *map().object() << ")"; os << "(" << *map().object() << ")";
} }
void CheckSmi::AllocateVreg(MaglevVregAllocationState* vreg_state) {
UseRegister(receiver_input());
}
void CheckSmi::GenerateCode(MaglevCodeGenState* code_gen_state,
const ProcessingState& state) {
Register object = ToRegister(receiver_input());
Condition is_smi = __ CheckSmi(object);
EmitEagerDeoptIf(NegateCondition(is_smi), code_gen_state, this);
}
void CheckSmi::PrintParams(std::ostream& os,
MaglevGraphLabeller* graph_labeller) const {}
void CheckHeapObject::AllocateVreg(MaglevVregAllocationState* vreg_state) {
UseRegister(receiver_input());
}
void CheckHeapObject::GenerateCode(MaglevCodeGenState* code_gen_state,
const ProcessingState& state) {
Register object = ToRegister(receiver_input());
Condition is_smi = __ CheckSmi(object);
EmitEagerDeoptIf(is_smi, code_gen_state, this);
}
void CheckHeapObject::PrintParams(std::ostream& os,
MaglevGraphLabeller* graph_labeller) const {}
void CheckMapsWithMigration::AllocateVreg( void CheckMapsWithMigration::AllocateVreg(
MaglevVregAllocationState* vreg_state) { MaglevVregAllocationState* vreg_state) {
UseRegister(actual_map_input()); UseRegister(receiver_input());
set_temporaries_needed(1); set_temporaries_needed(1);
} }
void CheckMapsWithMigration::GenerateCode(MaglevCodeGenState* code_gen_state, void CheckMapsWithMigration::GenerateCode(MaglevCodeGenState* code_gen_state,
const ProcessingState& state) { const ProcessingState& state) {
Register object = ToRegister(actual_map_input()); Register object = ToRegister(receiver_input());
Condition is_smi = __ CheckSmi(object);
EmitEagerDeoptIf(is_smi, code_gen_state, this);
RegList temps = temporaries(); RegList temps = temporaries();
Register map_tmp = temps.PopFirst(); Register map_tmp = temps.PopFirst();
......
...@@ -146,6 +146,8 @@ class CompactInterpreterFrameState; ...@@ -146,6 +146,8 @@ class CompactInterpreterFrameState;
#define NODE_LIST(V) \ #define NODE_LIST(V) \
V(CheckMaps) \ V(CheckMaps) \
V(CheckSmi) \
V(CheckHeapObject) \
V(CheckMapsWithMigration) \ V(CheckMapsWithMigration) \
V(StoreField) \ V(StoreField) \
GAP_MOVE_NODE_LIST(V) \ GAP_MOVE_NODE_LIST(V) \
...@@ -1665,8 +1667,8 @@ class CheckMaps : public FixedInputNodeT<1, CheckMaps> { ...@@ -1665,8 +1667,8 @@ class CheckMaps : public FixedInputNodeT<1, CheckMaps> {
compiler::MapRef map() const { return map_; } compiler::MapRef map() const { return map_; }
static constexpr int kActualMapIndex = 0; static constexpr int kReceiverIndex = 0;
Input& actual_map_input() { return input(kActualMapIndex); } Input& receiver_input() { return input(kReceiverIndex); }
void AllocateVreg(MaglevVregAllocationState*); void AllocateVreg(MaglevVregAllocationState*);
void GenerateCode(MaglevCodeGenState*, const ProcessingState&); void GenerateCode(MaglevCodeGenState*, const ProcessingState&);
...@@ -1675,6 +1677,37 @@ class CheckMaps : public FixedInputNodeT<1, CheckMaps> { ...@@ -1675,6 +1677,37 @@ class CheckMaps : public FixedInputNodeT<1, CheckMaps> {
private: private:
const compiler::MapRef map_; const compiler::MapRef map_;
}; };
class CheckSmi : public FixedInputNodeT<1, CheckSmi> {
using Base = FixedInputNodeT<1, CheckSmi>;
public:
explicit CheckSmi(uint64_t bitfield) : Base(bitfield) {}
static constexpr OpProperties kProperties = OpProperties::EagerDeopt();
static constexpr int kReceiverIndex = 0;
Input& receiver_input() { return input(kReceiverIndex); }
void AllocateVreg(MaglevVregAllocationState*);
void GenerateCode(MaglevCodeGenState*, const ProcessingState&);
void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
};
class CheckHeapObject : public FixedInputNodeT<1, CheckHeapObject> {
using Base = FixedInputNodeT<1, CheckHeapObject>;
public:
explicit CheckHeapObject(uint64_t bitfield) : Base(bitfield) {}
static constexpr OpProperties kProperties = OpProperties::EagerDeopt();
static constexpr int kReceiverIndex = 0;
Input& receiver_input() { return input(kReceiverIndex); }
void AllocateVreg(MaglevVregAllocationState*);
void GenerateCode(MaglevCodeGenState*, const ProcessingState&);
void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
};
class CheckMapsWithMigration class CheckMapsWithMigration
: public FixedInputNodeT<1, CheckMapsWithMigration> { : public FixedInputNodeT<1, CheckMapsWithMigration> {
...@@ -1695,8 +1728,8 @@ class CheckMapsWithMigration ...@@ -1695,8 +1728,8 @@ class CheckMapsWithMigration
compiler::MapRef map() const { return map_; } compiler::MapRef map() const { return map_; }
static constexpr int kActualMapIndex = 0; static constexpr int kReceiverIndex = 0;
Input& actual_map_input() { return input(kActualMapIndex); } Input& receiver_input() { return input(kReceiverIndex); }
void AllocateVreg(MaglevVregAllocationState*); void AllocateVreg(MaglevVregAllocationState*);
void GenerateCode(MaglevCodeGenState*, const ProcessingState&); void GenerateCode(MaglevCodeGenState*, const ProcessingState&);
......
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