11cb0ef41Sopenharmony_ci// Copyright 2016 the V8 project authors. All rights reserved. 21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 31cb0ef41Sopenharmony_ci// found in the LICENSE file. 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ci#ifndef V8_CODEGEN_SOURCE_POSITION_H_ 61cb0ef41Sopenharmony_ci#define V8_CODEGEN_SOURCE_POSITION_H_ 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_ci#include <iosfwd> 91cb0ef41Sopenharmony_ci 101cb0ef41Sopenharmony_ci#include "src/base/bit-field.h" 111cb0ef41Sopenharmony_ci#include "src/common/globals.h" 121cb0ef41Sopenharmony_ci#include "src/flags/flags.h" 131cb0ef41Sopenharmony_ci#include "src/handles/handles.h" 141cb0ef41Sopenharmony_ci 151cb0ef41Sopenharmony_cinamespace v8 { 161cb0ef41Sopenharmony_cinamespace internal { 171cb0ef41Sopenharmony_ci 181cb0ef41Sopenharmony_ciclass Code; 191cb0ef41Sopenharmony_ciclass OptimizedCompilationInfo; 201cb0ef41Sopenharmony_ciclass Script; 211cb0ef41Sopenharmony_ciclass SharedFunctionInfo; 221cb0ef41Sopenharmony_cistruct SourcePositionInfo; 231cb0ef41Sopenharmony_ci 241cb0ef41Sopenharmony_ci// SourcePosition stores 251cb0ef41Sopenharmony_ci// - is_external (1 bit true/false) 261cb0ef41Sopenharmony_ci// 271cb0ef41Sopenharmony_ci// - if is_external is true: 281cb0ef41Sopenharmony_ci// - external_line (20 bits, non-negative int) 291cb0ef41Sopenharmony_ci// - external_file_id (10 bits, non-negative int) 301cb0ef41Sopenharmony_ci// 311cb0ef41Sopenharmony_ci// - if is_external is false: 321cb0ef41Sopenharmony_ci// - script_offset (30 bit non-negative int or kNoSourcePosition) 331cb0ef41Sopenharmony_ci// 341cb0ef41Sopenharmony_ci// - In both cases, there is an inlining_id. 351cb0ef41Sopenharmony_ci// - inlining_id (16 bit non-negative int or kNotInlined). 361cb0ef41Sopenharmony_ci// 371cb0ef41Sopenharmony_ci// An "external" SourcePosition is one given by a file_id and a line, 381cb0ef41Sopenharmony_ci// suitable for embedding references to .cc or .tq files. 391cb0ef41Sopenharmony_ci// Otherwise, a SourcePosition contains an offset into a JavaScript 401cb0ef41Sopenharmony_ci// file. 411cb0ef41Sopenharmony_ci// 421cb0ef41Sopenharmony_ci// A defined inlining_id refers to positions in 431cb0ef41Sopenharmony_ci// OptimizedCompilationInfo::inlined_functions or 441cb0ef41Sopenharmony_ci// DeoptimizationData::InliningPositions, depending on the compilation stage. 451cb0ef41Sopenharmony_ciclass SourcePosition final { 461cb0ef41Sopenharmony_ci public: 471cb0ef41Sopenharmony_ci explicit SourcePosition(int script_offset, int inlining_id = kNotInlined) 481cb0ef41Sopenharmony_ci : value_(0) { 491cb0ef41Sopenharmony_ci SetIsExternal(false); 501cb0ef41Sopenharmony_ci SetScriptOffset(script_offset); 511cb0ef41Sopenharmony_ci SetInliningId(inlining_id); 521cb0ef41Sopenharmony_ci } 531cb0ef41Sopenharmony_ci 541cb0ef41Sopenharmony_ci // External SourcePositions should use the following method to construct 551cb0ef41Sopenharmony_ci // SourcePositions to avoid confusion. 561cb0ef41Sopenharmony_ci static SourcePosition External(int line, int file_id) { 571cb0ef41Sopenharmony_ci return SourcePosition(line, file_id, kNotInlined); 581cb0ef41Sopenharmony_ci } 591cb0ef41Sopenharmony_ci 601cb0ef41Sopenharmony_ci static SourcePosition Unknown() { return SourcePosition(kNoSourcePosition); } 611cb0ef41Sopenharmony_ci bool IsKnown() const { 621cb0ef41Sopenharmony_ci if (IsExternal()) return true; 631cb0ef41Sopenharmony_ci return ScriptOffset() != kNoSourcePosition || InliningId() != kNotInlined; 641cb0ef41Sopenharmony_ci } 651cb0ef41Sopenharmony_ci bool isInlined() const { 661cb0ef41Sopenharmony_ci if (IsExternal()) return false; 671cb0ef41Sopenharmony_ci return InliningId() != kNotInlined; 681cb0ef41Sopenharmony_ci } 691cb0ef41Sopenharmony_ci 701cb0ef41Sopenharmony_ci bool IsExternal() const { return IsExternalField::decode(value_); } 711cb0ef41Sopenharmony_ci bool IsJavaScript() const { return !IsExternal(); } 721cb0ef41Sopenharmony_ci 731cb0ef41Sopenharmony_ci int ExternalLine() const { 741cb0ef41Sopenharmony_ci DCHECK(IsExternal()); 751cb0ef41Sopenharmony_ci return ExternalLineField::decode(value_); 761cb0ef41Sopenharmony_ci } 771cb0ef41Sopenharmony_ci 781cb0ef41Sopenharmony_ci int ExternalFileId() const { 791cb0ef41Sopenharmony_ci DCHECK(IsExternal()); 801cb0ef41Sopenharmony_ci return ExternalFileIdField::decode(value_); 811cb0ef41Sopenharmony_ci } 821cb0ef41Sopenharmony_ci 831cb0ef41Sopenharmony_ci // Assumes that the code object is optimized 841cb0ef41Sopenharmony_ci std::vector<SourcePositionInfo> InliningStack(Handle<Code> code) const; 851cb0ef41Sopenharmony_ci std::vector<SourcePositionInfo> InliningStack( 861cb0ef41Sopenharmony_ci OptimizedCompilationInfo* cinfo) const; 871cb0ef41Sopenharmony_ci SourcePositionInfo FirstInfo(Handle<Code> code) const; 881cb0ef41Sopenharmony_ci 891cb0ef41Sopenharmony_ci void Print(std::ostream& out, Code code) const; 901cb0ef41Sopenharmony_ci void PrintJson(std::ostream& out) const; 911cb0ef41Sopenharmony_ci 921cb0ef41Sopenharmony_ci int ScriptOffset() const { 931cb0ef41Sopenharmony_ci DCHECK(IsJavaScript()); 941cb0ef41Sopenharmony_ci return ScriptOffsetField::decode(value_) - 1; 951cb0ef41Sopenharmony_ci } 961cb0ef41Sopenharmony_ci int InliningId() const { return InliningIdField::decode(value_) - 1; } 971cb0ef41Sopenharmony_ci 981cb0ef41Sopenharmony_ci void SetIsExternal(bool external) { 991cb0ef41Sopenharmony_ci value_ = IsExternalField::update(value_, external); 1001cb0ef41Sopenharmony_ci } 1011cb0ef41Sopenharmony_ci void SetExternalLine(int line) { 1021cb0ef41Sopenharmony_ci DCHECK(IsExternal()); 1031cb0ef41Sopenharmony_ci DCHECK(line <= ExternalLineField::kMax - 1); 1041cb0ef41Sopenharmony_ci value_ = ExternalLineField::update(value_, line); 1051cb0ef41Sopenharmony_ci } 1061cb0ef41Sopenharmony_ci void SetExternalFileId(int file_id) { 1071cb0ef41Sopenharmony_ci DCHECK(IsExternal()); 1081cb0ef41Sopenharmony_ci DCHECK(file_id <= ExternalFileIdField::kMax - 1); 1091cb0ef41Sopenharmony_ci value_ = ExternalFileIdField::update(value_, file_id); 1101cb0ef41Sopenharmony_ci } 1111cb0ef41Sopenharmony_ci 1121cb0ef41Sopenharmony_ci void SetScriptOffset(int script_offset) { 1131cb0ef41Sopenharmony_ci DCHECK(IsJavaScript()); 1141cb0ef41Sopenharmony_ci DCHECK(script_offset <= ScriptOffsetField::kMax - 2); 1151cb0ef41Sopenharmony_ci DCHECK_GE(script_offset, kNoSourcePosition); 1161cb0ef41Sopenharmony_ci value_ = ScriptOffsetField::update(value_, script_offset + 1); 1171cb0ef41Sopenharmony_ci } 1181cb0ef41Sopenharmony_ci void SetInliningId(int inlining_id) { 1191cb0ef41Sopenharmony_ci DCHECK(inlining_id <= InliningIdField::kMax - 2); 1201cb0ef41Sopenharmony_ci DCHECK_GE(inlining_id, kNotInlined); 1211cb0ef41Sopenharmony_ci value_ = InliningIdField::update(value_, inlining_id + 1); 1221cb0ef41Sopenharmony_ci } 1231cb0ef41Sopenharmony_ci 1241cb0ef41Sopenharmony_ci static const int kNotInlined = -1; 1251cb0ef41Sopenharmony_ci STATIC_ASSERT(kNoSourcePosition == -1); 1261cb0ef41Sopenharmony_ci 1271cb0ef41Sopenharmony_ci int64_t raw() const { return static_cast<int64_t>(value_); } 1281cb0ef41Sopenharmony_ci static SourcePosition FromRaw(int64_t raw) { 1291cb0ef41Sopenharmony_ci SourcePosition position = Unknown(); 1301cb0ef41Sopenharmony_ci DCHECK_GE(raw, 0); 1311cb0ef41Sopenharmony_ci position.value_ = static_cast<uint64_t>(raw); 1321cb0ef41Sopenharmony_ci return position; 1331cb0ef41Sopenharmony_ci } 1341cb0ef41Sopenharmony_ci 1351cb0ef41Sopenharmony_ci private: 1361cb0ef41Sopenharmony_ci // Used by SourcePosition::External(line, file_id). 1371cb0ef41Sopenharmony_ci SourcePosition(int line, int file_id, int inlining_id) : value_(0) { 1381cb0ef41Sopenharmony_ci SetIsExternal(true); 1391cb0ef41Sopenharmony_ci SetExternalLine(line); 1401cb0ef41Sopenharmony_ci SetExternalFileId(file_id); 1411cb0ef41Sopenharmony_ci SetInliningId(inlining_id); 1421cb0ef41Sopenharmony_ci } 1431cb0ef41Sopenharmony_ci 1441cb0ef41Sopenharmony_ci void Print(std::ostream& out, SharedFunctionInfo function) const; 1451cb0ef41Sopenharmony_ci 1461cb0ef41Sopenharmony_ci using IsExternalField = base::BitField64<bool, 0, 1>; 1471cb0ef41Sopenharmony_ci 1481cb0ef41Sopenharmony_ci // The two below are only used if IsExternal() is true. 1491cb0ef41Sopenharmony_ci using ExternalLineField = base::BitField64<int, 1, 20>; 1501cb0ef41Sopenharmony_ci using ExternalFileIdField = base::BitField64<int, 21, 10>; 1511cb0ef41Sopenharmony_ci 1521cb0ef41Sopenharmony_ci // ScriptOffsetField is only used if IsExternal() is false. 1531cb0ef41Sopenharmony_ci using ScriptOffsetField = base::BitField64<int, 1, 30>; 1541cb0ef41Sopenharmony_ci 1551cb0ef41Sopenharmony_ci // InliningId is in the high bits for better compression in 1561cb0ef41Sopenharmony_ci // SourcePositionTable. 1571cb0ef41Sopenharmony_ci using InliningIdField = base::BitField64<int, 31, 16>; 1581cb0ef41Sopenharmony_ci 1591cb0ef41Sopenharmony_ci // Leaving the highest bit untouched to allow for signed conversion. 1601cb0ef41Sopenharmony_ci uint64_t value_; 1611cb0ef41Sopenharmony_ci}; 1621cb0ef41Sopenharmony_ci 1631cb0ef41Sopenharmony_ciinline bool operator==(const SourcePosition& lhs, const SourcePosition& rhs) { 1641cb0ef41Sopenharmony_ci return lhs.raw() == rhs.raw(); 1651cb0ef41Sopenharmony_ci} 1661cb0ef41Sopenharmony_ci 1671cb0ef41Sopenharmony_ciinline bool operator!=(const SourcePosition& lhs, const SourcePosition& rhs) { 1681cb0ef41Sopenharmony_ci return !(lhs == rhs); 1691cb0ef41Sopenharmony_ci} 1701cb0ef41Sopenharmony_ci 1711cb0ef41Sopenharmony_cistruct InliningPosition { 1721cb0ef41Sopenharmony_ci // position of the inlined call 1731cb0ef41Sopenharmony_ci SourcePosition position = SourcePosition::Unknown(); 1741cb0ef41Sopenharmony_ci 1751cb0ef41Sopenharmony_ci // references position in DeoptimizationData::literals() 1761cb0ef41Sopenharmony_ci int inlined_function_id; 1771cb0ef41Sopenharmony_ci}; 1781cb0ef41Sopenharmony_ci 1791cb0ef41Sopenharmony_cistruct SourcePositionInfo { 1801cb0ef41Sopenharmony_ci SourcePositionInfo(SourcePosition pos, Handle<SharedFunctionInfo> f); 1811cb0ef41Sopenharmony_ci 1821cb0ef41Sopenharmony_ci SourcePosition position; 1831cb0ef41Sopenharmony_ci Handle<SharedFunctionInfo> shared; 1841cb0ef41Sopenharmony_ci Handle<Script> script; 1851cb0ef41Sopenharmony_ci int line = -1; 1861cb0ef41Sopenharmony_ci int column = -1; 1871cb0ef41Sopenharmony_ci}; 1881cb0ef41Sopenharmony_ci 1891cb0ef41Sopenharmony_cistd::ostream& operator<<(std::ostream& out, const SourcePosition& pos); 1901cb0ef41Sopenharmony_ci 1911cb0ef41Sopenharmony_cistd::ostream& operator<<(std::ostream& out, const SourcePositionInfo& pos); 1921cb0ef41Sopenharmony_cistd::ostream& operator<<(std::ostream& out, 1931cb0ef41Sopenharmony_ci const std::vector<SourcePositionInfo>& stack); 1941cb0ef41Sopenharmony_ci 1951cb0ef41Sopenharmony_ci} // namespace internal 1961cb0ef41Sopenharmony_ci} // namespace v8 1971cb0ef41Sopenharmony_ci 1981cb0ef41Sopenharmony_ci#endif // V8_CODEGEN_SOURCE_POSITION_H_ 199