Line data Source code
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 :
15 : namespace v8 {
16 : namespace internal {
17 :
18 : class Code;
19 : class CompilationInfo;
20 : class Script;
21 : class SharedFunctionInfo;
22 : struct 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 : // DeoptimizationData::InliningPositions, depending on the compilation stage.
31 : class SourcePosition final {
32 : public:
33 : explicit SourcePosition(int script_offset, int inlining_id = kNotInlined)
34 1806431 : : value_(0) {
35 : SetScriptOffset(script_offset);
36 : SetInliningId(inlining_id);
37 : }
38 :
39 : static SourcePosition Unknown() { return SourcePosition(kNoSourcePosition); }
40 : bool IsKnown() const {
41 245634128 : return ScriptOffset() != kNoSourcePosition || InliningId() != kNotInlined;
42 : }
43 : bool isInlined() const { return InliningId() != kNotInlined; }
44 :
45 : // Assumes that the code object is optimized
46 : std::vector<SourcePositionInfo> InliningStack(Handle<Code> code) const;
47 : std::vector<SourcePositionInfo> InliningStack(CompilationInfo* cinfo) const;
48 :
49 : void Print(std::ostream& out, Code* code) const;
50 :
51 119475090 : int ScriptOffset() const { return ScriptOffsetField::decode(value_) - 1; }
52 6402205 : int InliningId() const { return InliningIdField::decode(value_) - 1; }
53 :
54 : void SetScriptOffset(int script_offset) {
55 : DCHECK(script_offset <= ScriptOffsetField::kMax - 2);
56 : DCHECK_GE(script_offset, kNoSourcePosition);
57 31661520 : value_ = ScriptOffsetField::update(value_, script_offset + 1);
58 : }
59 : void SetInliningId(int inlining_id) {
60 : DCHECK(inlining_id <= InliningIdField::kMax - 2);
61 : DCHECK_GE(inlining_id, kNotInlined);
62 30348614 : value_ = InliningIdField::update(value_, inlining_id + 1);
63 : }
64 :
65 : static const int kNotInlined = -1;
66 : STATIC_ASSERT(kNoSourcePosition == -1);
67 :
68 28187448 : 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 92206901 : position.value_ = static_cast<uint64_t>(raw);
73 : return position;
74 : }
75 :
76 : private:
77 : void Print(std::ostream& out, SharedFunctionInfo* function) const;
78 :
79 : // InliningId is in the high bits for better compression in
80 : // SourcePositionTable.
81 : typedef BitField64<int, 0, 31> ScriptOffsetField;
82 : typedef BitField64<int, 31, 16> InliningIdField;
83 : // Leaving the highest bit untouched to allow for signed conversion.
84 : uint64_t value_;
85 : };
86 :
87 : inline bool operator==(const SourcePosition& lhs, const SourcePosition& rhs) {
88 : return lhs.raw() == rhs.raw();
89 : }
90 :
91 : inline bool operator!=(const SourcePosition& lhs, const SourcePosition& rhs) {
92 : return !(lhs == rhs);
93 : }
94 :
95 61528 : struct InliningPosition {
96 : // position of the inlined call
97 : SourcePosition position = SourcePosition::Unknown();
98 :
99 : // references position in DeoptimizationData::literals()
100 : int inlined_function_id;
101 : };
102 :
103 : struct SourcePositionInfo {
104 : SourcePositionInfo(SourcePosition pos, Handle<SharedFunctionInfo> f);
105 :
106 : SourcePosition position;
107 : Handle<SharedFunctionInfo> function;
108 : int line = -1;
109 : int column = -1;
110 : };
111 :
112 : std::ostream& operator<<(std::ostream& out, const SourcePosition& pos);
113 :
114 : std::ostream& operator<<(std::ostream& out, const SourcePositionInfo& pos);
115 : std::ostream& operator<<(std::ostream& out,
116 : const std::vector<SourcePositionInfo>& stack);
117 :
118 : } // namespace internal
119 : } // namespace v8
120 :
121 : #endif // V8_SOURCE_POSITION_H_
|