v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
code-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_CODE_POINTER_TABLE_H_
6#define V8_SANDBOX_CODE_POINTER_TABLE_H_
7
8#include "include/v8config.h"
10#include "src/base/memory.h"
11#include "src/common/globals.h"
14
15#ifdef V8_COMPRESS_POINTERS
16
17namespace v8 {
18namespace internal {
19
20class Isolate;
21class Counters;
22
29struct CodePointerTableEntry {
30 // We write-protect the CodePointerTable on platforms that support it for
31 // forward-edge CFI.
32 static constexpr bool IsWriteProtected = true;
33
34 // Make this entry a code pointer entry for the given code object and
35 // entrypoint.
36 inline void MakeCodePointerEntry(Address code, Address entrypoint,
37 CodeEntrypointTag tag, bool mark_as_alive);
38
39 // Make this entry a freelist entry, containing the index of the next entry
40 // on the freelist.
41 inline void MakeFreelistEntry(uint32_t next_entry_index);
42
43 // Load code entrypoint pointer stored in this entry.
44 // This entry must be a code pointer entry.
45 inline Address GetEntrypoint(CodeEntrypointTag tag) const;
46
47 // Store the given code entrypoint pointer in this entry.
48 // This entry must be a code pointer entry.
49 inline void SetEntrypoint(Address value, CodeEntrypointTag tag);
50
51 // Load the code object pointer stored in this entry.
52 // This entry must be a code pointer entry.
53 inline Address GetCodeObject() const;
54
55 // Store the given code object pointer in this entry.
56 // This entry must be a code pointer entry.
57 inline void SetCodeObject(Address value);
58
59 // Returns true if this entry is a freelist entry.
60 inline bool IsFreelistEntry() const;
61
62 // Get the index of the next entry on the freelist. This method may be
63 // called even when the entry is not a freelist entry. However, the result
64 // is only valid if this is a freelist entry. This behaviour is required
65 // for efficient entry allocation, see TryAllocateEntryFromFreelist.
66 inline uint32_t GetNextFreelistEntryIndex() const;
67
68 // Mark this entry as alive during garbage collection.
69 inline void Mark();
70
71 // Unmark this entry during sweeping.
72 inline void Unmark();
73
74 // Test whether this entry is currently marked as alive.
75 inline bool IsMarked() const;
76
77 private:
78 friend class CodePointerTable;
79
80 // Freelist entries contain the index of the next free entry in their lower 32
81 // bits and are tagged with the kFreeCodePointerTableEntryTag.
83
84 // The marking bit is stored in the code_ field, see below.
85 static constexpr Address kMarkingBit = 1;
86
87 std::atomic<Address> entrypoint_;
88 // The pointer to the Code object also contains the marking bit: since this is
89 // a tagged pointer to a V8 HeapObject, we know that it will be 4-byte aligned
90 // and that the LSB should always be set. We therefore use the LSB as marking
91 // bit. In this way:
92 // - When loading the pointer, we only need to perform an unconditional OR 1
93 // to get the correctly tagged pointer
94 // - When storing the pointer we don't need to do anything since the tagged
95 // pointer will automatically be marked
96 std::atomic<Address> code_;
97};
98
99static_assert(sizeof(CodePointerTableEntry) == kCodePointerTableEntrySize);
100
118class V8_EXPORT_PRIVATE CodePointerTable
119 : public ExternalEntityTable<CodePointerTableEntry,
120 kCodePointerTableReservationSize> {
121 using Base = ExternalEntityTable<CodePointerTableEntry,
123
124 public:
125 static_assert(kMaxCodePointers == kMaxCapacity);
126 static_assert(!kSupportsCompaction);
127
128 CodePointerTable() = default;
129 CodePointerTable(const CodePointerTable&) = delete;
130 CodePointerTable& operator=(const CodePointerTable&) = delete;
131
132 // The Spaces used by a CodePointerTable.
133 using Space = Base::SpaceWithBlackAllocationSupport;
134
135 // Retrieves the entrypoint of the entry referenced by the given handle.
136 //
137 // This method is atomic and can be called from background threads.
138 inline Address GetEntrypoint(CodePointerHandle handle,
139 CodeEntrypointTag tag) const;
140
141 // Retrieves the code object of the entry referenced by the given handle.
142 //
143 // This method is atomic and can be called from background threads.
144 inline Address GetCodeObject(CodePointerHandle handle) const;
145
146 // Sets the entrypoint of the entry referenced by the given handle.
147 //
148 // This method is atomic and can be called from background threads.
149 inline void SetEntrypoint(CodePointerHandle handle, Address value,
150 CodeEntrypointTag tag);
151
152 // Sets the code object of the entry referenced by the given handle.
153 //
154 // This method is atomic and can be called from background threads.
155 inline void SetCodeObject(CodePointerHandle handle, Address value);
156
157 // Allocates a new entry in the table and initialize it.
158 //
159 // This method is atomic and can be called from background threads.
160 inline CodePointerHandle AllocateAndInitializeEntry(Space* space,
161 Address code,
162 Address entrypoint,
163 CodeEntrypointTag tag);
164
165 // Marks the specified entry as alive.
166 //
167 // This method is atomic and can be called from background threads.
168 inline void Mark(Space* space, CodePointerHandle handle);
169
170 // Frees all unmarked entries in the given space.
171 //
172 // This method must only be called while mutator threads are stopped as it is
173 // not safe to allocate table entries while a space is being swept.
174 //
175 // Returns the number of live entries after sweeping.
176 uint32_t Sweep(Space* space, Counters* counters);
177
178 // Iterate over all active entries in the given space.
179 //
180 // The callback function will be invoked once for every entry that is
181 // currently in use, i.e. has been allocated and not yet freed, and will
182 // receive the handle and content (Code object pointer) of that entry.
183 template <typename Callback>
184 void IterateActiveEntriesIn(Space* space, Callback callback);
185
186 // The base address of this table, for use in JIT compilers.
187 Address base_address() const { return base(); }
188
189 private:
190 inline uint32_t HandleToIndex(CodePointerHandle handle) const;
191 inline CodePointerHandle IndexToHandle(uint32_t index) const;
192};
193
194} // namespace internal
195} // namespace v8
196
197#endif // V8_COMPRESS_POINTERS
198
199#endif // V8_SANDBOX_CODE_POINTER_TABLE_H_
ZoneList< RegExpInstruction > code_
TNode< Object > callback
uintptr_t Address
Definition memory.h:13
IndirectPointerHandle CodePointerHandle
constexpr size_t kCodePointerTableReservationSize
constexpr size_t kMaxCodePointers
constexpr int kCodePointerTableEntrySize
#define V8_EXPORT_PRIVATE
Definition macros.h:460