[torque] Show entire stack of inlined macros for Torque assertions

Otherwise, a failure message from a common macro like UnsafeCast<A> is
not particularly meaningful. With this change, the failure message would
show the line number in the top-level builtin and each in-between macro
that resulted in calling UnsafeCast<A>. This does not include plain CSA
macros, only those generated by Torque.

Bug: v8:7793
Change-Id: If0b9b7d2755f579ceacf47eef2440d97ec84a2ff
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2303598
Commit-Queue: Seth Brenith <seth.brenith@microsoft.com>
Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#69044}
This commit is contained in:
Seth Brenith 2020-07-23 07:56:58 -07:00 committed by Commit Bot
parent 93292424ec
commit de6bc11425
10 changed files with 87 additions and 16 deletions

View File

@ -108,7 +108,11 @@ void CodeStubAssembler::Check(const BranchGenerator& branch,
branch(&ok, &not_ok);
BIND(&not_ok);
FailAssert(message, file, line, extra_nodes);
std::vector<FileAndLine> file_and_line;
if (file != nullptr) {
file_and_line.push_back({file, line});
}
FailAssert(message, file_and_line, extra_nodes);
BIND(&ok);
Comment("] Assert");
@ -159,12 +163,24 @@ void CodeStubAssembler::FastCheck(TNode<BoolT> condition) {
}
void CodeStubAssembler::FailAssert(
const char* message, const char* file, int line,
const char* message, const std::vector<FileAndLine>& files_and_lines,
std::initializer_list<ExtraNode> extra_nodes) {
DCHECK_NOT_NULL(message);
EmbeddedVector<char, 1024> chars;
if (file != nullptr) {
SNPrintF(chars, "%s [%s:%d]", message, file, line);
std::stringstream stream;
for (auto it = files_and_lines.rbegin(); it != files_and_lines.rend(); ++it) {
if (it->first != nullptr) {
stream << " [" << it->first << ":" << it->second << "]";
#ifndef DEBUG
// To limit the size of these strings in release builds, we include only
// the innermost macro's file name and line number.
break;
#endif
}
}
std::string files_and_lines_text = stream.str();
if (files_and_lines_text.size() != 0) {
SNPrintF(chars, "%s%s", message, files_and_lines_text.c_str());
message = chars.begin();
}
TNode<String> message_node = StringConstant(message);

View File

@ -818,7 +818,8 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
void Check(SloppyTNode<Word32T> condition_node, const char* message,
const char* file, int line,
std::initializer_list<ExtraNode> extra_nodes = {});
void FailAssert(const char* message, const char* file, int line,
void FailAssert(const char* message,
const std::vector<FileAndLine>& files_and_lines,
std::initializer_list<ExtraNode> extra_nodes = {});
void FastCheck(TNode<BoolT> condition);

View File

@ -1525,6 +1525,8 @@ inline std::ostream& operator<<(std::ostream& os,
return os;
}
using FileAndLine = std::pair<const char*, int>;
enum class OptimizationMarker {
kLogFirstExecution,
kNone,

View File

@ -112,7 +112,7 @@ void CodeAssemblerState::SetInitialDebugInformation(const char* msg,
int line) {
#if DEBUG
AssemblerDebugInfo debug_info = {msg, file, line};
raw_assembler_->SetSourcePosition(file, line);
raw_assembler_->SetCurrentExternalSourcePosition({file, line});
raw_assembler_->SetInitialDebugInformation(debug_info);
#endif // DEBUG
}
@ -500,7 +500,21 @@ void CodeAssembler::StaticAssert(TNode<BoolT> value) {
}
void CodeAssembler::SetSourcePosition(const char* file, int line) {
raw_assembler()->SetSourcePosition(file, line);
raw_assembler()->SetCurrentExternalSourcePosition({file, line});
}
void CodeAssembler::PushSourcePosition() {
auto position = raw_assembler()->GetCurrentExternalSourcePosition();
state_->macro_call_stack_.push_back(position);
}
void CodeAssembler::PopSourcePosition() {
state_->macro_call_stack_.pop_back();
}
const std::vector<FileAndLine>& CodeAssembler::GetMacroSourcePositionStack()
const {
return state_->macro_call_stack_;
}
void CodeAssembler::Bind(Label* label) { return label->Bind(); }
@ -1445,7 +1459,8 @@ void CodeAssemblerLabel::Bind(AssemblerDebugInfo debug_info) {
FATAL("%s", str.str().c_str());
}
if (FLAG_enable_source_at_csa_bind) {
state_->raw_assembler_->SetSourcePosition(debug_info.file, debug_info.line);
state_->raw_assembler_->SetCurrentExternalSourcePosition(
{debug_info.file, debug_info.line});
}
state_->raw_assembler_->Bind(label_, debug_info);
UpdateVariablesAfterBind();

View File

@ -599,7 +599,22 @@ class V8_EXPORT_PRIVATE CodeAssembler {
void StaticAssert(TNode<BoolT> value);
// The following methods refer to source positions in CSA or Torque code
// compiled during mksnapshot, not JS compiled at runtime.
void SetSourcePosition(const char* file, int line);
void PushSourcePosition();
void PopSourcePosition();
class SourcePositionScope {
public:
explicit SourcePositionScope(CodeAssembler* ca) : ca_(ca) {
ca->PushSourcePosition();
}
~SourcePositionScope() { ca_->PopSourcePosition(); }
private:
CodeAssembler* ca_;
};
const std::vector<FileAndLine>& GetMacroSourcePositionStack() const;
void Bind(Label* label);
#if DEBUG
@ -1461,6 +1476,9 @@ class V8_EXPORT_PRIVATE CodeAssemblerState {
VariableId next_variable_id_ = 0;
JSGraph* jsgraph_;
// Only used by CodeStubAssembler builtins.
std::vector<FileAndLine> macro_call_stack_;
VariableId NextVariableId() { return next_variable_id_++; }
DISALLOW_COPY_AND_ASSIGN(CodeAssemblerState);

View File

@ -52,6 +52,7 @@ class V8_EXPORT_PRIVATE SourcePositionTable final
void SetCurrentPosition(const SourcePosition& pos) {
current_position_ = pos;
}
SourcePosition GetCurrentPosition() const { return current_position_; }
void PrintJson(std::ostream& os) const;

View File

@ -47,13 +47,24 @@ RawMachineAssembler::RawMachineAssembler(
source_positions_->AddDecorator();
}
void RawMachineAssembler::SetSourcePosition(const char* file, int line) {
int file_id = isolate()->LookupOrAddExternallyCompiledFilename(file);
SourcePosition p = SourcePosition::External(line, file_id);
DCHECK(p.ExternalLine() == line);
void RawMachineAssembler::SetCurrentExternalSourcePosition(
FileAndLine file_and_line) {
int file_id =
isolate()->LookupOrAddExternallyCompiledFilename(file_and_line.first);
SourcePosition p = SourcePosition::External(file_and_line.second, file_id);
DCHECK(p.ExternalLine() == file_and_line.second);
source_positions()->SetCurrentPosition(p);
}
FileAndLine RawMachineAssembler::GetCurrentExternalSourcePosition() const {
SourcePosition p = source_positions_->GetCurrentPosition();
if (!p.IsKnown()) return {nullptr, -1};
int file_id = p.ExternalFileId();
const char* file_name = isolate()->GetExternallyCompiledFilename(file_id);
int line = p.ExternalLine();
return {file_name, line};
}
Node* RawMachineAssembler::NullConstant() {
return HeapConstant(isolate()->factory()->null_value());
}

View File

@ -1011,7 +1011,8 @@ class V8_EXPORT_PRIVATE RawMachineAssembler {
return AddNode(op, sizeof...(args) + 1, buffer);
}
void SetSourcePosition(const char* file, int line);
void SetCurrentExternalSourcePosition(FileAndLine file_and_line);
FileAndLine GetCurrentExternalSourcePosition() const;
SourcePositionTable* source_positions() { return source_positions_; }
private:

View File

@ -846,9 +846,13 @@ void CSAGenerator::EmitInstruction(const AbortInstruction& instruction,
case AbortInstruction::Kind::kAssertionFailure: {
std::string file = StringLiteralQuote(
SourceFileMap::PathFromV8Root(instruction.pos.source));
out() << " CodeStubAssembler(state_).FailAssert("
<< StringLiteralQuote(instruction.message) << ", " << file << ", "
<< instruction.pos.start.line + 1 << ");\n";
out() << " {\n";
out() << " auto pos_stack = ca_.GetMacroSourcePositionStack();\n";
out() << " pos_stack.push_back({" << file << ", "
<< instruction.pos.start.line + 1 << "});\n";
out() << " CodeStubAssembler(state_).FailAssert("
<< StringLiteralQuote(instruction.message) << ", pos_stack);\n";
out() << " }\n";
break;
}
}

View File

@ -284,6 +284,8 @@ void ImplementationVisitor::VisitMacroCommon(Macro* macro) {
GenerateMacroFunctionDeclaration(source_out(), "", macro);
source_out() << " {\n";
source_out() << " compiler::CodeAssembler ca_(state_);\n";
source_out()
<< " compiler::CodeAssembler::SourcePositionScope pos_scope(&ca_);\n";
Stack<std::string> lowered_parameters;
Stack<const Type*> lowered_parameter_types;