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