blob: 0e03069bfd06a418caef6e26d074b3fbe5aed4e7 [file] [log] [blame]
Avi Drissman468e51b62022-09-13 20:47:011// Copyright 2014 The Chromium Authors
[email protected]b64e5212014-04-04 21:09:162// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "gin/public/v8_platform.h"
6
fdorayb87bcfb82017-05-24 17:49:407#include <algorithm>
8
[email protected]b64e5212014-04-04 21:09:169#include "base/bind.h"
Sami Kyostila2613496a2018-01-04 10:32:5710#include "base/bit_cast.h"
Hans Wennborgdcc5ada2020-04-27 13:27:2311#include "base/check_op.h"
jochen4844f72e2017-03-20 09:07:0312#include "base/debug/stack_trace.h"
[email protected]b64e5212014-04-04 21:09:1613#include "base/location.h"
Anton Bikineev8d95441b2021-10-03 12:26:2714#include "base/memory/nonscannable_memory.h"
Keishi Hattori0e45c022021-11-27 09:25:5215#include "base/memory/raw_ptr.h"
Sami Kyostila2613496a2018-01-04 10:32:5716#include "base/rand_util.h"
Sebastien Marchand75a7cdf2018-11-13 23:47:0317#include "base/system/sys_info.h"
Etienne Pierre-doray9caa721e2020-05-19 15:22:2218#include "base/task/post_job.h"
Gabriel Charette44db1422018-08-06 11:19:3319#include "base/task/task_traits.h"
Gabriel Charette99f5df32021-03-19 19:55:5520#include "base/task/thread_pool.h"
Gabriel Charetteeadf58862019-08-29 05:20:2721#include "base/task/thread_pool/thread_pool_instance.h"
tmoniuszko36416932016-01-27 16:28:4522#include "base/trace_event/trace_event.h"
Sami Kyostila88a4d552021-01-06 10:15:1923#include "base/tracing_buildflags.h"
Bill Budged1b87f02017-08-30 06:44:0824#include "build/build_config.h"
[email protected]b64e5212014-04-04 21:09:1625#include "gin/per_isolate_data.h"
André Kempe60269112021-09-17 13:14:1126#include "v8_platform_page_allocator.h"
[email protected]b64e5212014-04-04 21:09:1627
28namespace gin {
29
30namespace {
31
32base::LazyInstance<V8Platform>::Leaky g_v8_platform = LAZY_INSTANCE_INITIALIZER;
33
Andreas Haas6d4023c2019-01-18 13:16:0034constexpr base::TaskTraits kLowPriorityTaskTraits = {
Gabriel Charette8209d8442020-02-28 17:52:3535 base::TaskPriority::BEST_EFFORT};
Andreas Haas6d4023c2019-01-18 13:16:0036
Gabriel Charetteca4884b2018-05-04 17:35:0637constexpr base::TaskTraits kDefaultTaskTraits = {
Gabriel Charette8209d8442020-02-28 17:52:3538 base::TaskPriority::USER_VISIBLE};
Gabriel Charetteca4884b2018-05-04 17:35:0639
40constexpr base::TaskTraits kBlockingTaskTraits = {
Gabriel Charette8209d8442020-02-28 17:52:3541 base::TaskPriority::USER_BLOCKING};
Gabriel Charetteca4884b2018-05-04 17:35:0642
jochen4844f72e2017-03-20 09:07:0343void PrintStackTrace() {
44 base::debug::StackTrace trace;
45 trace.Print();
46}
47
Jochen Eisinger7845aae22017-06-26 15:05:4548class ConvertableToTraceFormatWrapper final
49 : public base::trace_event::ConvertableToTraceFormat {
50 public:
51 explicit ConvertableToTraceFormatWrapper(
David 'Digit' Turnerc1b9c282019-01-08 15:13:1152 std::unique_ptr<v8::ConvertableToTraceFormat> inner)
Jochen Eisinger7845aae22017-06-26 15:05:4553 : inner_(std::move(inner)) {}
Daniel Hosseinian68c0798d2021-04-16 08:16:0754 ConvertableToTraceFormatWrapper(const ConvertableToTraceFormatWrapper&) =
55 delete;
56 ConvertableToTraceFormatWrapper& operator=(
57 const ConvertableToTraceFormatWrapper&) = delete;
Jochen Eisinger7845aae22017-06-26 15:05:4558 ~ConvertableToTraceFormatWrapper() override = default;
59 void AppendAsTraceFormat(std::string* out) const final {
60 inner_->AppendAsTraceFormat(out);
61 }
62
63 private:
64 std::unique_ptr<v8::ConvertableToTraceFormat> inner_;
Jochen Eisinger7845aae22017-06-26 15:05:4565};
66
67class EnabledStateObserverImpl final
68 : public base::trace_event::TraceLog::EnabledStateObserver {
69 public:
Alexei Filippov05cd86c3c2018-09-26 02:12:1270 EnabledStateObserverImpl() {
71 base::trace_event::TraceLog::GetInstance()->AddEnabledStateObserver(this);
72 }
73
Daniel Hosseinian68c0798d2021-04-16 08:16:0774 EnabledStateObserverImpl(const EnabledStateObserverImpl&) = delete;
75
76 EnabledStateObserverImpl& operator=(const EnabledStateObserverImpl&) = delete;
77
Alexei Filippov05cd86c3c2018-09-26 02:12:1278 ~EnabledStateObserverImpl() override {
79 base::trace_event::TraceLog::GetInstance()->RemoveEnabledStateObserver(
80 this);
81 }
Jochen Eisinger7845aae22017-06-26 15:05:4582
83 void OnTraceLogEnabled() final {
84 base::AutoLock lock(mutex_);
85 for (auto* o : observers_) {
86 o->OnTraceEnabled();
87 }
88 }
89
90 void OnTraceLogDisabled() final {
91 base::AutoLock lock(mutex_);
92 for (auto* o : observers_) {
93 o->OnTraceDisabled();
94 }
95 }
96
97 void AddObserver(v8::TracingController::TraceStateObserver* observer) {
98 {
99 base::AutoLock lock(mutex_);
100 DCHECK(!observers_.count(observer));
Jochen Eisinger7845aae22017-06-26 15:05:45101 observers_.insert(observer);
102 }
Alexei Filippov05cd86c3c2018-09-26 02:12:12103
Jochen Eisinger7845aae22017-06-26 15:05:45104 // Fire the observer if recording is already in progress.
105 if (base::trace_event::TraceLog::GetInstance()->IsEnabled())
106 observer->OnTraceEnabled();
107 }
108
109 void RemoveObserver(v8::TracingController::TraceStateObserver* observer) {
110 base::AutoLock lock(mutex_);
111 DCHECK(observers_.count(observer) == 1);
112 observers_.erase(observer);
Jochen Eisinger7845aae22017-06-26 15:05:45113 }
114
115 private:
116 base::Lock mutex_;
117 std::unordered_set<v8::TracingController::TraceStateObserver*> observers_;
Jochen Eisinger7845aae22017-06-26 15:05:45118};
119
120base::LazyInstance<EnabledStateObserverImpl>::Leaky g_trace_state_dispatcher =
121 LAZY_INSTANCE_INITIALIZER;
122
Sami Kyostila2613496a2018-01-04 10:32:57123// TODO(skyostil): Deduplicate this with the clamper in Blink.
124class TimeClamper {
125 public:
Sami Kyostila1cf07352018-10-22 12:16:25126// As site isolation is enabled on desktop platforms, we can safely provide
127// more timing resolution. Jittering is still enabled everywhere.
Xiaohan Wangc696a4742022-01-08 01:20:46128#if BUILDFLAG(IS_ANDROID)
Sami Kyostila1cf07352018-10-22 12:16:25129 static constexpr double kResolutionSeconds = 100e-6;
130#else
131 static constexpr double kResolutionSeconds = 5e-6;
132#endif
Sami Kyostila2613496a2018-01-04 10:32:57133
134 TimeClamper() : secret_(base::RandUint64()) {}
Daniel Hosseinian68c0798d2021-04-16 08:16:07135 TimeClamper(const TimeClamper&) = delete;
136 TimeClamper& operator=(const TimeClamper&) = delete;
Sami Kyostila2613496a2018-01-04 10:32:57137
138 double ClampTimeResolution(double time_seconds) const {
Kenneth Russell0ebb714c2018-07-20 22:03:35139 bool was_negative = false;
140 if (time_seconds < 0) {
141 was_negative = true;
142 time_seconds = -time_seconds;
143 }
Sami Kyostila2613496a2018-01-04 10:32:57144 // For each clamped time interval, compute a pseudorandom transition
145 // threshold. The reported time will either be the start of that interval or
146 // the next one depending on which side of the threshold |time_seconds| is.
Sami Kyostila874bac6e2018-01-16 12:23:57147 double interval = floor(time_seconds / kResolutionSeconds);
148 double clamped_time = interval * kResolutionSeconds;
Sami Kyostila2613496a2018-01-04 10:32:57149 double tick_threshold = ThresholdFor(clamped_time);
150
151 if (time_seconds >= tick_threshold)
Kenneth Russell0ebb714c2018-07-20 22:03:35152 clamped_time = (interval + 1) * kResolutionSeconds;
153 if (was_negative)
154 clamped_time = -clamped_time;
Sami Kyostila2613496a2018-01-04 10:32:57155 return clamped_time;
156 }
157
158 private:
159 inline double ThresholdFor(double clamped_time) const {
Peter Kastingcc88ac052022-05-03 09:58:01160 uint64_t time_hash =
161 MurmurHash3(base::bit_cast<int64_t>(clamped_time) ^ secret_);
Sami Kyostila2613496a2018-01-04 10:32:57162 return clamped_time + kResolutionSeconds * ToDouble(time_hash);
163 }
164
165 static inline double ToDouble(uint64_t value) {
166 // Exponent for double values for [1.0 .. 2.0]
167 static const uint64_t kExponentBits = uint64_t{0x3FF0000000000000};
168 static const uint64_t kMantissaMask = uint64_t{0x000FFFFFFFFFFFFF};
169 uint64_t random = (value & kMantissaMask) | kExponentBits;
Peter Kastingcc88ac052022-05-03 09:58:01170 return base::bit_cast<double>(random) - 1;
Sami Kyostila2613496a2018-01-04 10:32:57171 }
172
173 static inline uint64_t MurmurHash3(uint64_t value) {
174 value ^= value >> 33;
175 value *= uint64_t{0xFF51AFD7ED558CCD};
176 value ^= value >> 33;
177 value *= uint64_t{0xC4CEB9FE1A85EC53};
178 value ^= value >> 33;
179 return value;
180 }
181
182 const uint64_t secret_;
Sami Kyostila2613496a2018-01-04 10:32:57183};
184
185base::LazyInstance<TimeClamper>::Leaky g_time_clamper =
186 LAZY_INSTANCE_INITIALIZER;
187
Bill Budge24b75fd2018-02-02 01:45:20188#if BUILDFLAG(USE_PARTITION_ALLOC)
Bill Budge24b75fd2018-02-02 01:45:20189
André Kempe60269112021-09-17 13:14:11190base::LazyInstance<gin::PageAllocator>::Leaky g_page_allocator =
Bill Budge24b75fd2018-02-02 01:45:20191 LAZY_INSTANCE_INITIALIZER;
192
193#endif // BUILDFLAG(USE_PARTITION_ALLOC)
194
Etienne Pierre-doray9caa721e2020-05-19 15:22:22195class JobDelegateImpl : public v8::JobDelegate {
196 public:
197 explicit JobDelegateImpl(base::JobDelegate* delegate) : delegate_(delegate) {}
198 JobDelegateImpl() = default;
199
200 JobDelegateImpl(const JobDelegateImpl&) = delete;
201 JobDelegateImpl& operator=(const JobDelegateImpl&) = delete;
202
203 // v8::JobDelegate:
204 bool ShouldYield() override { return delegate_->ShouldYield(); }
205 void NotifyConcurrencyIncrease() override {
206 delegate_->NotifyConcurrencyIncrease();
207 }
Etienne Pierre-doraydf067352020-08-17 15:50:26208 uint8_t GetTaskId() override { return delegate_->GetTaskId(); }
Etienne Pierre-doraybcff179ae2020-09-22 14:53:53209 bool IsJoiningThread() const override { return delegate_->IsJoiningThread(); }
Etienne Pierre-doray9caa721e2020-05-19 15:22:22210
211 private:
Keishi Hattori0e45c022021-11-27 09:25:52212 raw_ptr<base::JobDelegate> delegate_;
Etienne Pierre-doray9caa721e2020-05-19 15:22:22213};
214
215class JobHandleImpl : public v8::JobHandle {
216 public:
Etienne Pierre-doray2e0c74cf2020-12-03 15:17:18217 explicit JobHandleImpl(base::JobHandle handle) : handle_(std::move(handle)) {}
Etienne Pierre-doray9caa721e2020-05-19 15:22:22218 ~JobHandleImpl() override = default;
219
220 JobHandleImpl(const JobHandleImpl&) = delete;
221 JobHandleImpl& operator=(const JobHandleImpl&) = delete;
222
223 // v8::JobHandle:
224 void NotifyConcurrencyIncrease() override {
225 handle_.NotifyConcurrencyIncrease();
226 }
Etienne Pierre-doray13073462020-11-03 18:51:11227 bool UpdatePriorityEnabled() const override { return true; }
228 void UpdatePriority(v8::TaskPriority new_priority) override {
229 handle_.UpdatePriority(ToBaseTaskPriority(new_priority));
230 }
Etienne Pierre-doray9caa721e2020-05-19 15:22:22231 void Join() override { handle_.Join(); }
232 void Cancel() override { handle_.Cancel(); }
Etienne Pierre-dorayc72968a02020-10-08 13:28:02233 void CancelAndDetach() override { handle_.CancelAndDetach(); }
Etienne Pierre-doray4fea66bd2020-11-30 23:20:12234 bool IsActive() override { return handle_.IsActive(); }
235 bool IsValid() override { return !!handle_; }
236
Etienne Pierre-doray9caa721e2020-05-19 15:22:22237 private:
Etienne Pierre-doray13073462020-11-03 18:51:11238 static base::TaskPriority ToBaseTaskPriority(v8::TaskPriority priority) {
239 switch (priority) {
240 case v8::TaskPriority::kBestEffort:
241 return base::TaskPriority::BEST_EFFORT;
242 case v8::TaskPriority::kUserVisible:
243 return base::TaskPriority::USER_VISIBLE;
244 case v8::TaskPriority::kUserBlocking:
245 return base::TaskPriority::USER_BLOCKING;
246 }
247 }
248
Etienne Pierre-doray9caa721e2020-05-19 15:22:22249 base::JobHandle handle_;
Etienne Pierre-doray9caa721e2020-05-19 15:22:22250};
251
[email protected]b64e5212014-04-04 21:09:16252} // namespace
253
David 'Digit' Turnerc1b9c282019-01-08 15:13:11254} // namespace gin
255
256// Allow std::unique_ptr<v8::ConvertableToTraceFormat> to be a valid
257// initialization value for trace macros.
258template <>
259struct base::trace_event::TraceValue::Helper<
260 std::unique_ptr<v8::ConvertableToTraceFormat>> {
261 static constexpr unsigned char kType = TRACE_VALUE_TYPE_CONVERTABLE;
262 static inline void SetValue(
263 TraceValue* v,
264 std::unique_ptr<v8::ConvertableToTraceFormat> value) {
265 // NOTE: |as_convertable| is an owning pointer, so using new here
266 // is acceptable.
267 v->as_convertable =
268 new gin::ConvertableToTraceFormatWrapper(std::move(value));
269 }
270};
271
272namespace gin {
273
Jochen Eisinger7845aae22017-06-26 15:05:45274class V8Platform::TracingControllerImpl : public v8::TracingController {
275 public:
276 TracingControllerImpl() = default;
Daniel Hosseinian68c0798d2021-04-16 08:16:07277 TracingControllerImpl(const TracingControllerImpl&) = delete;
278 TracingControllerImpl& operator=(const TracingControllerImpl&) = delete;
Jochen Eisinger7845aae22017-06-26 15:05:45279 ~TracingControllerImpl() override = default;
280
281 // TracingController implementation.
Sami Kyostila88a4d552021-01-06 10:15:19282#if !BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
Jochen Eisinger7845aae22017-06-26 15:05:45283 const uint8_t* GetCategoryGroupEnabled(const char* name) override {
284 return TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(name);
285 }
286 uint64_t AddTraceEvent(
287 char phase,
288 const uint8_t* category_enabled_flag,
289 const char* name,
290 const char* scope,
291 uint64_t id,
292 uint64_t bind_id,
293 int32_t num_args,
294 const char** arg_names,
295 const uint8_t* arg_types,
296 const uint64_t* arg_values,
297 std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables,
298 unsigned int flags) override {
David 'Digit' Turnerc1b9c282019-01-08 15:13:11299 base::trace_event::TraceArguments args(
300 num_args, arg_names, arg_types,
301 reinterpret_cast<const unsigned long long*>(arg_values),
302 arg_convertables);
Jochen Eisinger7845aae22017-06-26 15:05:45303 DCHECK_LE(num_args, 2);
304 base::trace_event::TraceEventHandle handle =
305 TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_BIND_ID(
David 'Digit' Turnerc1b9c282019-01-08 15:13:11306 phase, category_enabled_flag, name, scope, id, bind_id, &args,
307 flags);
Jochen Eisinger7845aae22017-06-26 15:05:45308 uint64_t result;
309 memcpy(&result, &handle, sizeof(result));
310 return result;
311 }
Sajal Khandelwal56c29312019-04-24 21:40:33312 uint64_t AddTraceEventWithTimestamp(
313 char phase,
314 const uint8_t* category_enabled_flag,
315 const char* name,
316 const char* scope,
317 uint64_t id,
318 uint64_t bind_id,
319 int32_t num_args,
320 const char** arg_names,
321 const uint8_t* arg_types,
322 const uint64_t* arg_values,
323 std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables,
324 unsigned int flags,
325 int64_t timestampMicroseconds) override {
326 base::trace_event::TraceArguments args(
327 num_args, arg_names, arg_types,
328 reinterpret_cast<const unsigned long long*>(arg_values),
329 arg_convertables);
330 DCHECK_LE(num_args, 2);
331 base::TimeTicks timestamp =
Peter Kastinge5a38ed2021-10-02 03:06:35332 base::TimeTicks() + base::Microseconds(timestampMicroseconds);
Sajal Khandelwal56c29312019-04-24 21:40:33333 base::trace_event::TraceEventHandle handle =
334 TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP(
335 phase, category_enabled_flag, name, scope, id, bind_id,
336 TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, &args, flags);
337 uint64_t result;
338 memcpy(&result, &handle, sizeof(result));
339 return result;
340 }
Jochen Eisinger7845aae22017-06-26 15:05:45341 void UpdateTraceEventDuration(const uint8_t* category_enabled_flag,
342 const char* name,
343 uint64_t handle) override {
344 base::trace_event::TraceEventHandle traceEventHandle;
345 memcpy(&traceEventHandle, &handle, sizeof(handle));
346 TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(category_enabled_flag, name,
347 traceEventHandle);
348 }
Sami Kyostila88a4d552021-01-06 10:15:19349#endif // !BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
Jochen Eisinger7845aae22017-06-26 15:05:45350 void AddTraceStateObserver(TraceStateObserver* observer) override {
351 g_trace_state_dispatcher.Get().AddObserver(observer);
352 }
353 void RemoveTraceStateObserver(TraceStateObserver* observer) override {
354 g_trace_state_dispatcher.Get().RemoveObserver(observer);
355 }
Jochen Eisinger7845aae22017-06-26 15:05:45356};
357
[email protected]b64e5212014-04-04 21:09:16358// static
359V8Platform* V8Platform::Get() { return g_v8_platform.Pointer(); }
360
Jochen Eisinger7845aae22017-06-26 15:05:45361V8Platform::V8Platform() : tracing_controller_(new TracingControllerImpl) {}
[email protected]b64e5212014-04-04 21:09:16362
Chris Watkins756035a2017-12-01 03:03:27363V8Platform::~V8Platform() = default;
[email protected]b64e5212014-04-04 21:09:16364
Bill Budge24b75fd2018-02-02 01:45:20365#if BUILDFLAG(USE_PARTITION_ALLOC)
André Kempe60269112021-09-17 13:14:11366PageAllocator* V8Platform::GetPageAllocator() {
Bill Budge24b75fd2018-02-02 01:45:20367 return g_page_allocator.Pointer();
368}
369
Bill Budged1b87f02017-08-30 06:44:08370void V8Platform::OnCriticalMemoryPressure() {
Bill Budge24b75fd2018-02-02 01:45:20371// We only have a reservation on 32-bit Windows systems.
372// TODO(bbudge) Make the #if's in BlinkInitializer match.
Xiaohan Wangc696a4742022-01-08 01:20:46373#if BUILDFLAG(IS_WIN) && defined(ARCH_CPU_32_BITS)
Kalvin Leecb9c00c22022-07-12 05:18:35374 partition_alloc::ReleaseReservation();
Bill Budged1b87f02017-08-30 06:44:08375#endif
376}
Anton Bikineev8d95441b2021-10-03 12:26:27377
378v8::ZoneBackingAllocator* V8Platform::GetZoneBackingAllocator() {
379 static struct Allocator final : v8::ZoneBackingAllocator {
380 MallocFn GetMallocFn() const override {
381 return &base::AllocNonQuarantinable;
382 }
383 FreeFn GetFreeFn() const override { return &base::FreeNonQuarantinable; }
384 } allocator;
385 return &allocator;
386}
Bill Budge24b75fd2018-02-02 01:45:20387#endif // BUILDFLAG(USE_PARTITION_ALLOC)
Bill Budged1b87f02017-08-30 06:44:08388
Andreas Haasc13cae82017-11-16 12:54:38389std::shared_ptr<v8::TaskRunner> V8Platform::GetForegroundTaskRunner(
390 v8::Isolate* isolate) {
391 PerIsolateData* data = PerIsolateData::From(isolate);
392 return data->task_runner();
393}
394
Gabriel Charetteca4884b2018-05-04 17:35:06395int V8Platform::NumberOfWorkerThreads() {
396 // V8Platform assumes the scheduler uses the same set of workers for default
397 // and user blocking tasks.
Peter Kasting12bf3302022-06-07 19:52:07398 const size_t num_foreground_workers =
Gabriel Charette43fd3702019-05-29 16:36:51399 base::ThreadPoolInstance::Get()
Gabriel Charetteca4884b2018-05-04 17:35:06400 ->GetMaxConcurrentNonBlockedTasksWithTraitsDeprecated(
401 kDefaultTaskTraits);
402 DCHECK_EQ(num_foreground_workers,
Gabriel Charette43fd3702019-05-29 16:36:51403 base::ThreadPoolInstance::Get()
Gabriel Charetteca4884b2018-05-04 17:35:06404 ->GetMaxConcurrentNonBlockedTasksWithTraitsDeprecated(
405 kBlockingTaskTraits));
Peter Kasting12bf3302022-06-07 19:52:07406 return std::max(1, static_cast<int>(num_foreground_workers));
Andreas Haasc13cae82017-11-16 12:54:38407}
408
Gabriel Charetteca4884b2018-05-04 17:35:06409void V8Platform::CallOnWorkerThread(std::unique_ptr<v8::Task> task) {
Gabriel Charette8209d8442020-02-28 17:52:35410 base::ThreadPool::PostTask(FROM_HERE, kDefaultTaskTraits,
411 base::BindOnce(&v8::Task::Run, std::move(task)));
mlippautz40dfecc92016-03-07 21:06:50412}
413
Gabriel Charetteca4884b2018-05-04 17:35:06414void V8Platform::CallBlockingTaskOnWorkerThread(
415 std::unique_ptr<v8::Task> task) {
Gabriel Charette8209d8442020-02-28 17:52:35416 base::ThreadPool::PostTask(FROM_HERE, kBlockingTaskTraits,
417 base::BindOnce(&v8::Task::Run, std::move(task)));
Gabriel Charetteca4884b2018-05-04 17:35:06418}
419
Andreas Haas6d4023c2019-01-18 13:16:00420void V8Platform::CallLowPriorityTaskOnWorkerThread(
421 std::unique_ptr<v8::Task> task) {
Gabriel Charette8209d8442020-02-28 17:52:35422 base::ThreadPool::PostTask(FROM_HERE, kLowPriorityTaskTraits,
423 base::BindOnce(&v8::Task::Run, std::move(task)));
Andreas Haas6d4023c2019-01-18 13:16:00424}
425
Gabriel Charetteca4884b2018-05-04 17:35:06426void V8Platform::CallDelayedOnWorkerThread(std::unique_ptr<v8::Task> task,
427 double delay_in_seconds) {
Gabriel Charette8209d8442020-02-28 17:52:35428 base::ThreadPool::PostDelayedTask(
429 FROM_HERE, kDefaultTaskTraits,
430 base::BindOnce(&v8::Task::Run, std::move(task)),
Peter Kastinge5a38ed2021-10-02 03:06:35431 base::Seconds(delay_in_seconds));
[email protected]b64e5212014-04-04 21:09:16432}
433
Etienne Pierre-doray3a94d642022-06-21 17:35:53434std::unique_ptr<v8::JobHandle> V8Platform::CreateJob(
Etienne Pierre-doray9caa721e2020-05-19 15:22:22435 v8::TaskPriority priority,
436 std::unique_ptr<v8::JobTask> job_task) {
437 base::TaskTraits task_traits;
438 switch (priority) {
439 case v8::TaskPriority::kBestEffort:
440 task_traits = kLowPriorityTaskTraits;
441 break;
442 case v8::TaskPriority::kUserVisible:
443 task_traits = kDefaultTaskTraits;
444 break;
445 case v8::TaskPriority::kUserBlocking:
446 task_traits = kBlockingTaskTraits;
447 break;
448 }
Etienne Pierre-doray2e0c74cf2020-12-03 15:17:18449 // Ownership of |job_task| is assumed by |worker_task|, while
450 // |max_concurrency_callback| uses an unretained pointer.
451 auto* job_task_ptr = job_task.get();
Etienne Pierre-doray2f52b3512020-08-12 19:04:29452 auto handle =
Etienne Pierre-doray3a94d642022-06-21 17:35:53453 base::CreateJob(FROM_HERE, task_traits,
454 base::BindRepeating(
455 [](const std::unique_ptr<v8::JobTask>& job_task,
456 base::JobDelegate* delegate) {
457 JobDelegateImpl delegate_impl(delegate);
458 job_task->Run(&delegate_impl);
459 },
460 std::move(job_task)),
461 base::BindRepeating(
462 [](v8::JobTask* job_task, size_t worker_count) {
463 return job_task->GetMaxConcurrency(worker_count);
464 },
465 base::Unretained(job_task_ptr)));
Etienne Pierre-doray9caa721e2020-05-19 15:22:22466
Etienne Pierre-doray2e0c74cf2020-12-03 15:17:18467 return std::make_unique<JobHandleImpl>(std::move(handle));
Etienne Pierre-doray9caa721e2020-05-19 15:22:22468}
469
ulan3cbdcd02015-07-20 11:32:58470bool V8Platform::IdleTasksEnabled(v8::Isolate* isolate) {
Andreas Haasc13cae82017-11-16 12:54:38471 return PerIsolateData::From(isolate)->task_runner()->IdleTasksEnabled();
ulan3cbdcd02015-07-20 11:32:58472}
473
rmcilroy05d26622014-10-08 11:28:05474double V8Platform::MonotonicallyIncreasingTime() {
475 return base::TimeTicks::Now().ToInternalValue() /
476 static_cast<double>(base::Time::kMicrosecondsPerSecond);
477}
478
Sergei Dcdd78f72017-08-22 01:45:25479double V8Platform::CurrentClockTimeMillis() {
Sami Kyostila2613496a2018-01-04 10:32:57480 double now_seconds = base::Time::Now().ToJsTime() / 1000;
481 return g_time_clamper.Get().ClampTimeResolution(now_seconds) * 1000;
Sergei Dcdd78f72017-08-22 01:45:25482}
483
Jochen Eisinger7845aae22017-06-26 15:05:45484v8::TracingController* V8Platform::GetTracingController() {
485 return tracing_controller_.get();
486}
487
jochen4844f72e2017-03-20 09:07:03488v8::Platform::StackTracePrinter V8Platform::GetStackTracePrinter() {
489 return PrintStackTrace;
490}
491
[email protected]b64e5212014-04-04 21:09:16492} // namespace gin