v8 10.2.154 (node 18.16.0)
V8 is Google's open source JavaScript engine
Loading...
Searching...
No Matches
v8-platform.h
Go to the documentation of this file.
1// Copyright 2013 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_V8_PLATFORM_H_
6#define V8_V8_PLATFORM_H_
7
8#include <stddef.h>
9#include <stdint.h>
10#include <stdlib.h> // For abort.
11#include <memory>
12#include <string>
13
14#include "v8config.h" // NOLINT(build/include_directory)
15
16namespace v8 {
17
18class Isolate;
19
20// Valid priorities supported by the task scheduling infrastructure.
21enum class TaskPriority : uint8_t {
40};
41
45class Task {
46 public:
47 virtual ~Task() = default;
48
49 virtual void Run() = 0;
50};
51
58class IdleTask {
59 public:
60 virtual ~IdleTask() = default;
61 virtual void Run(double deadline_in_seconds) = 0;
62};
63
71 public:
76 virtual void PostTask(std::unique_ptr<Task> task) = 0;
77
93 virtual void PostNonNestableTask(std::unique_ptr<Task> task) {}
94
100 virtual void PostDelayedTask(std::unique_ptr<Task> task,
101 double delay_in_seconds) = 0;
102
119 virtual void PostNonNestableDelayedTask(std::unique_ptr<Task> task,
120 double delay_in_seconds) {}
121
130 virtual void PostIdleTask(std::unique_ptr<IdleTask> task) = 0;
131
135 virtual bool IdleTasksEnabled() = 0;
136
140 virtual bool NonNestableTasksEnabled() const { return false; }
141
145 virtual bool NonNestableDelayedTasksEnabled() const { return false; }
146
147 TaskRunner() = default;
148 virtual ~TaskRunner() = default;
149
150 TaskRunner(const TaskRunner&) = delete;
151 TaskRunner& operator=(const TaskRunner&) = delete;
152};
153
159 public:
165 virtual bool ShouldYield() = 0;
166
172 virtual void NotifyConcurrencyIncrease() = 0;
173
179 virtual uint8_t GetTaskId() = 0;
180
185 virtual bool IsJoiningThread() const = 0;
186};
187
193 public:
194 virtual ~JobHandle() = default;
195
201 virtual void NotifyConcurrencyIncrease() = 0;
202
210 virtual void Join() = 0;
211
216 virtual void Cancel() = 0;
217
218 /*
219 * Forces all existing workers to yield ASAP but doesn’t wait for them.
220 * Warning, this is dangerous if the Job's callback is bound to or has access
221 * to state which may be deleted after this call.
222 */
223 virtual void CancelAndDetach() = 0;
224
228 virtual bool IsActive() = 0;
229
235 virtual bool IsValid() = 0;
236
240 virtual bool UpdatePriorityEnabled() const { return false; }
241
245 virtual void UpdatePriority(TaskPriority new_priority) {}
246};
247
251class JobTask {
252 public:
253 virtual ~JobTask() = default;
254
255 virtual void Run(JobDelegate* delegate) = 0;
256
264 virtual size_t GetMaxConcurrency(size_t worker_count) const = 0;
265};
266
271 public:
272 virtual ~ConvertableToTraceFormat() = default;
273
280 virtual void AppendAsTraceFormat(std::string* out) const = 0;
281};
282
289 public:
290 virtual ~TracingController() = default;
291
292 // In Perfetto mode, trace events are written using Perfetto's Track Event
293 // API directly without going through the embedder. However, it is still
294 // possible to observe tracing being enabled and disabled.
295#if !defined(V8_USE_PERFETTO)
303 virtual const uint8_t* GetCategoryGroupEnabled(const char* name) {
304 static uint8_t no = 0;
305 return &no;
306 }
307
316 virtual uint64_t AddTraceEvent(
317 char phase, const uint8_t* category_enabled_flag, const char* name,
318 const char* scope, uint64_t id, uint64_t bind_id, int32_t num_args,
319 const char** arg_names, const uint8_t* arg_types,
320 const uint64_t* arg_values,
321 std::unique_ptr<ConvertableToTraceFormat>* arg_convertables,
322 unsigned int flags) {
323 return 0;
324 }
326 char phase, const uint8_t* category_enabled_flag, const char* name,
327 const char* scope, uint64_t id, uint64_t bind_id, int32_t num_args,
328 const char** arg_names, const uint8_t* arg_types,
329 const uint64_t* arg_values,
330 std::unique_ptr<ConvertableToTraceFormat>* arg_convertables,
331 unsigned int flags, int64_t timestamp) {
332 return 0;
333 }
334
339 virtual void UpdateTraceEventDuration(const uint8_t* category_enabled_flag,
340 const char* name, uint64_t handle) {}
341#endif // !defined(V8_USE_PERFETTO)
342
344 public:
345 virtual ~TraceStateObserver() = default;
346 virtual void OnTraceEnabled() = 0;
347 virtual void OnTraceDisabled() = 0;
348 };
349
352
355};
356
363 public:
364 virtual ~PageAllocator() = default;
365
370 virtual size_t AllocatePageSize() = 0;
371
376 virtual size_t CommitPageSize() = 0;
377
382 virtual void SetRandomMmapSeed(int64_t seed) = 0;
383
388 virtual void* GetRandomMmapAddr() = 0;
389
399 // Set this when reserving memory that will later require kReadWriteExecute
400 // permissions. The resulting behavior is platform-specific, currently
401 // this is used to set the MAP_JIT flag on Apple Silicon.
402 // TODO(jkummerow): Remove this when Wasm has a platform-independent
403 // w^x implementation.
404 // TODO(saelo): Remove this once all JIT pages are allocated through the
405 // VirtualAddressSpace API.
407 };
408
412 virtual void* AllocatePages(void* address, size_t length, size_t alignment,
413 Permission permissions) = 0;
414
418 virtual bool FreePages(void* address, size_t length) = 0;
419
423 virtual bool ReleasePages(void* address, size_t length,
424 size_t new_length) = 0;
425
429 virtual bool SetPermissions(void* address, size_t length,
430 Permission permissions) = 0;
431
439 virtual bool DiscardSystemPages(void* address, size_t size) { return true; }
440
449 virtual bool DecommitPages(void* address, size_t size) = 0;
450
456 public:
457 // Implementations are expected to free the shared memory mapping in the
458 // destructor.
459 virtual ~SharedMemoryMapping() = default;
460 virtual void* GetMemory() const = 0;
461 };
462
468 public:
469 // Implementations are expected to free the shared memory in the destructor.
470 virtual ~SharedMemory() = default;
471 virtual std::unique_ptr<SharedMemoryMapping> RemapTo(
472 void* new_address) const = 0;
473 virtual void* GetMemory() const = 0;
474 virtual size_t GetSize() const = 0;
475 };
476
486 virtual bool ReserveForSharedMemoryMapping(void* address, size_t size) {
487 return false;
488 }
489
499 virtual std::unique_ptr<SharedMemory> AllocateSharedPages(
500 size_t length, const void* original_address) {
501 return {};
502 }
503
512 virtual bool CanAllocateSharedPages() { return false; }
513};
514
515// Opaque type representing a handle to a shared memory region.
517static constexpr PlatformSharedMemoryHandle kInvalidSharedMemoryHandle = -1;
518
519// Conversion routines from the platform-dependent shared memory identifiers
520// into the opaque PlatformSharedMemoryHandle type. These use the underlying
521// types (e.g. unsigned int) instead of the typedef'd ones (e.g. mach_port_t)
522// to avoid pulling in large OS header files into this header file. Instead,
523// the users of these routines are expected to include the respecitve OS
524// headers in addition to this one.
525#if V8_OS_MACOS
526// Convert between a shared memory handle and a mach_port_t referencing a memory
527// entry object.
528inline PlatformSharedMemoryHandle SharedMemoryHandleFromMachMemoryEntry(
529 unsigned int port) {
530 return static_cast<PlatformSharedMemoryHandle>(port);
531}
532inline unsigned int MachMemoryEntryFromSharedMemoryHandle(
534 return static_cast<unsigned int>(handle);
535}
536#elif V8_OS_FUCHSIA
537// Convert between a shared memory handle and a zx_handle_t to a VMO.
538inline PlatformSharedMemoryHandle SharedMemoryHandleFromVMO(uint32_t handle) {
539 return static_cast<PlatformSharedMemoryHandle>(handle);
540}
541inline uint32_t VMOFromSharedMemoryHandle(PlatformSharedMemoryHandle handle) {
542 return static_cast<uint32_t>(handle);
543}
544#elif V8_OS_WIN
545// Convert between a shared memory handle and a Windows HANDLE to a file mapping
546// object.
547inline PlatformSharedMemoryHandle SharedMemoryHandleFromFileMapping(
548 void* handle) {
549 return reinterpret_cast<PlatformSharedMemoryHandle>(handle);
550}
551inline void* FileMappingFromSharedMemoryHandle(
553 return reinterpret_cast<void*>(handle);
554}
555#else
556// Convert between a shared memory handle and a file descriptor.
558 return static_cast<PlatformSharedMemoryHandle>(fd);
559}
562 return static_cast<int>(handle);
563}
564#endif
565
569enum class PagePermissions {
570 kNoAccess,
571 kRead,
575};
576
588 public:
589 using Address = uintptr_t;
590
592 Address base, size_t size,
594 : page_size_(page_size),
595 allocation_granularity_(allocation_granularity),
596 base_(base),
597 size_(size),
598 max_page_permissions_(max_page_permissions) {}
599
600 virtual ~VirtualAddressSpace() = default;
601
609 size_t page_size() const { return page_size_; }
610
619 size_t allocation_granularity() const { return allocation_granularity_; }
620
626 Address base() const { return base_; }
627
633 size_t size() const { return size_; }
634
641 PagePermissions max_page_permissions() const { return max_page_permissions_; }
642
649 virtual void SetRandomSeed(int64_t seed) = 0;
650
658
679 static constexpr Address kNoHint = 0;
681 AllocatePages(Address hint, size_t size, size_t alignment,
682 PagePermissions permissions) = 0;
683
696 virtual void FreePages(Address address, size_t size) = 0;
697
712 Address address, size_t size, PagePermissions permissions) = 0;
713
731 size_t size) = 0;
732
746 virtual void FreeGuardRegion(Address address, size_t size) = 0;
747
769 PlatformSharedMemoryHandle handle, uint64_t offset) = 0;
770
783 virtual void FreeSharedPages(Address address, size_t size) = 0;
784
790 virtual bool CanAllocateSubspaces() = 0;
791
792 /*
793 * Allocate a subspace.
794 *
795 * The address space of a subspace stays reserved in the parent space for the
796 * lifetime of the subspace. As such, it is guaranteed that page allocations
797 * on the parent space cannot end up inside a subspace.
798 *
799 * \param hint Hints where the subspace should be allocated. See
800 * AllocatePages() for more details.
801 *
802 * \param size The size in bytes of the subspace. Must be a multiple of the
803 * allocation_granularity().
804 *
805 * \param alignment The alignment of the subspace in bytes. Must be a multiple
806 * of the allocation_granularity() and should be a power of two.
807 *
808 * \param max_page_permissions The maximum permissions that pages allocated in
809 * the subspace can obtain.
810 *
811 * \returns a new subspace or nullptr on failure.
812 */
813 virtual std::unique_ptr<VirtualAddressSpace> AllocateSubspace(
814 Address hint, size_t size, size_t alignment,
816
817 //
818 // TODO(v8) maybe refactor the methods below before stabilizing the API. For
819 // example by combining them into some form of page operation method that
820 // takes a command enum as parameter.
821 //
822
834 size_t size) {
835 return true;
836 }
848 size_t size) = 0;
849
850 private:
851 const size_t page_size_;
852 const size_t allocation_granularity_;
853 const Address base_;
854 const size_t size_;
855 const PagePermissions max_page_permissions_;
856};
857
862 public:
863 using MallocFn = void* (*)(size_t);
864 using FreeFn = void (*)(void*);
865
866 virtual MallocFn GetMallocFn() const { return ::malloc; }
867 virtual FreeFn GetFreeFn() const { return ::free; }
868};
869
875 public:
876 virtual void EnterSection() {}
877 virtual void LeaveSection() {}
878};
879
886class Platform {
887 public:
888 virtual ~Platform() = default;
889
894 // TODO(bbudge) Make this abstract after all embedders implement this.
895 return nullptr;
896 }
897
902 static ZoneBackingAllocator default_allocator;
903 return &default_allocator;
904 }
905
914 // TODO(bbudge) Remove this when embedders override the following method.
915 // See crbug.com/634547.
916 }
917
927 virtual bool OnCriticalMemoryPressure(size_t length) { return false; }
928
936 virtual int NumberOfWorkerThreads() = 0;
937
943 virtual std::shared_ptr<v8::TaskRunner> GetForegroundTaskRunner(
944 Isolate* isolate) = 0;
945
949 virtual void CallOnWorkerThread(std::unique_ptr<Task> task) = 0;
950
955 virtual void CallBlockingTaskOnWorkerThread(std::unique_ptr<Task> task) {
956 // Embedders may optionally override this to process these tasks in a high
957 // priority pool.
958 CallOnWorkerThread(std::move(task));
959 }
960
964 virtual void CallLowPriorityTaskOnWorkerThread(std::unique_ptr<Task> task) {
965 // Embedders may optionally override this to process these tasks in a low
966 // priority pool.
967 CallOnWorkerThread(std::move(task));
968 }
969
974 virtual void CallDelayedOnWorkerThread(std::unique_ptr<Task> task,
975 double delay_in_seconds) = 0;
976
980 virtual bool IdleTasksEnabled(Isolate* isolate) { return false; }
981
1034 virtual std::unique_ptr<JobHandle> PostJob(
1035 TaskPriority priority, std::unique_ptr<JobTask> job_task) = 0;
1036
1044 virtual double MonotonicallyIncreasingTime() = 0;
1045
1050 virtual double CurrentClockTimeMillis() = 0;
1051
1052 typedef void (*StackTracePrinter)();
1053
1058 virtual StackTracePrinter GetStackTracePrinter() { return nullptr; }
1059
1064
1069 virtual void DumpWithoutCrashing() {}
1070
1077 static HighAllocationThroughputObserver default_observer;
1078 return &default_observer;
1079 }
1080
1081 protected:
1088};
1089
1090} // namespace v8
1091
1092#endif // V8_V8_PLATFORM_H_
virtual void AppendAsTraceFormat(std::string *out) const =0
virtual ~ConvertableToTraceFormat()=default
virtual ~IdleTask()=default
virtual void Run(double deadline_in_seconds)=0
virtual bool IsJoiningThread() const =0
virtual uint8_t GetTaskId()=0
virtual bool ShouldYield()=0
virtual void NotifyConcurrencyIncrease()=0
virtual void UpdatePriority(TaskPriority new_priority)
virtual bool UpdatePriorityEnabled() const
virtual void CancelAndDetach()=0
virtual bool IsActive()=0
virtual bool IsValid()=0
virtual void Cancel()=0
virtual void NotifyConcurrencyIncrease()=0
virtual ~JobHandle()=default
virtual void Join()=0
virtual size_t GetMaxConcurrency(size_t worker_count) const =0
virtual void Run(JobDelegate *delegate)=0
virtual ~JobTask()=default
virtual std::unique_ptr< SharedMemoryMapping > RemapTo(void *new_address) const =0
virtual size_t GetSize() const =0
virtual void * GetMemory() const =0
virtual ~SharedMemory()=default
virtual void * GetMemory() const =0
virtual std::unique_ptr< SharedMemory > AllocateSharedPages(size_t length, const void *original_address)
virtual bool SetPermissions(void *address, size_t length, Permission permissions)=0
virtual bool CanAllocateSharedPages()
virtual bool DecommitPages(void *address, size_t size)=0
virtual void * AllocatePages(void *address, size_t length, size_t alignment, Permission permissions)=0
virtual void * GetRandomMmapAddr()=0
virtual size_t CommitPageSize()=0
virtual bool DiscardSystemPages(void *address, size_t size)
virtual bool ReserveForSharedMemoryMapping(void *address, size_t size)
virtual bool ReleasePages(void *address, size_t length, size_t new_length)=0
virtual void SetRandomMmapSeed(int64_t seed)=0
virtual ~PageAllocator()=default
virtual size_t AllocatePageSize()=0
virtual bool FreePages(void *address, size_t length)=0
virtual ~Platform()=default
virtual TracingController * GetTracingController()=0
static V8_EXPORT double SystemClockTimeMillis()
virtual std::unique_ptr< JobHandle > PostJob(TaskPriority priority, std::unique_ptr< JobTask > job_task)=0
virtual void CallLowPriorityTaskOnWorkerThread(std::unique_ptr< Task > task)
virtual ZoneBackingAllocator * GetZoneBackingAllocator()
virtual void DumpWithoutCrashing()
virtual void CallBlockingTaskOnWorkerThread(std::unique_ptr< Task > task)
virtual std::shared_ptr< v8::TaskRunner > GetForegroundTaskRunner(Isolate *isolate)=0
void(* StackTracePrinter)()
virtual StackTracePrinter GetStackTracePrinter()
virtual void CallOnWorkerThread(std::unique_ptr< Task > task)=0
virtual bool OnCriticalMemoryPressure(size_t length)
virtual double CurrentClockTimeMillis()=0
virtual void OnCriticalMemoryPressure()
virtual void CallDelayedOnWorkerThread(std::unique_ptr< Task > task, double delay_in_seconds)=0
virtual HighAllocationThroughputObserver * GetHighAllocationThroughputObserver()
virtual bool IdleTasksEnabled(Isolate *isolate)
virtual double MonotonicallyIncreasingTime()=0
virtual int NumberOfWorkerThreads()=0
virtual PageAllocator * GetPageAllocator()
virtual void Run()=0
virtual ~Task()=default
virtual bool NonNestableTasksEnabled() const
virtual void PostNonNestableDelayedTask(std::unique_ptr< Task > task, double delay_in_seconds)
virtual void PostDelayedTask(std::unique_ptr< Task > task, double delay_in_seconds)=0
TaskRunner(const TaskRunner &)=delete
TaskRunner()=default
virtual bool NonNestableDelayedTasksEnabled() const
virtual void PostIdleTask(std::unique_ptr< IdleTask > task)=0
virtual bool IdleTasksEnabled()=0
virtual void PostTask(std::unique_ptr< Task > task)=0
virtual ~TaskRunner()=default
TaskRunner & operator=(const TaskRunner &)=delete
virtual void PostNonNestableTask(std::unique_ptr< Task > task)
Definition v8-platform.h:93
virtual const uint8_t * GetCategoryGroupEnabled(const char *name)
virtual void AddTraceStateObserver(TraceStateObserver *)
virtual ~TracingController()=default
virtual uint64_t AddTraceEventWithTimestamp(char phase, const uint8_t *category_enabled_flag, const char *name, const char *scope, uint64_t id, uint64_t bind_id, int32_t num_args, const char **arg_names, const uint8_t *arg_types, const uint64_t *arg_values, std::unique_ptr< ConvertableToTraceFormat > *arg_convertables, unsigned int flags, int64_t timestamp)
virtual void UpdateTraceEventDuration(const uint8_t *category_enabled_flag, const char *name, uint64_t handle)
virtual uint64_t AddTraceEvent(char phase, const uint8_t *category_enabled_flag, const char *name, const char *scope, uint64_t id, uint64_t bind_id, int32_t num_args, const char **arg_names, const uint8_t *arg_types, const uint64_t *arg_values, std::unique_ptr< ConvertableToTraceFormat > *arg_convertables, unsigned int flags)
virtual void RemoveTraceStateObserver(TraceStateObserver *)
size_t page_size() const
virtual V8_WARN_UNUSED_RESULT bool DiscardSystemPages(Address address, size_t size)
static constexpr Address kNoHint
VirtualAddressSpace(size_t page_size, size_t allocation_granularity, Address base, size_t size, PagePermissions max_page_permissions)
virtual void SetRandomSeed(int64_t seed)=0
virtual V8_WARN_UNUSED_RESULT bool SetPagePermissions(Address address, size_t size, PagePermissions permissions)=0
size_t allocation_granularity() const
virtual V8_WARN_UNUSED_RESULT Address AllocateSharedPages(Address hint, size_t size, PagePermissions permissions, PlatformSharedMemoryHandle handle, uint64_t offset)=0
virtual void FreeGuardRegion(Address address, size_t size)=0
virtual V8_WARN_UNUSED_RESULT bool DecommitPages(Address address, size_t size)=0
virtual ~VirtualAddressSpace()=default
virtual std::unique_ptr< VirtualAddressSpace > AllocateSubspace(Address hint, size_t size, size_t alignment, PagePermissions max_page_permissions)=0
virtual void FreeSharedPages(Address address, size_t size)=0
virtual V8_WARN_UNUSED_RESULT Address AllocatePages(Address hint, size_t size, size_t alignment, PagePermissions permissions)=0
virtual void FreePages(Address address, size_t size)=0
virtual bool CanAllocateSubspaces()=0
Address base() const
virtual Address RandomPageAddress()=0
PagePermissions max_page_permissions() const
virtual V8_WARN_UNUSED_RESULT bool AllocateGuardRegion(Address address, size_t size)=0
void(*)(void *) FreeFn
virtual MallocFn GetMallocFn() const
virtual FreeFn GetFreeFn() const
void *(*)(size_t) MallocFn
intptr_t PlatformSharedMemoryHandle
PlatformSharedMemoryHandle SharedMemoryHandleFromFileDescriptor(int fd)
TaskPriority
Definition v8-platform.h:21
int FileDescriptorFromSharedMemoryHandle(PlatformSharedMemoryHandle handle)
PagePermissions
int32_t(Local< Array > src, int32_t *dst, uint32_t max_length)
#define V8_EXPORT
Definition v8config.h:578
#define V8_WARN_UNUSED_RESULT
Definition v8config.h:499