1 // Copyright 2016 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "src/source-position.h" 6 #include "src/compilation-info.h" 7 #include "src/objects-inl.h" 8 9 namespace v8 { 10 namespace internal { 11 12 std::ostream& operator<<(std::ostream& out, const SourcePositionInfo& pos) { 13 Handle<SharedFunctionInfo> function(pos.function); 14 Handle<Script> script(Script::cast(function->script())); 15 out << "<"; 16 if (script->name()->IsString()) { 17 out << String::cast(script->name())->ToCString(DISALLOW_NULLS).get(); 18 } else { 19 out << "unknown"; 20 } 21 out << ":" << pos.line + 1 << ":" << pos.column + 1 << ">"; 22 return out; 23 } 24 25 std::ostream& operator<<(std::ostream& out, 26 const std::vector<SourcePositionInfo>& stack) { 27 bool first = true; 28 for (const SourcePositionInfo& pos : stack) { 29 if (!first) out << " inlined at "; 30 out << pos; 31 first = false; 32 } 33 return out; 34 } 35 36 std::ostream& operator<<(std::ostream& out, const SourcePosition& pos) { 37 if (pos.isInlined()) { 38 out << "<inlined(" << pos.InliningId() << "):"; 39 } else { 40 out << "<not inlined:"; 41 } 42 out << pos.ScriptOffset() << ">"; 43 return out; 44 } 45 46 SourcePositionInfo SourcePosition::Info( 47 Handle<SharedFunctionInfo> function) const { 48 SourcePositionInfo result(*this, function); 49 Handle<Script> script(Script::cast(function->script())); 50 Script::PositionInfo pos; 51 if (Script::GetPositionInfo(script, ScriptOffset(), &pos, 52 Script::WITH_OFFSET)) { 53 result.line = pos.line; 54 result.column = pos.column; 55 } 56 return result; 57 } 58 59 std::vector<SourcePositionInfo> SourcePosition::InliningStack( 60 CompilationInfo* cinfo) const { 61 SourcePosition pos = *this; 62 std::vector<SourcePositionInfo> stack; 63 while (pos.isInlined()) { 64 const auto& inl = cinfo->inlined_functions()[pos.InliningId()]; 65 stack.push_back(pos.Info(inl.shared_info)); 66 pos = inl.position.position; 67 } 68 stack.push_back(pos.Info(cinfo->shared_info())); 69 return stack; 70 } 71 72 std::vector<SourcePositionInfo> SourcePosition::InliningStack( 73 Handle<Code> code) const { 74 Handle<DeoptimizationInputData> deopt_data( 75 DeoptimizationInputData::cast(code->deoptimization_data())); 76 SourcePosition pos = *this; 77 std::vector<SourcePositionInfo> stack; 78 while (pos.isInlined()) { 79 InliningPosition inl = 80 deopt_data->InliningPositions()->get(pos.InliningId()); 81 Handle<SharedFunctionInfo> function( 82 deopt_data->GetInlinedFunction(inl.inlined_function_id)); 83 stack.push_back(pos.Info(function)); 84 pos = inl.position; 85 } 86 Handle<SharedFunctionInfo> function( 87 SharedFunctionInfo::cast(deopt_data->SharedFunctionInfo())); 88 stack.push_back(pos.Info(function)); 89 return stack; 90 } 91 92 void SourcePosition::Print(std::ostream& out, 93 SharedFunctionInfo* function) const { 94 Script* script = Script::cast(function->script()); 95 Object* source_name = script->name(); 96 Script::PositionInfo pos; 97 script->GetPositionInfo(ScriptOffset(), &pos, Script::WITH_OFFSET); 98 out << "<"; 99 if (source_name->IsString()) { 100 out << String::cast(source_name) 101 ->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL) 102 .get(); 103 } else { 104 out << "unknown"; 105 } 106 out << ":" << pos.line + 1 << ":" << pos.column + 1 << ">"; 107 } 108 109 void SourcePosition::Print(std::ostream& out, Code* code) const { 110 DeoptimizationInputData* deopt_data = 111 DeoptimizationInputData::cast(code->deoptimization_data()); 112 if (!isInlined()) { 113 SharedFunctionInfo* function( 114 SharedFunctionInfo::cast(deopt_data->SharedFunctionInfo())); 115 Print(out, function); 116 } else { 117 InliningPosition inl = deopt_data->InliningPositions()->get(InliningId()); 118 if (inl.inlined_function_id == -1) { 119 out << *this; 120 } else { 121 SharedFunctionInfo* function = 122 deopt_data->GetInlinedFunction(inl.inlined_function_id); 123 Print(out, function); 124 } 125 out << " inlined at "; 126 inl.position.Print(out, code); 127 } 128 } 129 130 } // namespace internal 131 } // namespace v8 132