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