1c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch// Copyright 2016 the V8 project authors. All rights reserved. 2c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch// found in the LICENSE file. 4c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 5c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch#include "src/source-position.h" 6c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch#include "src/compilation-info.h" 7c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch#include "src/objects-inl.h" 8c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 9c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochnamespace v8 { 10c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochnamespace internal { 11c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 12c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochstd::ostream& operator<<(std::ostream& out, const SourcePositionInfo& pos) { 13c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Handle<SharedFunctionInfo> function(pos.function); 1462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch String* name = nullptr; 1562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (function->script()->IsScript()) { 1662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Script* script = Script::cast(function->script()); 1762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (script->name()->IsString()) { 1862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch name = String::cast(script->name()); 1962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 2062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 21c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch out << "<"; 2262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (name != nullptr) { 2362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch out << name->ToCString(DISALLOW_NULLS).get(); 24c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } else { 25c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch out << "unknown"; 26c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 27c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch out << ":" << pos.line + 1 << ":" << pos.column + 1 << ">"; 28c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return out; 29c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch} 30c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 31c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochstd::ostream& operator<<(std::ostream& out, 32c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch const std::vector<SourcePositionInfo>& stack) { 33c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch bool first = true; 34c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch for (const SourcePositionInfo& pos : stack) { 35c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!first) out << " inlined at "; 36c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch out << pos; 37c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch first = false; 38c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 39c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return out; 40c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch} 41c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 42c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochstd::ostream& operator<<(std::ostream& out, const SourcePosition& pos) { 43c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (pos.isInlined()) { 44c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch out << "<inlined(" << pos.InliningId() << "):"; 45c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } else { 46c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch out << "<not inlined:"; 47c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 48c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch out << pos.ScriptOffset() << ">"; 49c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return out; 50c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch} 51c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 52c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochstd::vector<SourcePositionInfo> SourcePosition::InliningStack( 53c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch CompilationInfo* cinfo) const { 54c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch SourcePosition pos = *this; 55c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch std::vector<SourcePositionInfo> stack; 56c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch while (pos.isInlined()) { 57c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch const auto& inl = cinfo->inlined_functions()[pos.InliningId()]; 5862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch stack.push_back(SourcePositionInfo(pos, inl.shared_info)); 59c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch pos = inl.position.position; 60c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 6162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch stack.push_back(SourcePositionInfo(pos, cinfo->shared_info())); 62c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return stack; 63c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch} 64c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 65c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochstd::vector<SourcePositionInfo> SourcePosition::InliningStack( 66c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Handle<Code> code) const { 67c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Handle<DeoptimizationInputData> deopt_data( 68c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch DeoptimizationInputData::cast(code->deoptimization_data())); 69c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch SourcePosition pos = *this; 70c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch std::vector<SourcePositionInfo> stack; 71c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch while (pos.isInlined()) { 72c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch InliningPosition inl = 73c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch deopt_data->InliningPositions()->get(pos.InliningId()); 74c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Handle<SharedFunctionInfo> function( 75c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch deopt_data->GetInlinedFunction(inl.inlined_function_id)); 7662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch stack.push_back(SourcePositionInfo(pos, function)); 77c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch pos = inl.position; 78c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 79c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Handle<SharedFunctionInfo> function( 80c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch SharedFunctionInfo::cast(deopt_data->SharedFunctionInfo())); 8162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch stack.push_back(SourcePositionInfo(pos, function)); 82c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return stack; 83c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch} 84c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 85c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochvoid SourcePosition::Print(std::ostream& out, 86c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch SharedFunctionInfo* function) const { 87c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Script::PositionInfo pos; 8862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Object* source_name = nullptr; 8962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (function->script()->IsScript()) { 9062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Script* script = Script::cast(function->script()); 9162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch source_name = script->name(); 9262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch script->GetPositionInfo(ScriptOffset(), &pos, Script::WITH_OFFSET); 9362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 94c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch out << "<"; 9562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (source_name != nullptr && source_name->IsString()) { 96c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch out << String::cast(source_name) 97c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch ->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL) 98c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch .get(); 99c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } else { 100c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch out << "unknown"; 101c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 102c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch out << ":" << pos.line + 1 << ":" << pos.column + 1 << ">"; 103c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch} 104c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 105c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochvoid SourcePosition::Print(std::ostream& out, Code* code) const { 106c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch DeoptimizationInputData* deopt_data = 107c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch DeoptimizationInputData::cast(code->deoptimization_data()); 108c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!isInlined()) { 109c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch SharedFunctionInfo* function( 110c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch SharedFunctionInfo::cast(deopt_data->SharedFunctionInfo())); 111c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Print(out, function); 112c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } else { 113c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch InliningPosition inl = deopt_data->InliningPositions()->get(InliningId()); 114c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (inl.inlined_function_id == -1) { 115c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch out << *this; 116c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } else { 117c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch SharedFunctionInfo* function = 118c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch deopt_data->GetInlinedFunction(inl.inlined_function_id); 119c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Print(out, function); 120c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 121c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch out << " inlined at "; 122c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch inl.position.Print(out, code); 123c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 124c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch} 125c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 12662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochSourcePositionInfo::SourcePositionInfo(SourcePosition pos, 12762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<SharedFunctionInfo> f) 12862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch : position(pos), function(f) { 12962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (function->script()->IsScript()) { 13062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<Script> script(Script::cast(function->script())); 13162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Script::PositionInfo info; 13262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (Script::GetPositionInfo(script, pos.ScriptOffset(), &info, 13362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Script::WITH_OFFSET)) { 13462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch line = info.line; 13562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch column = info.column; 13662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 13762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 13862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 13962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 140c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch} // namespace internal 141c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch} // namespace v8 142