11cb0ef41Sopenharmony_ci// Copyright 2018 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_CONSTANT_POOL_H_
61cb0ef41Sopenharmony_ci#define V8_CODEGEN_CONSTANT_POOL_H_
71cb0ef41Sopenharmony_ci
81cb0ef41Sopenharmony_ci#include <map>
91cb0ef41Sopenharmony_ci
101cb0ef41Sopenharmony_ci#include "src/base/numbers/double.h"
111cb0ef41Sopenharmony_ci#include "src/codegen/label.h"
121cb0ef41Sopenharmony_ci#include "src/codegen/reloc-info.h"
131cb0ef41Sopenharmony_ci#include "src/common/globals.h"
141cb0ef41Sopenharmony_ci
151cb0ef41Sopenharmony_cinamespace v8 {
161cb0ef41Sopenharmony_cinamespace internal {
171cb0ef41Sopenharmony_ci
181cb0ef41Sopenharmony_ciclass Instruction;
191cb0ef41Sopenharmony_ci
201cb0ef41Sopenharmony_ci// -----------------------------------------------------------------------------
211cb0ef41Sopenharmony_ci// Constant pool support
221cb0ef41Sopenharmony_ci
231cb0ef41Sopenharmony_ciclass ConstantPoolEntry {
241cb0ef41Sopenharmony_ci public:
251cb0ef41Sopenharmony_ci  ConstantPoolEntry() = default;
261cb0ef41Sopenharmony_ci  ConstantPoolEntry(int position, intptr_t value, bool sharing_ok,
271cb0ef41Sopenharmony_ci                    RelocInfo::Mode rmode = RelocInfo::NO_INFO)
281cb0ef41Sopenharmony_ci      : position_(position),
291cb0ef41Sopenharmony_ci        merged_index_(sharing_ok ? SHARING_ALLOWED : SHARING_PROHIBITED),
301cb0ef41Sopenharmony_ci        value_(value),
311cb0ef41Sopenharmony_ci        rmode_(rmode) {}
321cb0ef41Sopenharmony_ci  ConstantPoolEntry(int position, base::Double value,
331cb0ef41Sopenharmony_ci                    RelocInfo::Mode rmode = RelocInfo::NO_INFO)
341cb0ef41Sopenharmony_ci      : position_(position),
351cb0ef41Sopenharmony_ci        merged_index_(SHARING_ALLOWED),
361cb0ef41Sopenharmony_ci        value64_(value.AsUint64()),
371cb0ef41Sopenharmony_ci        rmode_(rmode) {}
381cb0ef41Sopenharmony_ci
391cb0ef41Sopenharmony_ci  int position() const { return position_; }
401cb0ef41Sopenharmony_ci  bool sharing_ok() const { return merged_index_ != SHARING_PROHIBITED; }
411cb0ef41Sopenharmony_ci  bool is_merged() const { return merged_index_ >= 0; }
421cb0ef41Sopenharmony_ci  int merged_index() const {
431cb0ef41Sopenharmony_ci    DCHECK(is_merged());
441cb0ef41Sopenharmony_ci    return merged_index_;
451cb0ef41Sopenharmony_ci  }
461cb0ef41Sopenharmony_ci  void set_merged_index(int index) {
471cb0ef41Sopenharmony_ci    DCHECK(sharing_ok());
481cb0ef41Sopenharmony_ci    merged_index_ = index;
491cb0ef41Sopenharmony_ci    DCHECK(is_merged());
501cb0ef41Sopenharmony_ci  }
511cb0ef41Sopenharmony_ci  int offset() const {
521cb0ef41Sopenharmony_ci    DCHECK_GE(merged_index_, 0);
531cb0ef41Sopenharmony_ci    return merged_index_;
541cb0ef41Sopenharmony_ci  }
551cb0ef41Sopenharmony_ci  void set_offset(int offset) {
561cb0ef41Sopenharmony_ci    DCHECK_GE(offset, 0);
571cb0ef41Sopenharmony_ci    merged_index_ = offset;
581cb0ef41Sopenharmony_ci  }
591cb0ef41Sopenharmony_ci  intptr_t value() const { return value_; }
601cb0ef41Sopenharmony_ci  uint64_t value64() const { return value64_; }
611cb0ef41Sopenharmony_ci  RelocInfo::Mode rmode() const { return rmode_; }
621cb0ef41Sopenharmony_ci
631cb0ef41Sopenharmony_ci  enum Type { INTPTR, DOUBLE, NUMBER_OF_TYPES };
641cb0ef41Sopenharmony_ci
651cb0ef41Sopenharmony_ci  static int size(Type type) {
661cb0ef41Sopenharmony_ci    return (type == INTPTR) ? kSystemPointerSize : kDoubleSize;
671cb0ef41Sopenharmony_ci  }
681cb0ef41Sopenharmony_ci
691cb0ef41Sopenharmony_ci  enum Access { REGULAR, OVERFLOWED };
701cb0ef41Sopenharmony_ci
711cb0ef41Sopenharmony_ci private:
721cb0ef41Sopenharmony_ci  int position_;
731cb0ef41Sopenharmony_ci  int merged_index_;
741cb0ef41Sopenharmony_ci  union {
751cb0ef41Sopenharmony_ci    intptr_t value_;
761cb0ef41Sopenharmony_ci    uint64_t value64_;
771cb0ef41Sopenharmony_ci  };
781cb0ef41Sopenharmony_ci  // TODO(leszeks): The way we use this, it could probably be packed into
791cb0ef41Sopenharmony_ci  // merged_index_ if size is a concern.
801cb0ef41Sopenharmony_ci  RelocInfo::Mode rmode_;
811cb0ef41Sopenharmony_ci  enum { SHARING_PROHIBITED = -2, SHARING_ALLOWED = -1 };
821cb0ef41Sopenharmony_ci};
831cb0ef41Sopenharmony_ci
841cb0ef41Sopenharmony_ci#if defined(V8_TARGET_ARCH_PPC) || defined(V8_TARGET_ARCH_PPC64)
851cb0ef41Sopenharmony_ci
861cb0ef41Sopenharmony_ci// -----------------------------------------------------------------------------
871cb0ef41Sopenharmony_ci// Embedded constant pool support
881cb0ef41Sopenharmony_ci
891cb0ef41Sopenharmony_ciclass ConstantPoolBuilder {
901cb0ef41Sopenharmony_ci public:
911cb0ef41Sopenharmony_ci  ConstantPoolBuilder(int ptr_reach_bits, int double_reach_bits);
921cb0ef41Sopenharmony_ci
931cb0ef41Sopenharmony_ci#ifdef DEBUG
941cb0ef41Sopenharmony_ci  ~ConstantPoolBuilder() {
951cb0ef41Sopenharmony_ci    // Unused labels to prevent DCHECK failures.
961cb0ef41Sopenharmony_ci    emitted_label_.Unuse();
971cb0ef41Sopenharmony_ci    emitted_label_.UnuseNear();
981cb0ef41Sopenharmony_ci  }
991cb0ef41Sopenharmony_ci#endif
1001cb0ef41Sopenharmony_ci
1011cb0ef41Sopenharmony_ci  // Add pointer-sized constant to the embedded constant pool
1021cb0ef41Sopenharmony_ci  ConstantPoolEntry::Access AddEntry(int position, intptr_t value,
1031cb0ef41Sopenharmony_ci                                     bool sharing_ok) {
1041cb0ef41Sopenharmony_ci    ConstantPoolEntry entry(position, value, sharing_ok);
1051cb0ef41Sopenharmony_ci    return AddEntry(&entry, ConstantPoolEntry::INTPTR);
1061cb0ef41Sopenharmony_ci  }
1071cb0ef41Sopenharmony_ci
1081cb0ef41Sopenharmony_ci  // Add double constant to the embedded constant pool
1091cb0ef41Sopenharmony_ci  ConstantPoolEntry::Access AddEntry(int position, base::Double value) {
1101cb0ef41Sopenharmony_ci    ConstantPoolEntry entry(position, value);
1111cb0ef41Sopenharmony_ci    return AddEntry(&entry, ConstantPoolEntry::DOUBLE);
1121cb0ef41Sopenharmony_ci  }
1131cb0ef41Sopenharmony_ci
1141cb0ef41Sopenharmony_ci  // Add double constant to the embedded constant pool
1151cb0ef41Sopenharmony_ci  ConstantPoolEntry::Access AddEntry(int position, double value) {
1161cb0ef41Sopenharmony_ci    return AddEntry(position, base::Double(value));
1171cb0ef41Sopenharmony_ci  }
1181cb0ef41Sopenharmony_ci
1191cb0ef41Sopenharmony_ci  // Previews the access type required for the next new entry to be added.
1201cb0ef41Sopenharmony_ci  ConstantPoolEntry::Access NextAccess(ConstantPoolEntry::Type type) const;
1211cb0ef41Sopenharmony_ci
1221cb0ef41Sopenharmony_ci  bool IsEmpty() {
1231cb0ef41Sopenharmony_ci    return info_[ConstantPoolEntry::INTPTR].entries.empty() &&
1241cb0ef41Sopenharmony_ci           info_[ConstantPoolEntry::INTPTR].shared_entries.empty() &&
1251cb0ef41Sopenharmony_ci           info_[ConstantPoolEntry::DOUBLE].entries.empty() &&
1261cb0ef41Sopenharmony_ci           info_[ConstantPoolEntry::DOUBLE].shared_entries.empty();
1271cb0ef41Sopenharmony_ci  }
1281cb0ef41Sopenharmony_ci
1291cb0ef41Sopenharmony_ci  // Emit the constant pool.  Invoke only after all entries have been
1301cb0ef41Sopenharmony_ci  // added and all instructions have been emitted.
1311cb0ef41Sopenharmony_ci  // Returns position of the emitted pool (zero implies no constant pool).
1321cb0ef41Sopenharmony_ci  int Emit(Assembler* assm);
1331cb0ef41Sopenharmony_ci
1341cb0ef41Sopenharmony_ci  // Returns the label associated with the start of the constant pool.
1351cb0ef41Sopenharmony_ci  // Linking to this label in the function prologue may provide an
1361cb0ef41Sopenharmony_ci  // efficient means of constant pool pointer register initialization
1371cb0ef41Sopenharmony_ci  // on some architectures.
1381cb0ef41Sopenharmony_ci  inline Label* EmittedPosition() { return &emitted_label_; }
1391cb0ef41Sopenharmony_ci
1401cb0ef41Sopenharmony_ci private:
1411cb0ef41Sopenharmony_ci  ConstantPoolEntry::Access AddEntry(ConstantPoolEntry* entry,
1421cb0ef41Sopenharmony_ci                                     ConstantPoolEntry::Type type);
1431cb0ef41Sopenharmony_ci  void EmitSharedEntries(Assembler* assm, ConstantPoolEntry::Type type);
1441cb0ef41Sopenharmony_ci  void EmitGroup(Assembler* assm, ConstantPoolEntry::Access access,
1451cb0ef41Sopenharmony_ci                 ConstantPoolEntry::Type type);
1461cb0ef41Sopenharmony_ci
1471cb0ef41Sopenharmony_ci  struct PerTypeEntryInfo {
1481cb0ef41Sopenharmony_ci    PerTypeEntryInfo() : regular_count(0), overflow_start(-1) {}
1491cb0ef41Sopenharmony_ci    bool overflow() const {
1501cb0ef41Sopenharmony_ci      return (overflow_start >= 0 &&
1511cb0ef41Sopenharmony_ci              overflow_start < static_cast<int>(entries.size()));
1521cb0ef41Sopenharmony_ci    }
1531cb0ef41Sopenharmony_ci    int regular_reach_bits;
1541cb0ef41Sopenharmony_ci    int regular_count;
1551cb0ef41Sopenharmony_ci    int overflow_start;
1561cb0ef41Sopenharmony_ci    std::vector<ConstantPoolEntry> entries;
1571cb0ef41Sopenharmony_ci    std::vector<ConstantPoolEntry> shared_entries;
1581cb0ef41Sopenharmony_ci  };
1591cb0ef41Sopenharmony_ci
1601cb0ef41Sopenharmony_ci  Label emitted_label_;  // Records pc_offset of emitted pool
1611cb0ef41Sopenharmony_ci  PerTypeEntryInfo info_[ConstantPoolEntry::NUMBER_OF_TYPES];
1621cb0ef41Sopenharmony_ci};
1631cb0ef41Sopenharmony_ci
1641cb0ef41Sopenharmony_ci#endif  // defined(V8_TARGET_ARCH_PPC) || defined(V8_TARGET_ARCH_PPC64)
1651cb0ef41Sopenharmony_ci
1661cb0ef41Sopenharmony_ci#if defined(V8_TARGET_ARCH_ARM64) || defined(V8_TARGET_ARCH_RISCV64)
1671cb0ef41Sopenharmony_ci
1681cb0ef41Sopenharmony_ciclass ConstantPoolKey {
1691cb0ef41Sopenharmony_ci public:
1701cb0ef41Sopenharmony_ci  explicit ConstantPoolKey(uint64_t value,
1711cb0ef41Sopenharmony_ci                           RelocInfo::Mode rmode = RelocInfo::NO_INFO)
1721cb0ef41Sopenharmony_ci      : is_value32_(false), value64_(value), rmode_(rmode) {}
1731cb0ef41Sopenharmony_ci
1741cb0ef41Sopenharmony_ci  explicit ConstantPoolKey(uint32_t value,
1751cb0ef41Sopenharmony_ci                           RelocInfo::Mode rmode = RelocInfo::NO_INFO)
1761cb0ef41Sopenharmony_ci      : is_value32_(true), value32_(value), rmode_(rmode) {}
1771cb0ef41Sopenharmony_ci
1781cb0ef41Sopenharmony_ci  uint64_t value64() const {
1791cb0ef41Sopenharmony_ci    CHECK(!is_value32_);
1801cb0ef41Sopenharmony_ci    return value64_;
1811cb0ef41Sopenharmony_ci  }
1821cb0ef41Sopenharmony_ci  uint32_t value32() const {
1831cb0ef41Sopenharmony_ci    CHECK(is_value32_);
1841cb0ef41Sopenharmony_ci    return value32_;
1851cb0ef41Sopenharmony_ci  }
1861cb0ef41Sopenharmony_ci
1871cb0ef41Sopenharmony_ci  bool is_value32() const { return is_value32_; }
1881cb0ef41Sopenharmony_ci  RelocInfo::Mode rmode() const { return rmode_; }
1891cb0ef41Sopenharmony_ci
1901cb0ef41Sopenharmony_ci  bool AllowsDeduplication() const {
1911cb0ef41Sopenharmony_ci    DCHECK(rmode_ != RelocInfo::CONST_POOL &&
1921cb0ef41Sopenharmony_ci           rmode_ != RelocInfo::VENEER_POOL &&
1931cb0ef41Sopenharmony_ci           rmode_ != RelocInfo::DEOPT_SCRIPT_OFFSET &&
1941cb0ef41Sopenharmony_ci           rmode_ != RelocInfo::DEOPT_INLINING_ID &&
1951cb0ef41Sopenharmony_ci           rmode_ != RelocInfo::DEOPT_REASON && rmode_ != RelocInfo::DEOPT_ID &&
1961cb0ef41Sopenharmony_ci           rmode_ != RelocInfo::DEOPT_NODE_ID);
1971cb0ef41Sopenharmony_ci    // CODE_TARGETs can be shared because they aren't patched anymore,
1981cb0ef41Sopenharmony_ci    // and we make sure we emit only one reloc info for them (thus delta
1991cb0ef41Sopenharmony_ci    // patching) will apply the delta only once. At the moment, we do not dedup
2001cb0ef41Sopenharmony_ci    // code targets if they are wrapped in a heap object request (value == 0).
2011cb0ef41Sopenharmony_ci    bool is_sharable_code_target =
2021cb0ef41Sopenharmony_ci        rmode_ == RelocInfo::CODE_TARGET &&
2031cb0ef41Sopenharmony_ci        (is_value32() ? (value32() != 0) : (value64() != 0));
2041cb0ef41Sopenharmony_ci    bool is_sharable_embedded_object = RelocInfo::IsEmbeddedObjectMode(rmode_);
2051cb0ef41Sopenharmony_ci    return RelocInfo::IsShareableRelocMode(rmode_) || is_sharable_code_target ||
2061cb0ef41Sopenharmony_ci           is_sharable_embedded_object;
2071cb0ef41Sopenharmony_ci  }
2081cb0ef41Sopenharmony_ci
2091cb0ef41Sopenharmony_ci private:
2101cb0ef41Sopenharmony_ci  bool is_value32_;
2111cb0ef41Sopenharmony_ci  union {
2121cb0ef41Sopenharmony_ci    uint64_t value64_;
2131cb0ef41Sopenharmony_ci    uint32_t value32_;
2141cb0ef41Sopenharmony_ci  };
2151cb0ef41Sopenharmony_ci  RelocInfo::Mode rmode_;
2161cb0ef41Sopenharmony_ci};
2171cb0ef41Sopenharmony_ci
2181cb0ef41Sopenharmony_ci// Order for pool entries. 64bit entries go first.
2191cb0ef41Sopenharmony_ciinline bool operator<(const ConstantPoolKey& a, const ConstantPoolKey& b) {
2201cb0ef41Sopenharmony_ci  if (a.is_value32() < b.is_value32()) return true;
2211cb0ef41Sopenharmony_ci  if (a.is_value32() > b.is_value32()) return false;
2221cb0ef41Sopenharmony_ci  if (a.rmode() < b.rmode()) return true;
2231cb0ef41Sopenharmony_ci  if (a.rmode() > b.rmode()) return false;
2241cb0ef41Sopenharmony_ci  if (a.is_value32()) return a.value32() < b.value32();
2251cb0ef41Sopenharmony_ci  return a.value64() < b.value64();
2261cb0ef41Sopenharmony_ci}
2271cb0ef41Sopenharmony_ci
2281cb0ef41Sopenharmony_ciinline bool operator==(const ConstantPoolKey& a, const ConstantPoolKey& b) {
2291cb0ef41Sopenharmony_ci  if (a.rmode() != b.rmode() || a.is_value32() != b.is_value32()) {
2301cb0ef41Sopenharmony_ci    return false;
2311cb0ef41Sopenharmony_ci  }
2321cb0ef41Sopenharmony_ci  if (a.is_value32()) return a.value32() == b.value32();
2331cb0ef41Sopenharmony_ci  return a.value64() == b.value64();
2341cb0ef41Sopenharmony_ci}
2351cb0ef41Sopenharmony_ci
2361cb0ef41Sopenharmony_ci// Constant pool generation
2371cb0ef41Sopenharmony_cienum class Jump { kOmitted, kRequired };
2381cb0ef41Sopenharmony_cienum class Emission { kIfNeeded, kForced };
2391cb0ef41Sopenharmony_cienum class Alignment { kOmitted, kRequired };
2401cb0ef41Sopenharmony_cienum class RelocInfoStatus { kMustRecord, kMustOmitForDuplicate };
2411cb0ef41Sopenharmony_cienum class PoolEmissionCheck { kSkip };
2421cb0ef41Sopenharmony_ci
2431cb0ef41Sopenharmony_ci// Pools are emitted in the instruction stream, preferably after unconditional
2441cb0ef41Sopenharmony_ci// jumps or after returns from functions (in dead code locations).
2451cb0ef41Sopenharmony_ci// If a long code sequence does not contain unconditional jumps, it is
2461cb0ef41Sopenharmony_ci// necessary to emit the constant pool before the pool gets too far from the
2471cb0ef41Sopenharmony_ci// location it is accessed from. In this case, we emit a jump over the emitted
2481cb0ef41Sopenharmony_ci// constant pool.
2491cb0ef41Sopenharmony_ci// Constants in the pool may be addresses of functions that gets relocated;
2501cb0ef41Sopenharmony_ci// if so, a relocation info entry is associated to the constant pool entry.
2511cb0ef41Sopenharmony_ciclass ConstantPool {
2521cb0ef41Sopenharmony_ci public:
2531cb0ef41Sopenharmony_ci  explicit ConstantPool(Assembler* assm);
2541cb0ef41Sopenharmony_ci  ~ConstantPool();
2551cb0ef41Sopenharmony_ci
2561cb0ef41Sopenharmony_ci  // Returns true when we need to write RelocInfo and false when we do not.
2571cb0ef41Sopenharmony_ci  RelocInfoStatus RecordEntry(uint32_t data, RelocInfo::Mode rmode);
2581cb0ef41Sopenharmony_ci  RelocInfoStatus RecordEntry(uint64_t data, RelocInfo::Mode rmode);
2591cb0ef41Sopenharmony_ci
2601cb0ef41Sopenharmony_ci  size_t Entry32Count() const { return entry32_count_; }
2611cb0ef41Sopenharmony_ci  size_t Entry64Count() const { return entry64_count_; }
2621cb0ef41Sopenharmony_ci  bool IsEmpty() const { return entries_.empty(); }
2631cb0ef41Sopenharmony_ci  // Check if pool will be out of range at {pc_offset}.
2641cb0ef41Sopenharmony_ci  bool IsInImmRangeIfEmittedAt(int pc_offset);
2651cb0ef41Sopenharmony_ci  // Size in bytes of the constant pool. Depending on parameters, the size will
2661cb0ef41Sopenharmony_ci  // include the branch over the pool and alignment padding.
2671cb0ef41Sopenharmony_ci  int ComputeSize(Jump require_jump, Alignment require_alignment) const;
2681cb0ef41Sopenharmony_ci
2691cb0ef41Sopenharmony_ci  // Emit the pool at the current pc with a branch over the pool if requested.
2701cb0ef41Sopenharmony_ci  void EmitAndClear(Jump require);
2711cb0ef41Sopenharmony_ci  bool ShouldEmitNow(Jump require_jump, size_t margin = 0) const;
2721cb0ef41Sopenharmony_ci  V8_EXPORT_PRIVATE void Check(Emission force_emission, Jump require_jump,
2731cb0ef41Sopenharmony_ci                               size_t margin = 0);
2741cb0ef41Sopenharmony_ci
2751cb0ef41Sopenharmony_ci  V8_EXPORT_PRIVATE void MaybeCheck();
2761cb0ef41Sopenharmony_ci  void Clear();
2771cb0ef41Sopenharmony_ci
2781cb0ef41Sopenharmony_ci  // Constant pool emisssion can be blocked temporarily.
2791cb0ef41Sopenharmony_ci  bool IsBlocked() const;
2801cb0ef41Sopenharmony_ci
2811cb0ef41Sopenharmony_ci  // Repeated checking whether the constant pool should be emitted is expensive;
2821cb0ef41Sopenharmony_ci  // only check once a number of instructions have been generated.
2831cb0ef41Sopenharmony_ci  void SetNextCheckIn(size_t instructions);
2841cb0ef41Sopenharmony_ci
2851cb0ef41Sopenharmony_ci  // Class for scoping postponing the constant pool generation.
2861cb0ef41Sopenharmony_ci  class V8_EXPORT_PRIVATE V8_NODISCARD BlockScope {
2871cb0ef41Sopenharmony_ci   public:
2881cb0ef41Sopenharmony_ci    // BlockScope immediatelly emits the pool if necessary to ensure that
2891cb0ef41Sopenharmony_ci    // during the block scope at least {margin} bytes can be emitted without
2901cb0ef41Sopenharmony_ci    // pool emission becomming necessary.
2911cb0ef41Sopenharmony_ci    explicit BlockScope(Assembler* pool, size_t margin = 0);
2921cb0ef41Sopenharmony_ci    BlockScope(Assembler* pool, PoolEmissionCheck);
2931cb0ef41Sopenharmony_ci    ~BlockScope();
2941cb0ef41Sopenharmony_ci
2951cb0ef41Sopenharmony_ci   private:
2961cb0ef41Sopenharmony_ci    ConstantPool* pool_;
2971cb0ef41Sopenharmony_ci    DISALLOW_IMPLICIT_CONSTRUCTORS(BlockScope);
2981cb0ef41Sopenharmony_ci  };
2991cb0ef41Sopenharmony_ci
3001cb0ef41Sopenharmony_ci  // Hard limit to the const pool which must not be exceeded.
3011cb0ef41Sopenharmony_ci  static const size_t kMaxDistToPool32;
3021cb0ef41Sopenharmony_ci  static const size_t kMaxDistToPool64;
3031cb0ef41Sopenharmony_ci  // Approximate distance where the pool should be emitted.
3041cb0ef41Sopenharmony_ci  static const size_t kApproxDistToPool32;
3051cb0ef41Sopenharmony_ci  V8_EXPORT_PRIVATE static const size_t kApproxDistToPool64;
3061cb0ef41Sopenharmony_ci  // Approximate distance where the pool may be emitted if
3071cb0ef41Sopenharmony_ci  // no jump is required (due to a recent unconditional jump).
3081cb0ef41Sopenharmony_ci  static const size_t kOpportunityDistToPool32;
3091cb0ef41Sopenharmony_ci  static const size_t kOpportunityDistToPool64;
3101cb0ef41Sopenharmony_ci  // PC distance between constant pool checks.
3111cb0ef41Sopenharmony_ci  V8_EXPORT_PRIVATE static const size_t kCheckInterval;
3121cb0ef41Sopenharmony_ci  // Number of entries in the pool which trigger a check.
3131cb0ef41Sopenharmony_ci  static const size_t kApproxMaxEntryCount;
3141cb0ef41Sopenharmony_ci
3151cb0ef41Sopenharmony_ci private:
3161cb0ef41Sopenharmony_ci  void StartBlock();
3171cb0ef41Sopenharmony_ci  void EndBlock();
3181cb0ef41Sopenharmony_ci
3191cb0ef41Sopenharmony_ci  void EmitEntries();
3201cb0ef41Sopenharmony_ci  void EmitPrologue(Alignment require_alignment);
3211cb0ef41Sopenharmony_ci  int PrologueSize(Jump require_jump) const;
3221cb0ef41Sopenharmony_ci  RelocInfoStatus RecordKey(ConstantPoolKey key, int offset);
3231cb0ef41Sopenharmony_ci  RelocInfoStatus GetRelocInfoStatusFor(const ConstantPoolKey& key);
3241cb0ef41Sopenharmony_ci  void Emit(const ConstantPoolKey& key);
3251cb0ef41Sopenharmony_ci  void SetLoadOffsetToConstPoolEntry(int load_offset, Instruction* entry_offset,
3261cb0ef41Sopenharmony_ci                                     const ConstantPoolKey& key);
3271cb0ef41Sopenharmony_ci  Alignment IsAlignmentRequiredIfEmittedAt(Jump require_jump,
3281cb0ef41Sopenharmony_ci                                           int pc_offset) const;
3291cb0ef41Sopenharmony_ci
3301cb0ef41Sopenharmony_ci  Assembler* assm_;
3311cb0ef41Sopenharmony_ci  // Keep track of the first instruction requiring a constant pool entry
3321cb0ef41Sopenharmony_ci  // since the previous constant pool was emitted.
3331cb0ef41Sopenharmony_ci  int first_use_32_ = -1;
3341cb0ef41Sopenharmony_ci  int first_use_64_ = -1;
3351cb0ef41Sopenharmony_ci  // We sort not according to insertion order, but since we do not insert
3361cb0ef41Sopenharmony_ci  // addresses (for heap objects we insert an index which is created in
3371cb0ef41Sopenharmony_ci  // increasing order), the order is deterministic. We map each entry to the
3381cb0ef41Sopenharmony_ci  // pc offset of the load. We use a multimap because we need to record the
3391cb0ef41Sopenharmony_ci  // pc offset of each load of the same constant so that the immediate of the
3401cb0ef41Sopenharmony_ci  // loads can be back-patched when the pool is emitted.
3411cb0ef41Sopenharmony_ci  std::multimap<ConstantPoolKey, int> entries_;
3421cb0ef41Sopenharmony_ci  size_t entry32_count_ = 0;
3431cb0ef41Sopenharmony_ci  size_t entry64_count_ = 0;
3441cb0ef41Sopenharmony_ci  int next_check_ = 0;
3451cb0ef41Sopenharmony_ci  int blocked_nesting_ = 0;
3461cb0ef41Sopenharmony_ci};
3471cb0ef41Sopenharmony_ci
3481cb0ef41Sopenharmony_ci#endif  // defined(V8_TARGET_ARCH_ARM64)
3491cb0ef41Sopenharmony_ci
3501cb0ef41Sopenharmony_ci}  // namespace internal
3511cb0ef41Sopenharmony_ci}  // namespace v8
3521cb0ef41Sopenharmony_ci
3531cb0ef41Sopenharmony_ci#endif  // V8_CODEGEN_CONSTANT_POOL_H_
354