diff --git a/src/codegen/code-stub-assembler.cc b/src/codegen/code-stub-assembler.cc index 3f4a6d95ad..c44f322eb8 100644 --- a/src/codegen/code-stub-assembler.cc +++ b/src/codegen/code-stub-assembler.cc @@ -108,7 +108,11 @@ void CodeStubAssembler::Check(const BranchGenerator& branch, branch(&ok, ¬_ok); BIND(¬_ok); - FailAssert(message, file, line, extra_nodes); + std::vector 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 condition) { } void CodeStubAssembler::FailAssert( - const char* message, const char* file, int line, + const char* message, const std::vector& files_and_lines, std::initializer_list extra_nodes) { DCHECK_NOT_NULL(message); EmbeddedVector 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 message_node = StringConstant(message); diff --git a/src/codegen/code-stub-assembler.h b/src/codegen/code-stub-assembler.h index bb1c715cd5..e7a0a22bfd 100644 --- a/src/codegen/code-stub-assembler.h +++ b/src/codegen/code-stub-assembler.h @@ -818,7 +818,8 @@ class V8_EXPORT_PRIVATE CodeStubAssembler void Check(SloppyTNode condition_node, const char* message, const char* file, int line, std::initializer_list extra_nodes = {}); - void FailAssert(const char* message, const char* file, int line, + void FailAssert(const char* message, + const std::vector& files_and_lines, std::initializer_list extra_nodes = {}); void FastCheck(TNode condition); diff --git a/src/common/globals.h b/src/common/globals.h index 4f27f13132..e18edf28c5 100644 --- a/src/common/globals.h +++ b/src/common/globals.h @@ -1525,6 +1525,8 @@ inline std::ostream& operator<<(std::ostream& os, return os; } +using FileAndLine = std::pair; + enum class OptimizationMarker { kLogFirstExecution, kNone, diff --git a/src/compiler/code-assembler.cc b/src/compiler/code-assembler.cc index 91ca9297ef..4503536701 100644 --- a/src/compiler/code-assembler.cc +++ b/src/compiler/code-assembler.cc @@ -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 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& 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(); diff --git a/src/compiler/code-assembler.h b/src/compiler/code-assembler.h index 248dc08837..3911b34f53 100644 --- a/src/compiler/code-assembler.h +++ b/src/compiler/code-assembler.h @@ -599,7 +599,22 @@ class V8_EXPORT_PRIVATE CodeAssembler { void StaticAssert(TNode 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& 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 macro_call_stack_; + VariableId NextVariableId() { return next_variable_id_++; } DISALLOW_COPY_AND_ASSIGN(CodeAssemblerState); diff --git a/src/compiler/compiler-source-position-table.h b/src/compiler/compiler-source-position-table.h index c067c68c72..6c3ab684a8 100644 --- a/src/compiler/compiler-source-position-table.h +++ b/src/compiler/compiler-source-position-table.h @@ -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; diff --git a/src/compiler/raw-machine-assembler.cc b/src/compiler/raw-machine-assembler.cc index 50aa482c4a..7d8b920ed1 100644 --- a/src/compiler/raw-machine-assembler.cc +++ b/src/compiler/raw-machine-assembler.cc @@ -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()); } diff --git a/src/compiler/raw-machine-assembler.h b/src/compiler/raw-machine-assembler.h index b0894d2b06..4924fbb25d 100644 --- a/src/compiler/raw-machine-assembler.h +++ b/src/compiler/raw-machine-assembler.h @@ -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: diff --git a/src/torque/csa-generator.cc b/src/torque/csa-generator.cc index a25c5ce25f..da16a1b3b4 100644 --- a/src/torque/csa-generator.cc +++ b/src/torque/csa-generator.cc @@ -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; } } diff --git a/src/torque/implementation-visitor.cc b/src/torque/implementation-visitor.cc index 9db0660204..91dd2b3bd7 100644 --- a/src/torque/implementation-visitor.cc +++ b/src/torque/implementation-visitor.cc @@ -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 lowered_parameters; Stack lowered_parameter_types;