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 // DeoptimizationInputData::InliningPositions, depending on the compilation 31 // stage. 32 class 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 Unknown()40 static SourcePosition Unknown() { return SourcePosition(kNoSourcePosition); } IsKnown()41 bool IsKnown() const { 42 return ScriptOffset() != kNoSourcePosition || InliningId() != kNotInlined; 43 } isInlined()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 ScriptOffset()51 int ScriptOffset() const { return ScriptOffsetField::decode(value_) - 1; } InliningId()52 int InliningId() const { return InliningIdField::decode(value_) - 1; } 53 SetScriptOffset(int script_offset)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 } SetInliningId(int inlining_id)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 raw()68 int64_t raw() const { return static_cast<int64_t>(value_); } FromRaw(int64_t raw)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 88 inline bool operator==(const SourcePosition& lhs, const SourcePosition& rhs) { 89 return lhs.raw() == rhs.raw(); 90 } 91 92 inline bool operator!=(const SourcePosition& lhs, const SourcePosition& rhs) { 93 return !(lhs == rhs); 94 } 95 96 struct 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 104 struct SourcePositionInfo { SourcePositionInfoSourcePositionInfo105 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 114 std::ostream& operator<<(std::ostream& out, const SourcePosition& pos); 115 116 std::ostream& operator<<(std::ostream& out, const SourcePositionInfo& pos); 117 std::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