[maglev] Unsafely untag known smis

Bug: v8:7700
Change-Id: I60800b2a1ba9226289ca679ecf71766199b95850
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3987863
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
Commit-Queue: Toon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/main@{#83975}
This commit is contained in:
Toon Verwaest 2022-10-28 10:59:56 +02:00 committed by V8 LUCI CQ
parent 6127ada1be
commit ba091da0b0
5 changed files with 51 additions and 15 deletions

View File

@ -1176,9 +1176,16 @@ bool MaglevGraphBuilder::EnsureType(ValueNode* node, NodeType type,
return false;
}
ValueNode* MaglevGraphBuilder::BuildSmiUntag(ValueNode* node) {
if (EnsureType(node, NodeType::kSmi)) {
return AddNewNode<UnsafeSmiUntag>({node});
} else {
return AddNewNode<CheckedSmiUntag>({node});
}
}
void MaglevGraphBuilder::BuildCheckSmi(ValueNode* object) {
if (EnsureType(object, NodeType::kSmi)) return;
// TODO(leszeks): Figure out a way to also handle CheckedSmiUntag.
AddNewNode<CheckSmi>({object});
}
@ -1745,20 +1752,17 @@ ValueNode* MaglevGraphBuilder::GetInt32ElementIndex(ValueNode* object) {
case ValueRepresentation::kTagged:
if (SmiConstant* constant = object->TryCast<SmiConstant>()) {
return GetInt32Constant(constant->value().value());
} else {
} else if (CheckType(object, NodeType::kSmi)) {
NodeInfo* node_info = known_node_aspects().GetOrCreateInfoFor(object);
if (node_info->is_smi()) {
if (!node_info->int32_alternative) {
// TODO(leszeks): This could be unchecked.
node_info->int32_alternative =
AddNewNode<CheckedSmiUntag>({object});
}
return node_info->int32_alternative;
} else {
// TODO(leszeks): Cache this knowledge/converted value somehow on
// the node info.
return AddNewNode<CheckedObjectToIndex>({object});
if (!node_info->int32_alternative) {
// TODO(leszeks): This could be unchecked.
node_info->int32_alternative = AddNewNode<UnsafeSmiUntag>({object});
}
return node_info->int32_alternative;
} else {
// TODO(leszeks): Cache this knowledge/converted value somehow on
// the node info.
return AddNewNode<CheckedObjectToIndex>({object});
}
case ValueRepresentation::kInt32:
// Already good.
@ -3781,7 +3785,7 @@ void MaglevGraphBuilder::VisitSwitchOnGeneratorState() {
BasicBlockRef* ref = &targets[offset.case_value - case_value_base];
new (ref) BasicBlockRef(&jump_targets_[offset.target_offset]);
}
ValueNode* case_value = AddNewNode<CheckedSmiUntag>({state});
ValueNode* case_value = AddNewNode<UnsafeSmiUntag>({state});
BasicBlock* generator_prologue_block = FinishBlock<Switch>(
{case_value}, case_value_base, targets, offsets.size());
for (interpreter::JumpTableTargetOffset offset : offsets) {
@ -3833,7 +3837,7 @@ void MaglevGraphBuilder::VisitResumeGenerator() {
// register file length.
ValueNode* array_length_smi =
AddNewNode<LoadTaggedField>({array}, FixedArrayBase::kLengthOffset);
ValueNode* array_length = AddNewNode<CheckedSmiUntag>({array_length_smi});
ValueNode* array_length = AddNewNode<UnsafeSmiUntag>({array_length_smi});
ValueNode* register_size = GetInt32Constant(
parameter_count_without_receiver() + registers.register_count());
AddNewNode<AssertInt32>(

View File

@ -1000,6 +1000,8 @@ class MaglevGraphBuilder {
bool TryBuildPropertyCellAccess(
const compiler::GlobalAccessFeedback& global_access_feedback);
ValueNode* BuildSmiUntag(ValueNode* node);
void BuildCheckSmi(ValueNode* object);
void BuildCheckNumber(ValueNode* object);
void BuildCheckHeapObject(ValueNode* object);

View File

@ -107,6 +107,7 @@ class MaglevGraphVerifier {
DCHECK_EQ(node->input_count(), 0);
break;
case Opcode::kCheckedSmiUntag:
case Opcode::kUnsafeSmiUntag:
case Opcode::kGenericBitwiseNot:
case Opcode::kGenericDecrement:
case Opcode::kGenericIncrement:

View File

@ -2990,6 +2990,18 @@ void CheckedSmiUntag::GenerateCode(MaglevAssembler* masm,
__ SmiToInt32(value);
}
void UnsafeSmiUntag::AllocateVreg(MaglevVregAllocationState* vreg_state) {
UseRegister(input());
DefineSameAsFirst(vreg_state, this);
}
void UnsafeSmiUntag::GenerateCode(MaglevAssembler* masm,
const ProcessingState& state) {
Register value = ToRegister(input());
__ AssertSmi(value);
__ SmiToInt32(value);
}
void CheckedSmiTag::AllocateVreg(MaglevVregAllocationState* vreg_state) {
UseRegister(input());
DefineSameAsFirst(vreg_state, this);

View File

@ -168,6 +168,7 @@ class CompactInterpreterFrameState;
V(CheckedSmiTag) \
V(UnsafeSmiTag) \
V(CheckedSmiUntag) \
V(UnsafeSmiUntag) \
V(CheckedInternalizedString) \
V(CheckedObjectToIndex) \
V(ChangeInt32ToFloat64) \
@ -1793,6 +1794,22 @@ class CheckedSmiUntag : public FixedInputValueNodeT<1, CheckedSmiUntag> {
void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
};
class UnsafeSmiUntag : public FixedInputValueNodeT<1, UnsafeSmiUntag> {
using Base = FixedInputValueNodeT<1, UnsafeSmiUntag>;
public:
explicit UnsafeSmiUntag(uint64_t bitfield) : Base(bitfield) {}
static constexpr OpProperties kProperties =
OpProperties::Int32() | OpProperties::ConversionNode();
Input& input() { return Node::input(0); }
void AllocateVreg(MaglevVregAllocationState*);
void GenerateCode(MaglevAssembler*, const ProcessingState&);
void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
};
class Int32Constant : public FixedInputValueNodeT<0, Int32Constant> {
using Base = FixedInputValueNodeT<0, Int32Constant>;