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/objects-inl.h"
7 : #include "src/optimized-compilation-info.h"
8 :
9 : namespace v8 {
10 : namespace internal {
11 :
12 994 : std::ostream& operator<<(std::ostream& out, const SourcePositionInfo& pos) {
13 994 : out << "<";
14 1988 : if (!pos.script.is_null() && pos.script->name()->IsString()) {
15 2982 : out << String::cast(pos.script->name())->ToCString(DISALLOW_NULLS).get();
16 : } else {
17 0 : out << "unknown";
18 : }
19 2982 : out << ":" << pos.line + 1 << ":" << pos.column + 1 << ">";
20 994 : return out;
21 : }
22 :
23 994 : std::ostream& operator<<(std::ostream& out,
24 : const std::vector<SourcePositionInfo>& stack) {
25 : bool first = true;
26 1988 : for (const SourcePositionInfo& pos : stack) {
27 994 : if (!first) out << " inlined at ";
28 994 : out << pos;
29 : first = false;
30 : }
31 994 : return out;
32 : }
33 :
34 169 : std::ostream& operator<<(std::ostream& out, const SourcePosition& pos) {
35 169 : if (pos.isInlined()) {
36 0 : out << "<inlined(" << pos.InliningId() << "):";
37 : } else {
38 169 : out << "<not inlined:";
39 : }
40 :
41 169 : if (pos.IsExternal()) {
42 0 : out << pos.ExternalLine() << ", " << pos.ExternalFileId() << ">";
43 : } else {
44 169 : out << pos.ScriptOffset() << ">";
45 : }
46 169 : return out;
47 : }
48 :
49 994 : std::vector<SourcePositionInfo> SourcePosition::InliningStack(
50 : OptimizedCompilationInfo* cinfo) const {
51 994 : SourcePosition pos = *this;
52 : std::vector<SourcePositionInfo> stack;
53 994 : while (pos.isInlined()) {
54 0 : const auto& inl = cinfo->inlined_functions()[pos.InliningId()];
55 0 : stack.push_back(SourcePositionInfo(pos, inl.shared_info));
56 0 : pos = inl.position.position;
57 : }
58 1988 : stack.push_back(SourcePositionInfo(pos, cinfo->shared_info()));
59 994 : return stack;
60 : }
61 :
62 57 : std::vector<SourcePositionInfo> SourcePosition::InliningStack(
63 : Handle<Code> code) const {
64 : Isolate* isolate = code->GetIsolate();
65 : Handle<DeoptimizationData> deopt_data(
66 : DeoptimizationData::cast(code->deoptimization_data()), isolate);
67 57 : SourcePosition pos = *this;
68 : std::vector<SourcePositionInfo> stack;
69 265 : while (pos.isInlined()) {
70 : InliningPosition inl =
71 208 : deopt_data->InliningPositions()->get(pos.InliningId());
72 : Handle<SharedFunctionInfo> function(
73 208 : deopt_data->GetInlinedFunction(inl.inlined_function_id), isolate);
74 208 : stack.push_back(SourcePositionInfo(pos, function));
75 : pos = inl.position;
76 : }
77 : Handle<SharedFunctionInfo> function(
78 : SharedFunctionInfo::cast(deopt_data->SharedFunctionInfo()), isolate);
79 114 : stack.push_back(SourcePositionInfo(pos, function));
80 57 : return stack;
81 : }
82 :
83 246 : void SourcePosition::Print(std::ostream& out,
84 : SharedFunctionInfo function) const {
85 : Script::PositionInfo pos;
86 : Object source_name;
87 492 : if (function->script()->IsScript()) {
88 246 : Script script = Script::cast(function->script());
89 : source_name = script->name();
90 246 : script->GetPositionInfo(ScriptOffset(), &pos, Script::WITH_OFFSET);
91 : }
92 246 : out << "<";
93 246 : if (source_name->IsString()) {
94 0 : out << String::cast(source_name)
95 0 : ->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL)
96 0 : .get();
97 : } else {
98 246 : out << "unknown";
99 : }
100 738 : out << ":" << pos.line + 1 << ":" << pos.column + 1 << ">";
101 246 : }
102 :
103 602 : void SourcePosition::PrintJson(std::ostream& out) const {
104 602 : if (IsExternal()) {
105 0 : out << "{ \"line\" : " << ExternalLine() << ", "
106 0 : << " \"fileId\" : " << ExternalFileId() << ", "
107 0 : << " \"inliningId\" : " << InliningId() << "}";
108 : } else {
109 602 : out << "{ \"scriptOffset\" : " << ScriptOffset() << ", "
110 602 : << " \"inliningId\" : " << InliningId() << "}";
111 : }
112 602 : }
113 :
114 246 : void SourcePosition::Print(std::ostream& out, Code code) const {
115 : DeoptimizationData deopt_data =
116 246 : DeoptimizationData::cast(code->deoptimization_data());
117 246 : if (!isInlined()) {
118 : SharedFunctionInfo function(
119 246 : SharedFunctionInfo::cast(deopt_data->SharedFunctionInfo()));
120 246 : Print(out, function);
121 : } else {
122 0 : InliningPosition inl = deopt_data->InliningPositions()->get(InliningId());
123 0 : if (inl.inlined_function_id == -1) {
124 0 : out << *this;
125 : } else {
126 : SharedFunctionInfo function =
127 0 : deopt_data->GetInlinedFunction(inl.inlined_function_id);
128 0 : Print(out, function);
129 : }
130 0 : out << " inlined at ";
131 0 : inl.position.Print(out, code);
132 : }
133 246 : }
134 :
135 1307 : SourcePositionInfo::SourcePositionInfo(SourcePosition pos,
136 : Handle<SharedFunctionInfo> f)
137 : : position(pos),
138 : shared(f),
139 5228 : script(f.is_null() || !f->script()->IsScript()
140 : ? Handle<Script>::null()
141 5228 : : handle(Script::cast(f->script()), f->GetIsolate())) {
142 1307 : if (!script.is_null()) {
143 : Script::PositionInfo info;
144 1307 : if (Script::GetPositionInfo(script, pos.ScriptOffset(), &info,
145 : Script::WITH_OFFSET)) {
146 1307 : line = info.line;
147 1307 : column = info.column;
148 : }
149 : }
150 1307 : }
151 :
152 : } // namespace internal
153 122036 : } // namespace v8
|