summaryrefslogtreecommitdiff
path: root/deps/v8/src/codegen/source-position.h
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/codegen/source-position.h')
-rw-r--r--deps/v8/src/codegen/source-position.h197
1 files changed, 197 insertions, 0 deletions
diff --git a/deps/v8/src/codegen/source-position.h b/deps/v8/src/codegen/source-position.h
new file mode 100644
index 0000000000..ad0132b827
--- /dev/null
+++ b/deps/v8/src/codegen/source-position.h
@@ -0,0 +1,197 @@
+// 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_CODEGEN_SOURCE_POSITION_H_
+#define V8_CODEGEN_SOURCE_POSITION_H_
+
+#include <ostream>
+
+#include "src/common/globals.h"
+#include "src/flags/flags.h"
+#include "src/handles/handles.h"
+#include "src/utils/utils.h"
+
+namespace v8 {
+namespace internal {
+
+class Code;
+class OptimizedCompilationInfo;
+class Script;
+class SharedFunctionInfo;
+struct SourcePositionInfo;
+
+// SourcePosition stores
+// - is_external (1 bit true/false)
+//
+// - if is_external is true:
+// - external_line (20 bits, non-negative int)
+// - external_file_id (10 bits, non-negative int)
+//
+// - if is_external is false:
+// - script_offset (30 bit non-negative int or kNoSourcePosition)
+//
+// - In both cases, there is an inlining_id.
+// - inlining_id (16 bit non-negative int or kNotInlined).
+//
+// An "external" SourcePosition is one given by a file_id and a line,
+// suitable for embedding references to .cc or .tq files.
+// Otherwise, a SourcePosition contains an offset into a JavaScript
+// file.
+//
+// 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) {
+ SetIsExternal(false);
+ SetScriptOffset(script_offset);
+ SetInliningId(inlining_id);
+ }
+
+ // External SourcePositions should use the following method to construct
+ // SourcePositions to avoid confusion.
+ static SourcePosition External(int line, int file_id) {
+ return SourcePosition(line, file_id, kNotInlined);
+ }
+
+ static SourcePosition Unknown() { return SourcePosition(kNoSourcePosition); }
+ bool IsKnown() const {
+ if (IsExternal()) return true;
+ return ScriptOffset() != kNoSourcePosition || InliningId() != kNotInlined;
+ }
+ bool isInlined() const {
+ if (IsExternal()) return false;
+ return InliningId() != kNotInlined;
+ }
+
+ bool IsExternal() const { return IsExternalField::decode(value_); }
+ bool IsJavaScript() const { return !IsExternal(); }
+
+ int ExternalLine() const {
+ DCHECK(IsExternal());
+ return ExternalLineField::decode(value_);
+ }
+
+ int ExternalFileId() const {
+ DCHECK(IsExternal());
+ return ExternalFileIdField::decode(value_);
+ }
+
+ // 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 {
+ DCHECK(IsJavaScript());
+ return ScriptOffsetField::decode(value_) - 1;
+ }
+ int InliningId() const { return InliningIdField::decode(value_) - 1; }
+
+ void SetIsExternal(bool external) {
+ value_ = IsExternalField::update(value_, external);
+ }
+ void SetExternalLine(int line) {
+ DCHECK(IsExternal());
+ DCHECK(line <= ExternalLineField::kMax - 1);
+ value_ = ExternalLineField::update(value_, line);
+ }
+ void SetExternalFileId(int file_id) {
+ DCHECK(IsExternal());
+ DCHECK(file_id <= ExternalFileIdField::kMax - 1);
+ value_ = ExternalFileIdField::update(value_, file_id);
+ }
+
+ void SetScriptOffset(int script_offset) {
+ DCHECK(IsJavaScript());
+ 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:
+ // Used by SourcePosition::External(line, file_id).
+ SourcePosition(int line, int file_id, int inlining_id) : value_(0) {
+ SetIsExternal(true);
+ SetExternalLine(line);
+ SetExternalFileId(file_id);
+ SetInliningId(inlining_id);
+ }
+
+ void Print(std::ostream& out, SharedFunctionInfo function) const;
+
+ using IsExternalField = BitField64<bool, 0, 1>;
+
+ // The two below are only used if IsExternal() is true.
+ using ExternalLineField = BitField64<int, 1, 20>;
+ using ExternalFileIdField = BitField64<int, 21, 10>;
+
+ // ScriptOffsetField is only used if IsExternal() is false.
+ using ScriptOffsetField = BitField64<int, 1, 30>;
+
+ // InliningId is in the high bits for better compression in
+ // SourcePositionTable.
+ using InliningIdField = BitField64<int, 31, 16>;
+
+ // 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<SharedFunctionInfo> shared;
+ 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_CODEGEN_SOURCE_POSITION_H_