5#ifndef V8_SANDBOX_JS_DISPATCH_TABLE_H_
6#define V8_SANDBOX_JS_DISPATCH_TABLE_H_
15#ifdef V8_ENABLE_LEAPTIERING
33struct JSDispatchEntry {
36 static constexpr bool IsWriteProtected =
true;
38 inline void MakeJSDispatchEntry(Address
object, Address entrypoint,
41 inline Address GetEntrypoint()
const;
42 inline Address GetCodePointer()
const;
43 inline Tagged<Code> GetCode()
const;
44 inline uint16_t GetParameterCount()
const;
46 inline void SetCodeAndEntrypointPointer(Address new_object,
47 Address new_entrypoint);
48 inline void SetEntrypointPointer(Address new_entrypoint);
52 inline void MakeFreelistEntry(uint32_t next_entry_index);
55 inline bool IsFreelistEntry()
const;
61 inline uint32_t GetNextFreelistEntryIndex()
const;
70 inline bool IsMarked()
const;
74 static constexpr uintptr_t kEntrypointOffset = 0;
76 static constexpr size_t kParameterCountSize = 2;
78#if defined(V8_TARGET_ARCH_64_BIT)
82#ifdef V8_TARGET_BIG_ENDIAN
84 static constexpr int kBigEndianParamCountOffset =
85 sizeof(
Address) -
sizeof(uint16_t);
86 static constexpr uintptr_t kParameterCountOffset =
87 kCodeObjectOffset + kBigEndianParamCountOffset;
89 static constexpr uintptr_t kParameterCountOffset = kCodeObjectOffset;
91 static constexpr uint32_t kObjectPointerShift = 16;
92 static constexpr uint32_t kParameterCountMask = 0xffff;
93#elif defined(V8_TARGET_ARCH_32_BIT)
94 static constexpr uintptr_t kParameterCountOffset =
96 static constexpr uint32_t kObjectPointerShift = 0;
97 static constexpr uint32_t kParameterCountMask = 0x0;
99#error "Unsupported Architecture"
102 static void CheckFieldOffsets();
105 friend class JSDispatchTable;
108 std::atomic<Address> entrypoint_;
133 static constexpr Address kMarkingBit = 1 << kObjectPointerShift;
134 std::atomic<Address> encoded_word_;
136#ifdef V8_TARGET_ARCH_32_BIT
139 std::atomic<uint16_t> parameter_count_;
141 std::atomic<uint32_t> next_free_entry_;
170 :
public ExternalEntityTable<JSDispatchEntry,
171 kJSDispatchTableReservationSize> {
173 ExternalEntityTable<JSDispatchEntry, kJSDispatchTableReservationSize>;
176#ifdef V8_ENABLE_SANDBOX
179 static_assert(!kSupportsCompaction);
181 JSDispatchTable() =
default;
182 JSDispatchTable(
const JSDispatchTable&) =
delete;
183 JSDispatchTable& operator=(
const JSDispatchTable&) =
delete;
186 using Space = Base::SpaceWithBlackAllocationSupport;
189 inline Address GetEntrypoint(JSDispatchHandle handle);
196 inline Tagged<Code> GetCode(JSDispatchHandle handle);
199 inline Address GetCodeAddress(JSDispatchHandle handle);
202 inline uint16_t GetParameterCount(JSDispatchHandle handle);
208 inline void SetCodeNoWriteBarrier(JSDispatchHandle handle,
209 Tagged<Code> new_code);
213 inline void SetTieringRequest(JSDispatchHandle handle, TieringBuiltin builtin,
215 inline void SetCodeKeepTieringRequestNoWriteBarrier(JSDispatchHandle handle,
216 Tagged<Code> new_code);
218 inline void ResetTieringRequest(JSDispatchHandle handle);
220 inline bool IsTieringRequested(JSDispatchHandle handle);
221 inline bool IsTieringRequested(JSDispatchHandle handle,
222 TieringBuiltin builtin, Isolate* isolate);
232 inline std::optional<JSDispatchHandle> TryAllocateAndInitializeEntry(
238 bool ensure_static_handles);
239 bool PreAllocatedEntryNeedsInitialization(Space* space,
240 JSDispatchHandle handle);
241 void InitializePreAllocatedEntry(Space* space, JSDispatchHandle handle,
246#if V8_STATIC_DISPATCH_HANDLES_BOOL
248 return IndexToHandle(kInternalNullEntryIndex + 1 + index);
251 static bool InReadOnlySegment(JSDispatchHandle handle) {
252 return HandleToIndex(handle) <= kEndOfInternalReadOnlySegment;
254 static int OffsetOfEntry(JSDispatchHandle handle) {
255 return JSDispatchTable::HandleToIndex(handle)
262 inline void Mark(JSDispatchHandle handle);
270 template <
typename Callback>
271 uint32_t Sweep(Space* space, Counters* counters, Callback
callback);
278 template <
typename Callback>
279 void IterateActiveEntriesIn(Space* space, Callback
callback);
281 template <
typename Callback>
282 void IterateMarkedEntriesIn(Space* space, Callback
callback);
288 bool IsMarked(JSDispatchHandle handle);
290#if defined(DEBUG) || defined(VERIFY_HEAP)
291 inline void VerifyEntry(JSDispatchHandle handle, Space* space,
295 void PrintEntry(JSDispatchHandle handle);
296 void PrintCurrentTieringRequest(JSDispatchHandle handle, Isolate* isolate,
299 static constexpr bool kWriteBarrierSetsEntryMarkBit =
true;
302 static inline bool IsCompatibleCode(Tagged<Code> code,
305 inline void SetCodeAndEntrypointNoWriteBarrier(JSDispatchHandle handle,
306 Tagged<Code> new_code,
309 static uint32_t HandleToIndex(JSDispatchHandle handle) {
310 uint32_t index =
handle.value() >> kJSDispatchHandleShift;
320 friend class MarkCompactCollector;
V8_INLINE IndirectHandle< T > handle(Tagged< T > object, Isolate *isolate)
base::StrongAlias< JSDispatchHandleAliasTag, uint32_t > JSDispatchHandle
constexpr int kSystemPointerSize
constexpr size_t kMaxJSDispatchEntries
constexpr int kJSDispatchTableEntrySizeLog2
constexpr int kJSDispatchTableEntrySize
#define DCHECK_EQ(v1, v2)
#define V8_EXPORT_PRIVATE