v8  8.6.395 (node 15.0.1)
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 
24 /**
25  * Platform interface used by Heap. Contains allocators and executors.
26  */
28  public:
29  virtual ~Platform() = default;
30 
31  /**
32  * Returns the allocator used by cppgc to allocate its heap and various
33  * support structures.
34  */
35  virtual PageAllocator* GetPageAllocator() = 0;
36 
37  /**
38  * Monotonically increasing time in seconds from an arbitrary fixed point in
39  * the past. This function is expected to return at least
40  * millisecond-precision values. For this reason,
41  * it is recommended that the fixed point be no further in the past than
42  * the epoch.
43  **/
44  virtual double MonotonicallyIncreasingTime() = 0;
45 
46  /**
47  * Foreground task runner that should be used by a Heap.
48  */
49  virtual std::shared_ptr<TaskRunner> GetForegroundTaskRunner() {
50  return nullptr;
51  }
52 
53  /**
54  * Posts |job_task| to run in parallel. Returns a JobHandle associated with
55  * the Job, which can be joined or canceled.
56  * This avoids degenerate cases:
57  * - Calling CallOnWorkerThread() for each work item, causing significant
58  * overhead.
59  * - Fixed number of CallOnWorkerThread() calls that split the work and might
60  * run for a long time. This is problematic when many components post
61  * "num cores" tasks and all expect to use all the cores. In these cases,
62  * the scheduler lacks context to be fair to multiple same-priority requests
63  * and/or ability to request lower priority work to yield when high priority
64  * work comes in.
65  * A canonical implementation of |job_task| looks like:
66  * class MyJobTask : public JobTask {
67  * public:
68  * MyJobTask(...) : worker_queue_(...) {}
69  * // JobTask:
70  * void Run(JobDelegate* delegate) override {
71  * while (!delegate->ShouldYield()) {
72  * // Smallest unit of work.
73  * auto work_item = worker_queue_.TakeWorkItem(); // Thread safe.
74  * if (!work_item) return;
75  * ProcessWork(work_item);
76  * }
77  * }
78  *
79  * size_t GetMaxConcurrency() const override {
80  * return worker_queue_.GetSize(); // Thread safe.
81  * }
82  * };
83  * auto handle = PostJob(TaskPriority::kUserVisible,
84  * std::make_unique<MyJobTask>(...));
85  * handle->Join();
86  *
87  * PostJob() and methods of the returned JobHandle/JobDelegate, must never be
88  * called while holding a lock that could be acquired by JobTask::Run or
89  * JobTask::GetMaxConcurrency -- that could result in a deadlock. This is
90  * because [1] JobTask::GetMaxConcurrency may be invoked while holding
91  * internal lock (A), hence JobTask::GetMaxConcurrency can only use a lock (B)
92  * if that lock is *never* held while calling back into JobHandle from any
93  * thread (A=>B/B=>A deadlock) and [2] JobTask::Run or
94  * JobTask::GetMaxConcurrency may be invoked synchronously from JobHandle
95  * (B=>JobHandle::foo=>B deadlock).
96  *
97  * A sufficient PostJob() implementation that uses the default Job provided in
98  * libplatform looks like:
99  * std::unique_ptr<JobHandle> PostJob(
100  * TaskPriority priority, std::unique_ptr<JobTask> job_task) override {
101  * return std::make_unique<DefaultJobHandle>(
102  * std::make_shared<DefaultJobState>(
103  * this, std::move(job_task), kNumThreads));
104  * }
105  */
106  virtual std::unique_ptr<JobHandle> PostJob(
107  TaskPriority priority, std::unique_ptr<JobTask> job_task) {
108  return nullptr;
109  }
110 };
111 
112 /**
113  * Process-global initialization of the garbage collector. Must be called before
114  * creating a Heap.
115  */
116 V8_EXPORT void InitializeProcess(PageAllocator*);
117 
118 /**
119  * Must be called after destroying the last used heap.
120  */
122 
123 namespace internal {
124 
126 
127 } // namespace internal
128 } // namespace cppgc
129 
130 #endif // INCLUDE_CPPGC_PLATFORM_H_