• Home
  • History
  • Annotate
  • 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/objects-inl.h"
7 #include "src/optimized-compilation-info.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   out << pos.ScriptOffset() << ">";
41   return out;
42 }
43 
InliningStack(OptimizedCompilationInfo * cinfo) const44 std::vector<SourcePositionInfo> SourcePosition::InliningStack(
45     OptimizedCompilationInfo* cinfo) const {
46   SourcePosition pos = *this;
47   std::vector<SourcePositionInfo> stack;
48   while (pos.isInlined()) {
49     const auto& inl = cinfo->inlined_functions()[pos.InliningId()];
50     stack.push_back(SourcePositionInfo(pos, inl.shared_info));
51     pos = inl.position.position;
52   }
53   stack.push_back(SourcePositionInfo(pos, cinfo->shared_info()));
54   return stack;
55 }
56 
InliningStack(Handle<Code> code) const57 std::vector<SourcePositionInfo> SourcePosition::InliningStack(
58     Handle<Code> code) const {
59   Isolate* isolate = code->GetIsolate();
60   Handle<DeoptimizationData> deopt_data(
61       DeoptimizationData::cast(code->deoptimization_data()), isolate);
62   SourcePosition pos = *this;
63   std::vector<SourcePositionInfo> stack;
64   while (pos.isInlined()) {
65     InliningPosition inl =
66         deopt_data->InliningPositions()->get(pos.InliningId());
67     Handle<SharedFunctionInfo> function(
68         deopt_data->GetInlinedFunction(inl.inlined_function_id), isolate);
69     stack.push_back(SourcePositionInfo(pos, function));
70     pos = inl.position;
71   }
72   Handle<SharedFunctionInfo> function(
73       SharedFunctionInfo::cast(deopt_data->SharedFunctionInfo()), isolate);
74   stack.push_back(SourcePositionInfo(pos, function));
75   return stack;
76 }
77 
Print(std::ostream & out,SharedFunctionInfo * function) const78 void SourcePosition::Print(std::ostream& out,
79                            SharedFunctionInfo* function) const {
80   Script::PositionInfo pos;
81   Object* source_name = nullptr;
82   if (function->script()->IsScript()) {
83     Script* script = Script::cast(function->script());
84     source_name = script->name();
85     script->GetPositionInfo(ScriptOffset(), &pos, Script::WITH_OFFSET);
86   }
87   out << "<";
88   if (source_name != nullptr && source_name->IsString()) {
89     out << String::cast(source_name)
90                ->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL)
91                .get();
92   } else {
93     out << "unknown";
94   }
95   out << ":" << pos.line + 1 << ":" << pos.column + 1 << ">";
96 }
97 
PrintJson(std::ostream & out) const98 void SourcePosition::PrintJson(std::ostream& out) const {
99   out << "{ \"scriptOffset\" : " << ScriptOffset() << ", "
100       << "  \"inliningId\" : " << InliningId() << "}";
101 }
102 
Print(std::ostream & out,Code * code) const103 void SourcePosition::Print(std::ostream& out, Code* code) const {
104   DeoptimizationData* deopt_data =
105       DeoptimizationData::cast(code->deoptimization_data());
106   if (!isInlined()) {
107     SharedFunctionInfo* function(
108         SharedFunctionInfo::cast(deopt_data->SharedFunctionInfo()));
109     Print(out, function);
110   } else {
111     InliningPosition inl = deopt_data->InliningPositions()->get(InliningId());
112     if (inl.inlined_function_id == -1) {
113       out << *this;
114     } else {
115       SharedFunctionInfo* function =
116           deopt_data->GetInlinedFunction(inl.inlined_function_id);
117       Print(out, function);
118     }
119     out << " inlined at ";
120     inl.position.Print(out, code);
121   }
122 }
123 
SourcePositionInfo(SourcePosition pos,Handle<SharedFunctionInfo> f)124 SourcePositionInfo::SourcePositionInfo(SourcePosition pos,
125                                        Handle<SharedFunctionInfo> f)
126     : position(pos),
127       script(f.is_null() || !f->script()->IsScript()
128                  ? Handle<Script>::null()
129                  : handle(Script::cast(f->script()), f->GetIsolate())) {
130   if (!script.is_null()) {
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