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 String* name = nullptr; 15 if (function->script()->IsScript()) { 16 Script* script = Script::cast(function->script()); 17 if (script->name()->IsString()) { 18 name = String::cast(script->name()); 19 } 20 } 21 out << "<"; 22 if (name != nullptr) { 23 out << name->ToCString(DISALLOW_NULLS).get(); 24 } else { 25 out << "unknown"; 26 } 27 out << ":" << pos.line + 1 << ":" << pos.column + 1 << ">"; 28 return out; 29 } 30 31 std::ostream& operator<<(std::ostream& out, 32 const std::vector<SourcePositionInfo>& stack) { 33 bool first = true; 34 for (const SourcePositionInfo& pos : stack) { 35 if (!first) out << " inlined at "; 36 out << pos; 37 first = false; 38 } 39 return out; 40 } 41 42 std::ostream& operator<<(std::ostream& out, const SourcePosition& pos) { 43 if (pos.isInlined()) { 44 out << "<inlined(" << pos.InliningId() << "):"; 45 } else { 46 out << "<not inlined:"; 47 } 48 out << pos.ScriptOffset() << ">"; 49 return out; 50 } 51 52 std::vector<SourcePositionInfo> SourcePosition::InliningStack( 53 CompilationInfo* cinfo) const { 54 SourcePosition pos = *this; 55 std::vector<SourcePositionInfo> stack; 56 while (pos.isInlined()) { 57 const auto& inl = cinfo->inlined_functions()[pos.InliningId()]; 58 stack.push_back(SourcePositionInfo(pos, inl.shared_info)); 59 pos = inl.position.position; 60 } 61 stack.push_back(SourcePositionInfo(pos, cinfo->shared_info())); 62 return stack; 63 } 64 65 std::vector<SourcePositionInfo> SourcePosition::InliningStack( 66 Handle<Code> code) const { 67 Handle<DeoptimizationInputData> deopt_data( 68 DeoptimizationInputData::cast(code->deoptimization_data())); 69 SourcePosition pos = *this; 70 std::vector<SourcePositionInfo> stack; 71 while (pos.isInlined()) { 72 InliningPosition inl = 73 deopt_data->InliningPositions()->get(pos.InliningId()); 74 Handle<SharedFunctionInfo> function( 75 deopt_data->GetInlinedFunction(inl.inlined_function_id)); 76 stack.push_back(SourcePositionInfo(pos, function)); 77 pos = inl.position; 78 } 79 Handle<SharedFunctionInfo> function( 80 SharedFunctionInfo::cast(deopt_data->SharedFunctionInfo())); 81 stack.push_back(SourcePositionInfo(pos, function)); 82 return stack; 83 } 84 85 void SourcePosition::Print(std::ostream& out, 86 SharedFunctionInfo* function) const { 87 Script::PositionInfo pos; 88 Object* source_name = nullptr; 89 if (function->script()->IsScript()) { 90 Script* script = Script::cast(function->script()); 91 source_name = script->name(); 92 script->GetPositionInfo(ScriptOffset(), &pos, Script::WITH_OFFSET); 93 } 94 out << "<"; 95 if (source_name != nullptr && source_name->IsString()) { 96 out << String::cast(source_name) 97 ->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL) 98 .get(); 99 } else { 100 out << "unknown"; 101 } 102 out << ":" << pos.line + 1 << ":" << pos.column + 1 << ">"; 103 } 104 105 void SourcePosition::Print(std::ostream& out, Code* code) const { 106 DeoptimizationInputData* deopt_data = 107 DeoptimizationInputData::cast(code->deoptimization_data()); 108 if (!isInlined()) { 109 SharedFunctionInfo* function( 110 SharedFunctionInfo::cast(deopt_data->SharedFunctionInfo())); 111 Print(out, function); 112 } else { 113 InliningPosition inl = deopt_data->InliningPositions()->get(InliningId()); 114 if (inl.inlined_function_id == -1) { 115 out << *this; 116 } else { 117 SharedFunctionInfo* function = 118 deopt_data->GetInlinedFunction(inl.inlined_function_id); 119 Print(out, function); 120 } 121 out << " inlined at "; 122 inl.position.Print(out, code); 123 } 124 } 125 126 SourcePositionInfo::SourcePositionInfo(SourcePosition pos, 127 Handle<SharedFunctionInfo> f) 128 : position(pos), function(f) { 129 if (function->script()->IsScript()) { 130 Handle<Script> script(Script::cast(function->script())); 131 Script::PositionInfo info; 132 if (Script::GetPositionInfo(script, pos.ScriptOffset(), &info, 133 Script::WITH_OFFSET)) { 134 line = info.line; 135 column = info.column; 136 } 137 } 138 } 139 140 } // namespace internal 141 } // namespace v8 142