5#ifndef V8_SANDBOX_EXTERNAL_POINTER_TABLE_H_
6#define V8_SANDBOX_EXTERNAL_POINTER_TABLE_H_
17#ifdef V8_COMPRESS_POINTERS
24class ReadOnlyArtifacts;
40struct ExternalPointerTableEntry {
41 enum class EvacuateMarkMode { kTransferMark, kLeaveUnmarked, kClearMark };
45 inline void MakeExternalPointerEntry(Address value, ExternalPointerTag tag,
52 inline Address GetExternalPointer(ExternalPointerTagRange tag_range)
const;
56 inline void SetExternalPointer(Address value, ExternalPointerTag tag);
59 inline bool HasExternalPointer(ExternalPointerTagRange tag_range)
const;
65 inline Address ExchangeExternalPointer(Address value, ExternalPointerTag tag);
73 inline Address ExtractManagedResourceOrNull()
const;
77 inline void MakeZappedEntry();
81 inline void MakeFreelistEntry(uint32_t next_entry_index);
87 inline uint32_t GetNextFreelistEntryIndex()
const;
91 inline void MakeEvacuationEntry(Address handle_location);
94 inline bool HasEvacuationEntry()
const;
99 inline void Evacuate(ExternalPointerTableEntry& dest, EvacuateMarkMode mode);
104 static constexpr bool IsWriteProtected =
false;
107 friend class ExternalPointerTable;
114 Payload(Address pointer, ExternalPointerTag tag)
115 : encoded_word_(Tag(pointer, tag)) {}
117 static Address Tag(Address pointer, ExternalPointerTag tag) {
122 static bool CheckTag(Address content, ExternalPointerTagRange tag_range) {
125 if (ExternalPointerCanBeEmpty(tag_range) && !content) {
131 return tag_range.Contains(tag);
134 Address Untag(ExternalPointerTagRange tag_range)
const {
135 Address content = encoded_word_;
136 SBXCHECK(CheckTag(content, tag_range));
140 Address Untag(ExternalPointerTag tag)
const {
144 bool IsTaggedWithTagIn(ExternalPointerTagRange tag_range)
const {
145 return CheckTag(encoded_word_, tag_range);
148 bool IsTaggedWith(ExternalPointerTag tag)
const {
154 void ClearMarkBit() { encoded_word_ &= ~kExternalPointerMarkBit; }
156 bool HasMarkBitSet()
const {
160 uint32_t ExtractFreelistLink()
const {
161 return static_cast<uint32_t
>(encoded_word_);
170 bool ContainsFreelistLink()
const {
171 return IsTaggedWith(kExternalPointerFreeEntryTag);
174 bool ContainsEvacuationEntry()
const {
175 return IsTaggedWith(kExternalPointerEvacuationEntryTag);
178 Address ExtractEvacuationEntryHandleLocation()
const {
179 return Untag(kExternalPointerEvacuationEntryTag);
182 bool ContainsPointer()
const {
183 return !ContainsFreelistLink() && !ContainsEvacuationEntry();
187 return encoded_word_ == other.encoded_word_;
191 return encoded_word_ != other.encoded_word_;
198 inline Payload GetRawPayload() {
199 return payload_.load(std::memory_order_relaxed);
201 inline void SetRawPayload(Payload new_payload) {
202 return payload_.store(new_payload, std::memory_order_relaxed);
205 inline void MaybeUpdateRawPointerForLSan(Address value) {
206#if defined(LEAK_SANITIZER)
207 raw_pointer_for_lsan_ =
value;
214 std::atomic<Payload> payload_;
216#if defined(LEAK_SANITIZER)
234#if defined(LEAK_SANITIZER)
236static_assert(
sizeof(ExternalPointerTableEntry) == 16);
239static_assert(
sizeof(ExternalPointerTableEntry) == 8);
309 :
public CompactibleExternalEntityTable<
310 ExternalPointerTableEntry, kExternalPointerTableReservationSize> {
312 CompactibleExternalEntityTable<ExternalPointerTableEntry,
313 kExternalPointerTableReservationSize>;
315#if defined(LEAK_SANITIZER)
321 static_assert(kSupportsCompaction);
324 using EvacuateMarkMode = ExternalPointerTableEntry::EvacuateMarkMode;
326 ExternalPointerTable() =
default;
327 ExternalPointerTable(
const ExternalPointerTable&) =
delete;
328 ExternalPointerTable& operator=(
const ExternalPointerTable&) =
delete;
331 struct Space :
public Base::Space {
342 inline void NotifyExternalPointerFieldInvalidated(
343 Address field_address, ExternalPointerTagRange tag_range);
346 void AssertEmpty() {
CHECK(segments_.empty()); }
348 bool allocate_black() {
return allocate_black_; }
349 void set_allocate_black(
bool allocate_black) {
350 allocate_black_ = allocate_black;
354 bool allocate_black_ =
false;
358 void SetUpFromReadOnlyArtifacts(Space* read_only_space,
359 const ReadOnlyArtifacts* artifacts);
364 inline Address Get(ExternalPointerHandle handle,
365 ExternalPointerTagRange tag_range)
const;
370 inline void Set(ExternalPointerHandle handle, Address value,
371 ExternalPointerTag tag);
379 ExternalPointerTag tag);
387 inline void Zap(ExternalPointerHandle handle);
394 Space* space, Address initial_value, ExternalPointerTag tag);
404 inline void Mark(Space* space, ExternalPointerHandle handle,
405 Address handle_location);
412 inline void Evacuate(Space* from_space, Space* to_space,
413 ExternalPointerHandle handle, Address handle_location,
414 EvacuateMarkMode mode);
432 uint32_t EvacuateAndSweepAndCompact(Space* to_space, Space* from_space,
434 uint32_t SweepAndCompact(Space* space, Counters* counters);
435 uint32_t Sweep(Space* space, Counters* counters);
437 inline bool Contains(Space* space, ExternalPointerHandle handle)
const;
454 class ManagedResource :
public Malloced {
458 inline void ZapExternalPointerTableEntry();
461 friend class ExternalPointerTable;
463 template <
typename IsolateT>
464 friend class Deserializer;
466 ExternalPointerTable* owning_table_ =
nullptr;
471 static inline bool IsValidHandle(ExternalPointerHandle handle);
472 static inline uint32_t HandleToIndex(ExternalPointerHandle handle);
475 inline void TakeOwnershipOfManagedResourceIfNecessary(
476 Address value, ExternalPointerHandle handle, ExternalPointerTag tag);
477 inline void FreeManagedResourceIfPresent(uint32_t entry_index);
479 void ResolveEvacuationEntryDuringSweeping(
480 uint32_t index, ExternalPointerHandle* handle_location,
481 uint32_t start_of_evacuation_area);
#define SBXCHECK(condition)
bool operator==(PointerWithPayload< PointerType, PayloadType, NumPayloadBits > lhs, PointerWithPayload< PointerType, PayloadType, NumPayloadBits > rhs)
V8_INLINE const Operation & Get(const Graph &graph, OpIndex index)
void Exchange(LiftoffAssembler *lasm, Register dst, Register lhs, Register rhs)
constexpr uint64_t kExternalPointerTagShift
bool operator!=(ExternalReference lhs, ExternalReference rhs)
constexpr uint64_t kExternalPointerPayloadMask
constexpr uint64_t kExternalPointerTagMask
TagRange< ExternalPointerTag > ExternalPointerTagRange
constexpr size_t kMaxExternalPointers
constexpr ExternalPointerHandle kNullExternalPointerHandle
uint32_t ExternalPointerHandle
constexpr uint64_t kExternalPointerMarkBit
#define DCHECK_LE(v1, v2)
#define V8_EXPORT_PRIVATE
std::unique_ptr< ValueMirror > value