Commit ac5e66d4 authored by Victor Gomes's avatar Victor Gomes Committed by V8 LUCI CQ

[maglev] Add some debug code to ResumeGenerator

This mimics Ignition, which calls AbortIfRegisterCountInvalid.

This adds a --maglev-assert flag, since we do not want to emit
different code per IR node for debug vs. release modes.

Bug: v8:7700
Change-Id: Iddb17f0ccadf9d6009b242883b2e5d126875c844
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3876385Reviewed-by: 's avatarLeszek Swirski <leszeks@chromium.org>
Auto-Submit: Victor Gomes <victorgomes@chromium.org>
Commit-Queue: Victor Gomes <victorgomes@chromium.org>
Cr-Commit-Position: refs/heads/main@{#83081}
parent 22543d70
......@@ -468,6 +468,7 @@ DEFINE_BOOL_READONLY(stress_maglev, false, "trigger maglev compilation earlier")
#endif // V8_ENABLE_MAGLEV
DEFINE_STRING(maglev_filter, "*", "optimization filter for the maglev compiler")
DEFINE_BOOL(maglev_assert, false, "insert extra assertion in maglev code")
DEFINE_BOOL(maglev_break_on_entry, false, "insert an int3 on maglev entries")
DEFINE_BOOL(print_maglev_graph, false, "print maglev graph")
DEFINE_BOOL(print_maglev_code, false, "print maglev code")
......
......@@ -2927,6 +2927,20 @@ void MaglevGraphBuilder::VisitResumeGenerator() {
ValueNode* array = AddNewNode<LoadTaggedField>(
{generator}, JSGeneratorObject::kParametersAndRegistersOffset);
interpreter::RegisterList registers = iterator_.GetRegisterListOperand(1);
if (FLAG_maglev_assert) {
// Check if register count is invalid, that is, larger than the
// register file length.
ValueNode* array_length_smi =
AddNewNode<LoadTaggedField>({array}, FixedArrayBase::kLengthOffset);
ValueNode* array_length = AddNewNode<CheckedSmiUntag>({array_length_smi});
ValueNode* register_size = GetInt32Constant(
parameter_count_without_receiver() + registers.register_count());
AddNewNode<AssertInt32>(
{register_size, array_length}, AssertCondition::kLessOrEqual,
AbortReason::kInvalidParametersAndRegistersInGenerator);
}
const compiler::BytecodeLivenessState* liveness =
GetOutLivenessFor(next_offset());
for (int i = 0; i < registers.register_count(); ++i) {
......
......@@ -213,6 +213,7 @@ class MaglevGraphVerifier {
CheckValueInputIs(node, 2, ValueRepresentation::kTagged);
CheckValueInputIs(node, 3, ValueRepresentation::kTagged);
break;
case Opcode::kAssertInt32:
case Opcode::kInt32AddWithOverflow:
case Opcode::kInt32SubtractWithOverflow:
case Opcode::kInt32MultiplyWithOverflow:
......
......@@ -1157,6 +1157,63 @@ void Abort::PrintParams(std::ostream& os,
os << "(" << GetAbortReason(reason()) << ")";
}
namespace {
Condition ToCondition(AssertCondition cond) {
switch (cond) {
case AssertCondition::kLess:
return less;
case AssertCondition::kLessOrEqual:
return less_equal;
case AssertCondition::kGreater:
return greater;
case AssertCondition::kGeaterOrEqual:
return greater_equal;
case AssertCondition::kEqual:
return equal;
case AssertCondition::kNotEqual:
return not_equal;
}
}
std::ostream& operator<<(std::ostream& os, const AssertCondition cond) {
switch (cond) {
case AssertCondition::kLess:
os << "Less";
break;
case AssertCondition::kLessOrEqual:
os << "LessOrEqual";
break;
case AssertCondition::kGreater:
os << "Greater";
break;
case AssertCondition::kGeaterOrEqual:
os << "GeaterOrEqual";
break;
case AssertCondition::kEqual:
os << "Equal";
break;
case AssertCondition::kNotEqual:
os << "NotEqual";
break;
}
return os;
}
} // namespace
void AssertInt32::AllocateVreg(MaglevVregAllocationState* vreg_state) {
UseRegister(left_input());
UseRegister(right_input());
}
void AssertInt32::GenerateCode(MaglevAssembler* masm,
const ProcessingState& state) {
__ cmpq(ToRegister(left_input()), ToRegister(right_input()));
__ Check(ToCondition(condition_), reason_);
}
void AssertInt32::PrintParams(std::ostream& os,
MaglevGraphLabeller* graph_labeller) const {
os << "(" << condition_ << ")";
}
void CheckMaps::AllocateVreg(MaglevVregAllocationState* vreg_state) {
UseRegister(receiver_input());
}
......
......@@ -184,6 +184,7 @@ class CompactInterpreterFrameState;
V(GapMove)
#define NODE_LIST(V) \
V(AssertInt32) \
V(CheckMaps) \
V(CheckSmi) \
V(CheckNumber) \
......@@ -2455,6 +2456,33 @@ class CreateClosure : public FixedInputValueNodeT<1, CreateClosure> {
const bool pretenured_;
};
enum class AssertCondition {
kLess,
kLessOrEqual,
kGreater,
kGeaterOrEqual,
kEqual,
kNotEqual,
};
class AssertInt32 : public FixedInputNodeT<2, AssertInt32> {
using Base = FixedInputNodeT<2, AssertInt32>;
public:
explicit AssertInt32(uint64_t bitfield, AssertCondition condition,
AbortReason reason)
: Base(bitfield), condition_(condition), reason_(reason) {}
Input& left_input() { return input(0); }
Input& right_input() { return input(1); }
DECL_NODE_INTERFACE()
private:
AssertCondition condition_;
AbortReason reason_;
};
enum class CheckType { kCheckHeapObject, kOmitHeapObjectCheck };
class CheckMaps : public FixedInputNodeT<1, CheckMaps> {
......
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