• 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/source-position.h"
6 #include "src/compilation-info.h"
7 #include "src/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   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 
operator <<(std::ostream & out,const std::vector<SourcePositionInfo> & stack)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 
operator <<(std::ostream & out,const SourcePosition & pos)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 
InliningStack(CompilationInfo * cinfo) const52 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 
InliningStack(Handle<Code> code) const65 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 
Print(std::ostream & out,SharedFunctionInfo * function) const85 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 
Print(std::ostream & out,Code * code) const105 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 
SourcePositionInfo(SourcePosition pos,Handle<SharedFunctionInfo> f)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