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#ifndef V8_SOURCE_POSITION_H_
6#define V8_SOURCE_POSITION_H_
7
8#include <ostream>
9
10#include "src/flags.h"
11#include "src/globals.h"
12#include "src/handles.h"
13#include "src/utils.h"
14
15namespace v8 {
16namespace internal {
17
18class Code;
19class CompilationInfo;
20class Script;
21class SharedFunctionInfo;
22struct SourcePositionInfo;
23
24// SourcePosition stores
25// - script_offset (31 bit non-negative int or kNoSourcePosition)
26// - inlining_id (16 bit non-negative int or kNotInlined).
27//
28// A defined inlining_id refers to positions in
29// CompilationInfo::inlined_functions or
30// DeoptimizationInputData::InliningPositions, depending on the compilation
31// stage.
32class SourcePosition final {
33 public:
34  explicit SourcePosition(int script_offset, int inlining_id = kNotInlined)
35      : value_(0) {
36    SetScriptOffset(script_offset);
37    SetInliningId(inlining_id);
38  }
39
40  static SourcePosition Unknown() { return SourcePosition(kNoSourcePosition); }
41  bool IsKnown() const {
42    return ScriptOffset() != kNoSourcePosition || InliningId() != kNotInlined;
43  }
44  bool isInlined() const { return InliningId() != kNotInlined; }
45
46  std::vector<SourcePositionInfo> InliningStack(Handle<Code> code) const;
47  std::vector<SourcePositionInfo> InliningStack(CompilationInfo* code) const;
48
49  void Print(std::ostream& out, Code* function) const;
50
51  int ScriptOffset() const { return ScriptOffsetField::decode(value_) - 1; }
52  int InliningId() const { return InliningIdField::decode(value_) - 1; }
53
54  void SetScriptOffset(int script_offset) {
55    DCHECK(script_offset <= ScriptOffsetField::kMax - 2);
56    DCHECK(script_offset >= kNoSourcePosition);
57    value_ = ScriptOffsetField::update(value_, script_offset + 1);
58  }
59  void SetInliningId(int inlining_id) {
60    DCHECK(inlining_id <= InliningIdField::kMax - 2);
61    DCHECK(inlining_id >= kNotInlined);
62    value_ = InliningIdField::update(value_, inlining_id + 1);
63  }
64
65  static const int kNotInlined = -1;
66  STATIC_ASSERT(kNoSourcePosition == -1);
67
68  int64_t raw() const { return static_cast<int64_t>(value_); }
69  static SourcePosition FromRaw(int64_t raw) {
70    SourcePosition position = Unknown();
71    DCHECK_GE(raw, 0);
72    position.value_ = static_cast<uint64_t>(raw);
73    return position;
74  }
75
76 private:
77  void Print(std::ostream& out, SharedFunctionInfo* function) const;
78  SourcePositionInfo Info(Handle<SharedFunctionInfo> script) const;
79
80  // InliningId is in the high bits for better compression in
81  // SourcePositionTable.
82  typedef BitField64<int, 0, 31> ScriptOffsetField;
83  typedef BitField64<int, 31, 16> InliningIdField;
84  // Leaving the highest bit untouched to allow for signed conversion.
85  uint64_t value_;
86};
87
88inline bool operator==(const SourcePosition& lhs, const SourcePosition& rhs) {
89  return lhs.raw() == rhs.raw();
90}
91
92inline bool operator!=(const SourcePosition& lhs, const SourcePosition& rhs) {
93  return !(lhs == rhs);
94}
95
96struct InliningPosition {
97  // position of the inlined call
98  SourcePosition position = SourcePosition::Unknown();
99
100  // references position in DeoptimizationInputData::literals()
101  int inlined_function_id;
102};
103
104struct SourcePositionInfo {
105  explicit SourcePositionInfo(SourcePosition pos, Handle<SharedFunctionInfo> f)
106      : position(pos), function(f) {}
107
108  SourcePosition position;
109  Handle<SharedFunctionInfo> function;
110  int line = -1;
111  int column = -1;
112};
113
114std::ostream& operator<<(std::ostream& out, const SourcePosition& pos);
115
116std::ostream& operator<<(std::ostream& out, const SourcePositionInfo& pos);
117std::ostream& operator<<(std::ostream& out,
118                         const std::vector<SourcePositionInfo>& stack);
119
120}  // namespace internal
121}  // namespace v8
122
123#endif  // V8_SOURCE_POSITION_H_
124