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