Commit b24e4a1b authored by Tobias Tebbi's avatar Tobias Tebbi Committed by Commit Bot

[torque] use same mechanism as CSA_ASSERT for asserts and checks

Bug: v8:8393
Change-Id: I6ab34cbe6c17f358c570e0bd27bf2de917f71b71
Reviewed-on: https://chromium-review.googlesource.com/c/1309764
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarDaniel Clifford <danno@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57211}
parent 0b4350ae
...@@ -116,27 +116,9 @@ void CodeStubAssembler::Check(const BranchGenerator& branch, ...@@ -116,27 +116,9 @@ void CodeStubAssembler::Check(const BranchGenerator& branch,
branch(&ok, &not_ok); branch(&ok, &not_ok);
BIND(&not_ok); BIND(&not_ok);
DCHECK_NOT_NULL(message); FailAssert(message, file, line, extra_node1, extra_node1_name, extra_node2,
char chars[1024]; extra_node2_name, extra_node3, extra_node3_name, extra_node4,
Vector<char> buffer(chars); extra_node4_name, extra_node5, extra_node5_name);
if (file != nullptr) {
SNPrintF(buffer, "CSA_ASSERT failed: %s [%s:%d]\n", message, file, line);
} else {
SNPrintF(buffer, "CSA_ASSERT failed: %s\n", message);
}
Node* message_node = StringConstant(&(buffer[0]));
#ifdef DEBUG
// Only print the extra nodes in debug builds.
MaybePrintNodeWithName(this, extra_node1, extra_node1_name);
MaybePrintNodeWithName(this, extra_node2, extra_node2_name);
MaybePrintNodeWithName(this, extra_node3, extra_node3_name);
MaybePrintNodeWithName(this, extra_node4, extra_node4_name);
MaybePrintNodeWithName(this, extra_node5, extra_node5_name);
#endif
DebugAbort(message_node);
Unreachable();
BIND(&ok); BIND(&ok);
Comment("] Assert"); Comment("] Assert");
...@@ -168,6 +150,36 @@ void CodeStubAssembler::FastCheck(TNode<BoolT> condition) { ...@@ -168,6 +150,36 @@ void CodeStubAssembler::FastCheck(TNode<BoolT> condition) {
BIND(&ok); BIND(&ok);
} }
void CodeStubAssembler::FailAssert(
const char* message, const char* file, int line, Node* extra_node1,
const char* extra_node1_name, Node* extra_node2,
const char* extra_node2_name, Node* extra_node3,
const char* extra_node3_name, Node* extra_node4,
const char* extra_node4_name, Node* extra_node5,
const char* extra_node5_name) {
DCHECK_NOT_NULL(message);
char chars[1024];
Vector<char> buffer(chars);
if (file != nullptr) {
SNPrintF(buffer, "CSA_ASSERT failed: %s [%s:%d]\n", message, file, line);
} else {
SNPrintF(buffer, "CSA_ASSERT failed: %s\n", message);
}
Node* message_node = StringConstant(&(buffer[0]));
#ifdef DEBUG
// Only print the extra nodes in debug builds.
MaybePrintNodeWithName(this, extra_node1, extra_node1_name);
MaybePrintNodeWithName(this, extra_node2, extra_node2_name);
MaybePrintNodeWithName(this, extra_node3, extra_node3_name);
MaybePrintNodeWithName(this, extra_node4, extra_node4_name);
MaybePrintNodeWithName(this, extra_node5, extra_node5_name);
#endif
DebugAbort(message_node);
Unreachable();
}
Node* CodeStubAssembler::SelectImpl(TNode<BoolT> condition, Node* CodeStubAssembler::SelectImpl(TNode<BoolT> condition,
const NodeGenerator& true_body, const NodeGenerator& true_body,
const NodeGenerator& false_body, const NodeGenerator& false_body,
......
...@@ -680,6 +680,14 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler { ...@@ -680,6 +680,14 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
Node* extra_node3 = nullptr, const char* extra_node3_name = "", Node* extra_node3 = nullptr, const char* extra_node3_name = "",
Node* extra_node4 = nullptr, const char* extra_node4_name = "", Node* extra_node4 = nullptr, const char* extra_node4_name = "",
Node* extra_node5 = nullptr, const char* extra_node5_name = ""); Node* extra_node5 = nullptr, const char* extra_node5_name = "");
void FailAssert(
const char* message = nullptr, const char* file = nullptr, int line = 0,
Node* extra_node1 = nullptr, const char* extra_node1_name = "",
Node* extra_node2 = nullptr, const char* extra_node2_name = "",
Node* extra_node3 = nullptr, const char* extra_node3_name = "",
Node* extra_node4 = nullptr, const char* extra_node4_name = "",
Node* extra_node5 = nullptr, const char* extra_node5_name = "");
void FastCheck(TNode<BoolT> condition); void FastCheck(TNode<BoolT> condition);
// The following Call wrappers call an object according to the semantics that // The following Call wrappers call an object according to the semantics that
...@@ -3410,7 +3418,6 @@ class ToDirectStringAssembler : public CodeStubAssembler { ...@@ -3410,7 +3418,6 @@ class ToDirectStringAssembler : public CodeStubAssembler {
const Flags flags_; const Flags flags_;
}; };
DEFINE_OPERATORS_FOR_FLAGS(CodeStubAssembler::AllocationFlags); DEFINE_OPERATORS_FOR_FLAGS(CodeStubAssembler::AllocationFlags);
} // namespace internal } // namespace internal
......
...@@ -140,9 +140,18 @@ void CfgAssembler::Print(std::string s) { ...@@ -140,9 +140,18 @@ void CfgAssembler::Print(std::string s) {
Emit(PrintConstantStringInstruction{std::move(s)}); Emit(PrintConstantStringInstruction{std::move(s)});
} }
void CfgAssembler::Unreachable() { Emit(DebugBreakInstruction{true}); } void CfgAssembler::AssertionFailure(std::string message) {
Emit(AbortInstruction{AbortInstruction::Kind::kAssertionFailure,
std::move(message)});
}
void CfgAssembler::Unreachable() {
Emit(AbortInstruction{AbortInstruction::Kind::kUnreachable});
}
void CfgAssembler::DebugBreak() { Emit(DebugBreakInstruction{false}); } void CfgAssembler::DebugBreak() {
Emit(AbortInstruction{AbortInstruction::Kind::kDebugBreak});
}
} // namespace torque } // namespace torque
} // namespace internal } // namespace internal
......
...@@ -133,6 +133,7 @@ class CfgAssembler { ...@@ -133,6 +133,7 @@ class CfgAssembler {
void Poke(StackRange destination, StackRange origin, void Poke(StackRange destination, StackRange origin,
base::Optional<const Type*> type); base::Optional<const Type*> type);
void Print(std::string s); void Print(std::string s);
void AssertionFailure(std::string message);
void Unreachable(); void Unreachable();
void DebugBreak(); void DebugBreak();
......
...@@ -523,12 +523,24 @@ void CSAGenerator::EmitInstruction( ...@@ -523,12 +523,24 @@ void CSAGenerator::EmitInstruction(
out_ << " Print(" << StringLiteralQuote(instruction.message) << ");\n"; out_ << " Print(" << StringLiteralQuote(instruction.message) << ");\n";
} }
void CSAGenerator::EmitInstruction(const DebugBreakInstruction& instruction, void CSAGenerator::EmitInstruction(const AbortInstruction& instruction,
Stack<std::string>* stack) { Stack<std::string>* stack) {
if (instruction.never_continues) { switch (instruction.kind) {
out_ << " Unreachable();\n"; case AbortInstruction::Kind::kUnreachable:
} else { DCHECK(instruction.message.empty());
out_ << " DebugBreak();\n"; out_ << " Unreachable();\n";
break;
case AbortInstruction::Kind::kDebugBreak:
DCHECK(instruction.message.empty());
out_ << " DebugBreak();\n";
break;
case AbortInstruction::Kind::kAssertionFailure: {
std::string file =
StringLiteralQuote(SourceFileMap::GetSource(instruction.pos.source));
out_ << " FailAssert(" << StringLiteralQuote(instruction.message)
<< ", " << file << ", " << instruction.pos.line + 1 << ");\n";
break;
}
} }
} }
......
...@@ -881,7 +881,9 @@ const Type* ImplementationVisitor::Visit(DebugStatement* stmt) { ...@@ -881,7 +881,9 @@ const Type* ImplementationVisitor::Visit(DebugStatement* stmt) {
stmt->reason + "' at " + stmt->reason + "' at " +
PositionAsString(stmt->pos)}); PositionAsString(stmt->pos)});
#endif #endif
assembler().Emit(DebugBreakInstruction{stmt->never_continues}); assembler().Emit(AbortInstruction{stmt->never_continues
? AbortInstruction::Kind::kUnreachable
: AbortInstruction::Kind::kDebugBreak});
if (stmt->never_continues) { if (stmt->never_continues) {
return TypeOracle::GetNeverType(); return TypeOracle::GetNeverType();
} else { } else {
...@@ -927,10 +929,10 @@ const Type* ImplementationVisitor::Visit(AssertStatement* stmt) { ...@@ -927,10 +929,10 @@ const Type* ImplementationVisitor::Visit(AssertStatement* stmt) {
GenerateExpressionBranch(stmt->expression, true_block, false_block); GenerateExpressionBranch(stmt->expression, true_block, false_block);
assembler().Bind(false_block); assembler().Bind(false_block);
assembler().Emit(PrintConstantStringInstruction{
"assert '" + FormatAssertSource(stmt->source) + "' failed at " + assembler().Emit(AbortInstruction{
PositionAsString(stmt->pos)}); AbortInstruction::Kind::kAssertionFailure,
assembler().Emit(DebugBreakInstruction{true}); "Torque assert '" + FormatAssertSource(stmt->source) + "' failed"});
assembler().Bind(true_block); assembler().Bind(true_block);
} }
......
...@@ -256,8 +256,8 @@ void ReturnInstruction::TypeInstruction(Stack<const Type*>* stack, ...@@ -256,8 +256,8 @@ void ReturnInstruction::TypeInstruction(Stack<const Type*>* stack,
void PrintConstantStringInstruction::TypeInstruction( void PrintConstantStringInstruction::TypeInstruction(
Stack<const Type*>* stack, ControlFlowGraph* cfg) const {} Stack<const Type*>* stack, ControlFlowGraph* cfg) const {}
void DebugBreakInstruction::TypeInstruction(Stack<const Type*>* stack, void AbortInstruction::TypeInstruction(Stack<const Type*>* stack,
ControlFlowGraph* cfg) const {} ControlFlowGraph* cfg) const {}
void UnsafeCastInstruction::TypeInstruction(Stack<const Type*>* stack, void UnsafeCastInstruction::TypeInstruction(Stack<const Type*>* stack,
ControlFlowGraph* cfg) const { ControlFlowGraph* cfg) const {
......
...@@ -41,7 +41,7 @@ class RuntimeFunction; ...@@ -41,7 +41,7 @@ class RuntimeFunction;
V(GotoExternalInstruction) \ V(GotoExternalInstruction) \
V(ReturnInstruction) \ V(ReturnInstruction) \
V(PrintConstantStringInstruction) \ V(PrintConstantStringInstruction) \
V(DebugBreakInstruction) \ V(AbortInstruction) \
V(UnsafeCastInstruction) V(UnsafeCastInstruction)
#define TORQUE_INSTRUCTION_BOILERPLATE() \ #define TORQUE_INSTRUCTION_BOILERPLATE() \
...@@ -355,13 +355,17 @@ struct PrintConstantStringInstruction : InstructionBase { ...@@ -355,13 +355,17 @@ struct PrintConstantStringInstruction : InstructionBase {
std::string message; std::string message;
}; };
struct DebugBreakInstruction : InstructionBase { struct AbortInstruction : InstructionBase {
TORQUE_INSTRUCTION_BOILERPLATE() TORQUE_INSTRUCTION_BOILERPLATE()
bool IsBlockTerminator() const override { return never_continues; } enum class Kind { kDebugBreak, kUnreachable, kAssertionFailure };
explicit DebugBreakInstruction(bool never_continues) bool IsBlockTerminator() const override { return kind != Kind::kDebugBreak; }
: never_continues(never_continues) {} explicit AbortInstruction(Kind kind, std::string message = "") : kind(kind) {
// The normal way to write this triggers a bug in Clang on Windows.
this->message = std::move(message);
}
bool never_continues; Kind kind;
std::string message;
}; };
struct UnsafeCastInstruction : InstructionBase { struct UnsafeCastInstruction : InstructionBase {
......
...@@ -49,7 +49,7 @@ std::string StringLiteralUnquote(const std::string& s) { ...@@ -49,7 +49,7 @@ std::string StringLiteralUnquote(const std::string& s) {
std::string StringLiteralQuote(const std::string& s) { std::string StringLiteralQuote(const std::string& s) {
std::stringstream result; std::stringstream result;
result << '"'; result << '"';
for (size_t i = 0; i < s.length() - 1; ++i) { for (size_t i = 0; i < s.length(); ++i) {
switch (s[i]) { switch (s[i]) {
case '\n': case '\n':
result << "\\n"; result << "\\n";
......
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