v8  9.0.257(node16.0.0)
V8 is Google's open source JavaScript engine
platform.h
Go to the documentation of this file.
1 // Copyright 2020 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 INCLUDE_CPPGC_PLATFORM_H_
6 #define INCLUDE_CPPGC_PLATFORM_H_
7 
8 #include "v8-platform.h" // NOLINT(build/include_directory)
9 #include "v8config.h" // NOLINT(build/include_directory)
10 
11 namespace cppgc {
12 
13 // TODO(v8:10346): Create separate includes for concepts that are not
14 // V8-specific.
15 using IdleTask = v8::IdleTask;
16 using JobHandle = v8::JobHandle;
17 using JobDelegate = v8::JobDelegate;
18 using JobTask = v8::JobTask;
19 using PageAllocator = v8::PageAllocator;
20 using Task = v8::Task;
21 using TaskPriority = v8::TaskPriority;
22 using TaskRunner = v8::TaskRunner;
23 using TracingController = v8::TracingController;
24 
25 /**
26  * Platform interface used by Heap. Contains allocators and executors.
27  */
29  public:
30  virtual ~Platform() = default;
31 
32  /**
33  * Returns the allocator used by cppgc to allocate its heap and various
34  * support structures.
35  */
36  virtual PageAllocator* GetPageAllocator() = 0;
37 
38  /**
39  * Monotonically increasing time in seconds from an arbitrary fixed point in
40  * the past. This function is expected to return at least
41  * millisecond-precision values. For this reason,
42  * it is recommended that the fixed point be no further in the past than
43  * the epoch.
44  **/
45  virtual double MonotonicallyIncreasingTime() = 0;
46 
47  /**
48  * Foreground task runner that should be used by a Heap.
49  */
50  virtual std::shared_ptr<TaskRunner> GetForegroundTaskRunner() {
51  return nullptr;
52  }
53 
54  /**
55  * Posts `job_task` to run in parallel. Returns a `JobHandle` associated with
56  * the `Job`, which can be joined or canceled.
57  * This avoids degenerate cases:
58  * - Calling `CallOnWorkerThread()` for each work item, causing significant
59  * overhead.
60  * - Fixed number of `CallOnWorkerThread()` calls that split the work and
61  * might run for a long time. This is problematic when many components post
62  * "num cores" tasks and all expect to use all the cores. In these cases,
63  * the scheduler lacks context to be fair to multiple same-priority requests
64  * and/or ability to request lower priority work to yield when high priority
65  * work comes in.
66  * A canonical implementation of `job_task` looks like:
67  * \code
68  * class MyJobTask : public JobTask {
69  * public:
70  * MyJobTask(...) : worker_queue_(...) {}
71  * // JobTask implementation.
72  * void Run(JobDelegate* delegate) override {
73  * while (!delegate->ShouldYield()) {
74  * // Smallest unit of work.
75  * auto work_item = worker_queue_.TakeWorkItem(); // Thread safe.
76  * if (!work_item) return;
77  * ProcessWork(work_item);
78  * }
79  * }
80  *
81  * size_t GetMaxConcurrency() const override {
82  * return worker_queue_.GetSize(); // Thread safe.
83  * }
84  * };
85  *
86  * // ...
87  * auto handle = PostJob(TaskPriority::kUserVisible,
88  * std::make_unique<MyJobTask>(...));
89  * handle->Join();
90  * \endcode
91  *
92  * `PostJob()` and methods of the returned JobHandle/JobDelegate, must never
93  * be called while holding a lock that could be acquired by `JobTask::Run()`
94  * or `JobTask::GetMaxConcurrency()` -- that could result in a deadlock. This
95  * is because (1) `JobTask::GetMaxConcurrency()` may be invoked while holding
96  * internal lock (A), hence `JobTask::GetMaxConcurrency()` can only use a lock
97  * (B) if that lock is *never* held while calling back into `JobHandle` from
98  * any thread (A=>B/B=>A deadlock) and (2) `JobTask::Run()` or
99  * `JobTask::GetMaxConcurrency()` may be invoked synchronously from
100  * `JobHandle` (B=>JobHandle::foo=>B deadlock).
101  *
102  * A sufficient `PostJob()` implementation that uses the default Job provided
103  * in libplatform looks like:
104  * \code
105  * std::unique_ptr<JobHandle> PostJob(
106  * TaskPriority priority, std::unique_ptr<JobTask> job_task) override {
107  * return std::make_unique<DefaultJobHandle>(
108  * std::make_shared<DefaultJobState>(
109  * this, std::move(job_task), kNumThreads));
110  * }
111  * \endcode
112  */
113  virtual std::unique_ptr<JobHandle> PostJob(
114  TaskPriority priority, std::unique_ptr<JobTask> job_task) {
115  return nullptr;
116  }
117 
118  /**
119  * Returns an instance of a `TracingController`. This must be non-nullptr. The
120  * default implementation returns an empty `TracingController` that consumes
121  * trace data without effect.
122  */
123  virtual TracingController* GetTracingController();
124 };
125 
126 /**
127  * Process-global initialization of the garbage collector. Must be called before
128  * creating a Heap.
129  *
130  * Can be called multiple times when paired with `ShutdownProcess()`.
131  *
132  * \param page_allocator The allocator used for maintaining meta data. Must not
133  * change between multiple calls to InitializeProcess.
134  */
135 V8_EXPORT void InitializeProcess(PageAllocator* page_allocator);
136 
137 /**
138  * Must be called after destroying the last used heap. Some process-global
139  * metadata may not be returned and reused upon a subsequent
140  * `InitializeProcess()` call.
141  */
143 
144 namespace internal {
145 
146 V8_EXPORT void Abort();
147 
148 } // namespace internal
149 } // namespace cppgc
150 
151 #endif // INCLUDE_CPPGC_PLATFORM_H_
cppgc::internal::Abort
V8_EXPORT void Abort()
cppgc::InitializeProcess
V8_EXPORT void InitializeProcess(PageAllocator *page_allocator)
v8::IdleTask
Definition: v8-platform.h:58
v8::PageAllocator
Definition: v8-platform.h:376
cppgc::Platform::MonotonicallyIncreasingTime
virtual double MonotonicallyIncreasingTime()=0
cppgc::Platform::GetForegroundTaskRunner
virtual std::shared_ptr< TaskRunner > GetForegroundTaskRunner()
Definition: platform.h:50
cppgc
Definition: allocation.h:17
V8_EXPORT
#define V8_EXPORT
Definition: v8config.h:512
v8::TracingController
Definition: v8-platform.h:302
v8::JobTask
Definition: v8-platform.h:261
cppgc::Platform::GetTracingController
virtual TracingController * GetTracingController()
cppgc::ShutdownProcess
V8_EXPORT void ShutdownProcess()
v8
Definition: libplatform.h:15
cppgc::Platform::GetPageAllocator
virtual PageAllocator * GetPageAllocator()=0
v8::TaskPriority
TaskPriority
Definition: v8-platform.h:21
v8::JobHandle
Definition: v8-platform.h:193
v8::Task
Definition: v8-platform.h:45
cppgc::Platform
Definition: platform.h:28
cppgc::Platform::~Platform
virtual ~Platform()=default
v8::TaskRunner
Definition: v8-platform.h:70
cppgc::Platform::PostJob
virtual std::unique_ptr< JobHandle > PostJob(TaskPriority priority, std::unique_ptr< JobTask > job_task)
Definition: platform.h:113
cppgc::internal
Definition: allocation.h:22
v8::JobDelegate
Definition: v8-platform.h:158