5 #include "src/libplatform/default-platform.h" 10 #include "include/libplatform/libplatform.h" 11 #include "src/base/debug/stack_trace.h" 12 #include "src/base/logging.h" 13 #include "src/base/page-allocator.h" 14 #include "src/base/platform/platform.h" 15 #include "src/base/platform/time.h" 16 #include "src/base/sys-info.h" 17 #include "src/libplatform/default-foreground-task-runner.h" 18 #include "src/libplatform/default-worker-threads-task-runner.h" 25 void PrintStackTrace() {
29 v8::base::debug::DisableSignalStackDump();
34 std::unique_ptr<v8::Platform> NewDefaultPlatform(
35 int thread_pool_size, IdleTaskSupport idle_task_support,
36 InProcessStackDumping in_process_stack_dumping,
37 std::unique_ptr<v8::TracingController> tracing_controller) {
38 if (in_process_stack_dumping == InProcessStackDumping::kEnabled) {
39 v8::base::debug::EnableInProcessStackDumping();
41 std::unique_ptr<DefaultPlatform> platform(
42 new DefaultPlatform(idle_task_support, std::move(tracing_controller)));
43 platform->SetThreadPoolSize(thread_pool_size);
44 platform->EnsureBackgroundTaskRunnerInitialized();
45 return std::move(platform);
49 int thread_pool_size, IdleTaskSupport idle_task_support,
50 InProcessStackDumping in_process_stack_dumping,
52 return NewDefaultPlatform(
53 thread_pool_size, idle_task_support, in_process_stack_dumping,
54 std::unique_ptr<v8::TracingController>(tracing_controller))
58 bool PumpMessageLoop(
v8::Platform* platform, v8::Isolate* isolate,
59 MessageLoopBehavior behavior) {
60 return static_cast<DefaultPlatform*
>(platform)->PumpMessageLoop(isolate,
64 void RunIdleTasks(
v8::Platform* platform, v8::Isolate* isolate,
65 double idle_time_in_seconds) {
66 static_cast<DefaultPlatform*
>(platform)->RunIdleTasks(isolate,
67 idle_time_in_seconds);
70 void SetTracingController(
73 static_cast<DefaultPlatform*
>(platform)->SetTracingController(
74 std::unique_ptr<v8::TracingController>(tracing_controller));
77 const int DefaultPlatform::kMaxThreadPoolSize = 8;
79 DefaultPlatform::DefaultPlatform(
80 IdleTaskSupport idle_task_support,
81 std::unique_ptr<v8::TracingController> tracing_controller)
82 : thread_pool_size_(0),
83 idle_task_support_(idle_task_support),
84 tracing_controller_(
std::move(tracing_controller)),
85 page_allocator_(new
v8::base::PageAllocator()),
86 time_function_for_testing_(nullptr) {
87 if (!tracing_controller_) {
88 tracing::TracingController* controller =
new tracing::TracingController();
89 controller->Initialize(
nullptr);
90 tracing_controller_.reset(controller);
94 DefaultPlatform::~DefaultPlatform() {
95 base::MutexGuard guard(&lock_);
96 if (worker_threads_task_runner_) worker_threads_task_runner_->Terminate();
97 for (
auto it : foreground_task_runner_map_) {
98 it.second->Terminate();
102 void DefaultPlatform::SetThreadPoolSize(
int thread_pool_size) {
103 base::MutexGuard guard(&lock_);
104 DCHECK_GE(thread_pool_size, 0);
105 if (thread_pool_size < 1) {
106 thread_pool_size = base::SysInfo::NumberOfProcessors() - 1;
109 std::max(std::min(thread_pool_size, kMaxThreadPoolSize), 1);
112 void DefaultPlatform::EnsureBackgroundTaskRunnerInitialized() {
113 base::MutexGuard guard(&lock_);
114 if (!worker_threads_task_runner_) {
115 worker_threads_task_runner_ =
116 std::make_shared<DefaultWorkerThreadsTaskRunner>(thread_pool_size_);
122 double DefaultTimeFunction() {
123 return base::TimeTicks::HighResolutionNow().ToInternalValue() /
124 static_cast<double>(base::Time::kMicrosecondsPerSecond);
129 void DefaultPlatform::SetTimeFunctionForTesting(
130 DefaultPlatform::TimeFunction time_function) {
131 base::MutexGuard guard(&lock_);
132 time_function_for_testing_ = time_function;
134 DCHECK(foreground_task_runner_map_.empty());
137 bool DefaultPlatform::PumpMessageLoop(v8::Isolate* isolate,
138 MessageLoopBehavior wait_for_work) {
139 bool failed_result = wait_for_work == MessageLoopBehavior::kWaitForWork;
140 std::shared_ptr<DefaultForegroundTaskRunner> task_runner;
142 base::MutexGuard guard(&lock_);
143 auto it = foreground_task_runner_map_.find(isolate);
144 if (it == foreground_task_runner_map_.end())
return failed_result;
145 task_runner = it->second;
148 std::unique_ptr<Task> task = task_runner->PopTaskFromQueue(wait_for_work);
149 if (!task)
return failed_result;
155 void DefaultPlatform::RunIdleTasks(v8::Isolate* isolate,
156 double idle_time_in_seconds) {
157 DCHECK_EQ(IdleTaskSupport::kEnabled, idle_task_support_);
158 std::shared_ptr<DefaultForegroundTaskRunner> task_runner;
160 base::MutexGuard guard(&lock_);
161 if (foreground_task_runner_map_.find(isolate) ==
162 foreground_task_runner_map_.end()) {
165 task_runner = foreground_task_runner_map_[isolate];
167 double deadline_in_seconds =
168 MonotonicallyIncreasingTime() + idle_time_in_seconds;
170 while (deadline_in_seconds > MonotonicallyIncreasingTime()) {
171 std::unique_ptr<IdleTask> task = task_runner->PopTaskFromIdleQueue();
173 task->Run(deadline_in_seconds);
177 std::shared_ptr<TaskRunner> DefaultPlatform::GetForegroundTaskRunner(
178 v8::Isolate* isolate) {
179 base::MutexGuard guard(&lock_);
180 if (foreground_task_runner_map_.find(isolate) ==
181 foreground_task_runner_map_.end()) {
182 foreground_task_runner_map_.insert(std::make_pair(
183 isolate, std::make_shared<DefaultForegroundTaskRunner>(
184 idle_task_support_, time_function_for_testing_
185 ? time_function_for_testing_
186 : DefaultTimeFunction)));
188 return foreground_task_runner_map_[isolate];
191 void DefaultPlatform::CallOnWorkerThread(std::unique_ptr<Task> task) {
192 EnsureBackgroundTaskRunnerInitialized();
193 worker_threads_task_runner_->PostTask(std::move(task));
196 void DefaultPlatform::CallDelayedOnWorkerThread(std::unique_ptr<Task> task,
197 double delay_in_seconds) {
198 EnsureBackgroundTaskRunnerInitialized();
199 worker_threads_task_runner_->PostDelayedTask(std::move(task),
203 void DefaultPlatform::CallOnForegroundThread(v8::Isolate* isolate, Task* task) {
204 GetForegroundTaskRunner(isolate)->PostTask(std::unique_ptr<Task>(task));
207 void DefaultPlatform::CallDelayedOnForegroundThread(Isolate* isolate,
209 double delay_in_seconds) {
210 GetForegroundTaskRunner(isolate)->PostDelayedTask(std::unique_ptr<Task>(task),
214 void DefaultPlatform::CallIdleOnForegroundThread(Isolate* isolate,
216 GetForegroundTaskRunner(isolate)->PostIdleTask(
217 std::unique_ptr<IdleTask>(task));
220 bool DefaultPlatform::IdleTasksEnabled(Isolate* isolate) {
221 return idle_task_support_ == IdleTaskSupport::kEnabled;
224 double DefaultPlatform::MonotonicallyIncreasingTime() {
225 if (time_function_for_testing_)
return time_function_for_testing_();
226 return DefaultTimeFunction();
229 double DefaultPlatform::CurrentClockTimeMillis() {
230 return base::OS::TimeCurrentMillis();
233 TracingController* DefaultPlatform::GetTracingController() {
234 return tracing_controller_.get();
237 void DefaultPlatform::SetTracingController(
238 std::unique_ptr<v8::TracingController> tracing_controller) {
239 DCHECK_NOT_NULL(tracing_controller.get());
240 tracing_controller_ = std::move(tracing_controller);
243 int DefaultPlatform::NumberOfWorkerThreads() {
return thread_pool_size_; }
245 Platform::StackTracePrinter DefaultPlatform::GetStackTracePrinter() {
246 return PrintStackTrace;
250 return page_allocator_.get();