| // Copyright 2016 the V8 project authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #ifndef V8_SOURCE_POSITION_H_ | |
| #define V8_SOURCE_POSITION_H_ | |
| #include <ostream> | |
| #include "src/flags.h" | |
| #include "src/globals.h" | |
| #include "src/handles.h" | |
| #include "src/utils.h" | |
| namespace v8 { | |
| namespace internal { | |
| class Code; | |
| class OptimizedCompilationInfo; | |
| class Script; | |
| class SharedFunctionInfo; | |
| struct SourcePositionInfo; | |
| // SourcePosition stores | |
| // - script_offset (31 bit non-negative int or kNoSourcePosition) | |
| // - inlining_id (16 bit non-negative int or kNotInlined). | |
| // | |
| // A defined inlining_id refers to positions in | |
| // OptimizedCompilationInfo::inlined_functions or | |
| // DeoptimizationData::InliningPositions, depending on the compilation stage. | |
| class SourcePosition final { | |
| public: | |
| explicit SourcePosition(int script_offset, int inlining_id = kNotInlined) | |
| : value_(0) { | |
| SetScriptOffset(script_offset); | |
| SetInliningId(inlining_id); | |
| } | |
| static SourcePosition Unknown() { return SourcePosition(kNoSourcePosition); } | |
| bool IsKnown() const { | |
| return ScriptOffset() != kNoSourcePosition || InliningId() != kNotInlined; | |
| } | |
| bool isInlined() const { return InliningId() != kNotInlined; } | |
| // Assumes that the code object is optimized | |
| std::vector<SourcePositionInfo> InliningStack(Handle<Code> code) const; | |
| std::vector<SourcePositionInfo> InliningStack( | |
| OptimizedCompilationInfo* cinfo) const; | |
| void Print(std::ostream& out, Code* code) const; | |
| void PrintJson(std::ostream& out) const; | |
| int ScriptOffset() const { return ScriptOffsetField::decode(value_) - 1; } | |
| int InliningId() const { return InliningIdField::decode(value_) - 1; } | |
| void SetScriptOffset(int script_offset) { | |
| DCHECK(script_offset <= ScriptOffsetField::kMax - 2); | |
| DCHECK_GE(script_offset, kNoSourcePosition); | |
| value_ = ScriptOffsetField::update(value_, script_offset + 1); | |
| } | |
| void SetInliningId(int inlining_id) { | |
| DCHECK(inlining_id <= InliningIdField::kMax - 2); | |
| DCHECK_GE(inlining_id, kNotInlined); | |
| value_ = InliningIdField::update(value_, inlining_id + 1); | |
| } | |
| static const int kNotInlined = -1; | |
| STATIC_ASSERT(kNoSourcePosition == -1); | |
| int64_t raw() const { return static_cast<int64_t>(value_); } | |
| static SourcePosition FromRaw(int64_t raw) { | |
| SourcePosition position = Unknown(); | |
| DCHECK_GE(raw, 0); | |
| position.value_ = static_cast<uint64_t>(raw); | |
| return position; | |
| } | |
| private: | |
| void Print(std::ostream& out, SharedFunctionInfo* function) const; | |
| // InliningId is in the high bits for better compression in | |
| // SourcePositionTable. | |
| typedef BitField64<int, 0, 31> ScriptOffsetField; | |
| typedef BitField64<int, 31, 16> InliningIdField; | |
| // Leaving the highest bit untouched to allow for signed conversion. | |
| uint64_t value_; | |
| }; | |
| inline bool operator==(const SourcePosition& lhs, const SourcePosition& rhs) { | |
| return lhs.raw() == rhs.raw(); | |
| } | |
| inline bool operator!=(const SourcePosition& lhs, const SourcePosition& rhs) { | |
| return !(lhs == rhs); | |
| } | |
| struct InliningPosition { | |
| // position of the inlined call | |
| SourcePosition position = SourcePosition::Unknown(); | |
| // references position in DeoptimizationData::literals() | |
| int inlined_function_id; | |
| }; | |
| struct SourcePositionInfo { | |
| SourcePositionInfo(SourcePosition pos, Handle<SharedFunctionInfo> f); | |
| SourcePosition position; | |
| Handle<Script> script; | |
| int line = -1; | |
| int column = -1; | |
| }; | |
| std::ostream& operator<<(std::ostream& out, const SourcePosition& pos); | |
| std::ostream& operator<<(std::ostream& out, const SourcePositionInfo& pos); | |
| std::ostream& operator<<(std::ostream& out, | |
| const std::vector<SourcePositionInfo>& stack); | |
| } // namespace internal | |
| } // namespace v8 | |
| #endif // V8_SOURCE_POSITION_H_ |