[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:
parent
93292424ec
commit
de6bc11425
@ -108,7 +108,11 @@ void CodeStubAssembler::Check(const BranchGenerator& branch,
|
||||
branch(&ok, ¬_ok);
|
||||
|
||||
BIND(¬_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);
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user