1c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch// Copyright 2016 the V8 project authors. All rights reserved.
2c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch// found in the LICENSE file.
4c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
5c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch#include "src/source-position.h"
6c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch#include "src/compilation-info.h"
7c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch#include "src/objects-inl.h"
8c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
9c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochnamespace v8 {
10c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochnamespace internal {
11c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
12c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochstd::ostream& operator<<(std::ostream& out, const SourcePositionInfo& pos) {
13c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  Handle<SharedFunctionInfo> function(pos.function);
14c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  Handle<Script> script(Script::cast(function->script()));
15c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  out << "<";
16c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (script->name()->IsString()) {
17c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    out << String::cast(script->name())->ToCString(DISALLOW_NULLS).get();
18c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  } else {
19c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    out << "unknown";
20c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  }
21c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  out << ":" << pos.line + 1 << ":" << pos.column + 1 << ">";
22c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  return out;
23c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch}
24c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
25c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochstd::ostream& operator<<(std::ostream& out,
26c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                         const std::vector<SourcePositionInfo>& stack) {
27c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  bool first = true;
28c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  for (const SourcePositionInfo& pos : stack) {
29c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    if (!first) out << " inlined at ";
30c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    out << pos;
31c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    first = false;
32c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  }
33c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  return out;
34c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch}
35c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
36c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochstd::ostream& operator<<(std::ostream& out, const SourcePosition& pos) {
37c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (pos.isInlined()) {
38c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    out << "<inlined(" << pos.InliningId() << "):";
39c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  } else {
40c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    out << "<not inlined:";
41c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  }
42c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  out << pos.ScriptOffset() << ">";
43c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  return out;
44c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch}
45c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
46c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochSourcePositionInfo SourcePosition::Info(
47c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    Handle<SharedFunctionInfo> function) const {
48c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  SourcePositionInfo result(*this, function);
49c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  Handle<Script> script(Script::cast(function->script()));
50c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  Script::PositionInfo pos;
51c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (Script::GetPositionInfo(script, ScriptOffset(), &pos,
52c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                              Script::WITH_OFFSET)) {
53c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    result.line = pos.line;
54c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    result.column = pos.column;
55c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  }
56c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  return result;
57c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch}
58c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
59c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochstd::vector<SourcePositionInfo> SourcePosition::InliningStack(
60c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    CompilationInfo* cinfo) const {
61c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  SourcePosition pos = *this;
62c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  std::vector<SourcePositionInfo> stack;
63c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  while (pos.isInlined()) {
64c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    const auto& inl = cinfo->inlined_functions()[pos.InliningId()];
65c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    stack.push_back(pos.Info(inl.shared_info));
66c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    pos = inl.position.position;
67c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  }
68c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  stack.push_back(pos.Info(cinfo->shared_info()));
69c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  return stack;
70c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch}
71c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
72c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochstd::vector<SourcePositionInfo> SourcePosition::InliningStack(
73c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    Handle<Code> code) const {
74c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  Handle<DeoptimizationInputData> deopt_data(
75c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      DeoptimizationInputData::cast(code->deoptimization_data()));
76c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  SourcePosition pos = *this;
77c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  std::vector<SourcePositionInfo> stack;
78c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  while (pos.isInlined()) {
79c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    InliningPosition inl =
80c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        deopt_data->InliningPositions()->get(pos.InliningId());
81c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    Handle<SharedFunctionInfo> function(
82c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        deopt_data->GetInlinedFunction(inl.inlined_function_id));
83c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    stack.push_back(pos.Info(function));
84c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    pos = inl.position;
85c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  }
86c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  Handle<SharedFunctionInfo> function(
87c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      SharedFunctionInfo::cast(deopt_data->SharedFunctionInfo()));
88c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  stack.push_back(pos.Info(function));
89c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  return stack;
90c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch}
91c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
92c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochvoid SourcePosition::Print(std::ostream& out,
93c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                           SharedFunctionInfo* function) const {
94c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  Script* script = Script::cast(function->script());
95c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  Object* source_name = script->name();
96c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  Script::PositionInfo pos;
97c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  script->GetPositionInfo(ScriptOffset(), &pos, Script::WITH_OFFSET);
98c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  out << "<";
99c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (source_name->IsString()) {
100c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    out << String::cast(source_name)
101c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch               ->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL)
102c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch               .get();
103c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  } else {
104c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    out << "unknown";
105c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  }
106c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  out << ":" << pos.line + 1 << ":" << pos.column + 1 << ">";
107c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch}
108c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
109c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochvoid SourcePosition::Print(std::ostream& out, Code* code) const {
110c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  DeoptimizationInputData* deopt_data =
111c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      DeoptimizationInputData::cast(code->deoptimization_data());
112c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (!isInlined()) {
113c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    SharedFunctionInfo* function(
114c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        SharedFunctionInfo::cast(deopt_data->SharedFunctionInfo()));
115c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    Print(out, function);
116c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  } else {
117c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    InliningPosition inl = deopt_data->InliningPositions()->get(InliningId());
118c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    if (inl.inlined_function_id == -1) {
119c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      out << *this;
120c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    } else {
121c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      SharedFunctionInfo* function =
122c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          deopt_data->GetInlinedFunction(inl.inlined_function_id);
123c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      Print(out, function);
124c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    }
125c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    out << " inlined at ";
126c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    inl.position.Print(out, code);
127c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  }
128c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch}
129c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
130c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch}  // namespace internal
131c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch}  // namespace v8
132