v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
trusted-pointer-table.h
Go to the documentation of this file.
1// Copyright 2023 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef V8_SANDBOX_TRUSTED_POINTER_TABLE_H_
6#define V8_SANDBOX_TRUSTED_POINTER_TABLE_H_
7
8#include "include/v8config.h"
10#include "src/base/memory.h"
11#include "src/common/globals.h"
15
16#ifdef V8_ENABLE_SANDBOX
17
18namespace v8 {
19namespace internal {
20
21class Counters;
22class Isolate;
23class TrustedPointerPublishingScope;
24
30struct TrustedPointerTableEntry {
31 // Make this entry a "regular" entry, containing an absolute pointer to a
32 // TrustedObject.
33 inline void MakeTrustedPointerEntry(Address pointer, IndirectPointerTag tag,
34 bool mark_as_alive);
35
36 // Make this entry a freelist entry, containing the index of the next entry
37 // on the freelist.
38 inline void MakeFreelistEntry(uint32_t next_entry_index);
39
40 // Make this entry a zapped entry. Zapped entries contain invalid pointers.
41 inline void MakeZappedEntry();
42
43 // Retrieve the pointer stored in this entry. This entry must be tagged with
44 // the given tag, otherwise an inaccessible pointer will be returned.
45 // This entry must not be a freelist entry.
46 inline Address GetPointer(IndirectPointerTag tag) const;
47
48 // Store the given pointer in this entry while preserving the marking state.
49 // This entry must not be a freelist entry.
50 inline void SetPointer(Address pointer, IndirectPointerTag tag);
51
52 // Returns true if this entry contains a pointer with the given tag.
53 inline bool HasPointer(IndirectPointerTag tag) const;
54
55 // Overwrites the existing type tag. Be careful.
56 inline void OverwriteTag(IndirectPointerTag tag);
57
58 // Returns true if this entry is a freelist entry.
59 inline bool IsFreelistEntry() const;
60
61 // Get the index of the next entry on the freelist. This method may be
62 // called even when the entry is not a freelist entry. However, the result
63 // is only valid if this is a freelist entry. This behaviour is required
64 // for efficient entry allocation, see TryAllocateEntryFromFreelist.
65 inline uint32_t GetNextFreelistEntryIndex() const;
66
67 // Mark this entry as alive during garbage collection.
68 inline void Mark();
69
70 // Unmark this entry during sweeping.
71 inline void Unmark();
72
73 // Test whether this entry is currently marked as alive.
74 inline bool IsMarked() const;
75
76 static constexpr bool IsWriteProtected = false;
77
78 private:
79 friend class TrustedPointerTable;
80
81 // TrustedPointerTable entries consist of a single pointer-sized word
82 // containing a tag and marking bit together with the actual pointer.
83 struct TrustedPointerTaggingScheme {
84 using TagType = IndirectPointerTag;
85 static constexpr uint64_t kMarkBit = kTrustedPointerTableMarkBit;
86 static constexpr uint64_t kTagMask = kIndirectPointerTagMask;
87 static constexpr TagType kFreeEntryTag = kFreeTrustedPointerTableEntryTag;
88 static constexpr bool kSupportsEvacuation = false;
89 static constexpr bool kSupportsZapping = false;
90 };
91
92 struct Payload : TaggedPayload<TrustedPointerTaggingScheme> {
93 static Payload ForTrustedPointerEntry(Address pointer,
94 IndirectPointerTag tag) {
95 // We expect to only store references to (trusted) HeapObjects in the
96 // TrustedPointerTable, so the HeapObject tag bit must be set.
97 DCHECK_EQ(pointer & kHeapObjectTag, kHeapObjectTag);
98 DCHECK_EQ(pointer & kTrustedPointerTableMarkBit, 0);
99 DCHECK_EQ(pointer & kIndirectPointerTagMask, 0);
100 return Payload(pointer, tag);
101 }
102
103 static Payload ForFreelistEntry(uint32_t next_entry) {
104 return Payload(next_entry, kFreeTrustedPointerTableEntryTag);
105 }
106
107 static Payload ForZappedEntry() {
108 return Payload(0, kIndirectPointerNullTag);
109 }
110
111 private:
112 Payload(Address pointer, IndirectPointerTag tag)
113 : TaggedPayload(pointer, tag) {}
114 };
115
116 std::atomic<Payload> payload_;
117};
118
119static_assert(sizeof(TrustedPointerTableEntry) ==
121
136class V8_EXPORT_PRIVATE TrustedPointerTable
137 : public ExternalEntityTable<TrustedPointerTableEntry,
138 kTrustedPointerTableReservationSize> {
139 public:
140 static_assert(kMaxTrustedPointers == kMaxCapacity);
141 static_assert(!kSupportsCompaction);
142
143 TrustedPointerTable() = default;
144 TrustedPointerTable(const TrustedPointerTable&) = delete;
145 TrustedPointerTable& operator=(const TrustedPointerTable&) = delete;
146
147 // The Spaces used by a TrustedPointerTable.
148 using Space = ExternalEntityTable<
149 TrustedPointerTableEntry,
150 kTrustedPointerTableReservationSize>::SpaceWithBlackAllocationSupport;
151
152 // Retrieves the content of the entry referenced by the given handle.
153 //
154 // This method is atomic and can be called from background threads.
155 inline Address Get(TrustedPointerHandle handle, IndirectPointerTag tag) const;
156 // Allows kUnpublishedIndirectPointerTag in addition to the specified {tag}.
157 inline Address GetMaybeUnpublished(TrustedPointerHandle handle,
158 IndirectPointerTag tag) const;
159
160 // Sets the content of the entry referenced by the given handle.
161 //
162 // This method is atomic and can be called from background threads.
163 inline void Set(TrustedPointerHandle handle, Address pointer,
164 IndirectPointerTag tag);
165
166 // Allocates a new entry in the table and initialize it.
167 //
168 // This method is atomic and can be called from background threads.
169 inline TrustedPointerHandle AllocateAndInitializeEntry(
170 Space* space, Address pointer, IndirectPointerTag tag,
171 TrustedPointerPublishingScope* scope);
172
173 // Marks the specified entry as alive.
174 //
175 // This method is atomic and can be called from background threads.
176 inline void Mark(Space* space, TrustedPointerHandle handle);
177
178 // Frees all unmarked entries in the given space.
179 //
180 // This method must only be called while mutator threads are stopped as it is
181 // not safe to allocate table entries while a space is being swept.
182 //
183 // Returns the number of live entries after sweeping.
184 uint32_t Sweep(Space* space, Counters* counters);
185
186 // Zaps the content of the entry referenced by the given handle.
187 //
188 // Accessing a zapped entry will return an invalid pointer.
189 inline void Zap(TrustedPointerHandle handle);
190
191 // Checks whether the given entry currently has the "unpublished" tag.
192 inline bool IsUnpublished(TrustedPointerHandle handle) const;
193
194 // Iterate over all active entries in the given space.
195 //
196 // The callback function will be invoked once for every entry that is
197 // currently in use, i.e. has been allocated and not yet freed, and will
198 // receive the handle and content of that entry.
199 template <typename Callback>
200 void IterateActiveEntriesIn(Space* space, Callback callback);
201
202 // The base address of this table, for use in JIT compilers.
203 Address base_address() const { return base(); }
204
205 private:
206 inline uint32_t HandleToIndex(TrustedPointerHandle handle) const;
207 inline TrustedPointerHandle IndexToHandle(uint32_t index) const;
208
209 // Ensure that the value is valid before storing it into this table.
210 inline void Validate(Address pointer, IndirectPointerTag tag);
211};
212
213} // namespace internal
214} // namespace v8
215
216#endif // V8_ENABLE_SANDBOX
217
218#endif // V8_SANDBOX_TRUSTED_POINTER_TABLE_H_
TNode< Object > callback
uintptr_t Address
Definition memory.h:13
V8_INLINE const Operation & Get(const Graph &graph, OpIndex index)
Definition graph.h:1231
constexpr int kTagMask
Definition reloc-info.h:72
IndirectPointerHandle TrustedPointerHandle
constexpr int kTrustedPointerTableEntrySize
constexpr size_t kMaxTrustedPointers
constexpr uint64_t kIndirectPointerTagMask
constexpr size_t kTrustedPointerTableReservationSize
constexpr uint64_t kTrustedPointerTableMarkBit
#define DCHECK_EQ(v1, v2)
Definition logging.h:485
#define V8_EXPORT_PRIVATE
Definition macros.h:460