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