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 OptimizedCompilationInfo; 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 // OptimizedCompilationInfo::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 : value_(0) { 35 SetScriptOffset(script_offset); 36 SetInliningId(inlining_id); 37 } 38 Unknown()39 static SourcePosition Unknown() { return SourcePosition(kNoSourcePosition); } IsKnown()40 bool IsKnown() const { 41 return ScriptOffset() != kNoSourcePosition || InliningId() != kNotInlined; 42 } isInlined()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( 48 OptimizedCompilationInfo* cinfo) const; 49 50 void Print(std::ostream& out, Code* code) const; 51 void PrintJson(std::ostream& out) const; 52 ScriptOffset()53 int ScriptOffset() const { return ScriptOffsetField::decode(value_) - 1; } InliningId()54 int InliningId() const { return InliningIdField::decode(value_) - 1; } 55 SetScriptOffset(int script_offset)56 void SetScriptOffset(int script_offset) { 57 DCHECK(script_offset <= ScriptOffsetField::kMax - 2); 58 DCHECK_GE(script_offset, kNoSourcePosition); 59 value_ = ScriptOffsetField::update(value_, script_offset + 1); 60 } SetInliningId(int inlining_id)61 void SetInliningId(int inlining_id) { 62 DCHECK(inlining_id <= InliningIdField::kMax - 2); 63 DCHECK_GE(inlining_id, kNotInlined); 64 value_ = InliningIdField::update(value_, inlining_id + 1); 65 } 66 67 static const int kNotInlined = -1; 68 STATIC_ASSERT(kNoSourcePosition == -1); 69 raw()70 int64_t raw() const { return static_cast<int64_t>(value_); } FromRaw(int64_t raw)71 static SourcePosition FromRaw(int64_t raw) { 72 SourcePosition position = Unknown(); 73 DCHECK_GE(raw, 0); 74 position.value_ = static_cast<uint64_t>(raw); 75 return position; 76 } 77 78 private: 79 void Print(std::ostream& out, SharedFunctionInfo* function) const; 80 81 // InliningId is in the high bits for better compression in 82 // SourcePositionTable. 83 typedef BitField64<int, 0, 31> ScriptOffsetField; 84 typedef BitField64<int, 31, 16> InliningIdField; 85 // Leaving the highest bit untouched to allow for signed conversion. 86 uint64_t value_; 87 }; 88 89 inline bool operator==(const SourcePosition& lhs, const SourcePosition& rhs) { 90 return lhs.raw() == rhs.raw(); 91 } 92 93 inline bool operator!=(const SourcePosition& lhs, const SourcePosition& rhs) { 94 return !(lhs == rhs); 95 } 96 97 struct InliningPosition { 98 // position of the inlined call 99 SourcePosition position = SourcePosition::Unknown(); 100 101 // references position in DeoptimizationData::literals() 102 int inlined_function_id; 103 }; 104 105 struct SourcePositionInfo { 106 SourcePositionInfo(SourcePosition pos, Handle<SharedFunctionInfo> f); 107 108 SourcePosition position; 109 Handle<Script> script; 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