LCOV - code coverage report
Current view: top level - src/libplatform - default-platform.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 101 108 93.5 %
Date: 2019-02-19 Functions: 26 28 92.9 %

          Line data    Source code
       1             : // Copyright 2013 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             : #include "src/libplatform/default-platform.h"
       6             : 
       7             : #include <algorithm>
       8             : #include <queue>
       9             : 
      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"
      19             : 
      20             : namespace v8 {
      21             : namespace platform {
      22             : 
      23             : namespace {
      24             : 
      25           0 : void PrintStackTrace() {
      26           0 :   v8::base::debug::StackTrace trace;
      27           0 :   trace.Print();
      28             :   // Avoid dumping duplicate stack trace on abort signal.
      29           0 :   v8::base::debug::DisableSignalStackDump();
      30           0 : }
      31             : 
      32             : }  // namespace
      33             : 
      34       59608 : 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       59608 :   if (in_process_stack_dumping == InProcessStackDumping::kEnabled) {
      39       29536 :     v8::base::debug::EnableInProcessStackDumping();
      40             :   }
      41             :   std::unique_ptr<DefaultPlatform> platform(
      42      119216 :       new DefaultPlatform(idle_task_support, std::move(tracing_controller)));
      43       59608 :   platform->SetThreadPoolSize(thread_pool_size);
      44       59608 :   platform->EnsureBackgroundTaskRunnerInitialized();
      45       59608 :   return std::move(platform);
      46             : }
      47             : 
      48      244470 : bool PumpMessageLoop(v8::Platform* platform, v8::Isolate* isolate,
      49             :                      MessageLoopBehavior behavior) {
      50             :   return static_cast<DefaultPlatform*>(platform)->PumpMessageLoop(isolate,
      51      244470 :                                                                   behavior);
      52             : }
      53             : 
      54      159240 : void RunIdleTasks(v8::Platform* platform, v8::Isolate* isolate,
      55             :                   double idle_time_in_seconds) {
      56             :   static_cast<DefaultPlatform*>(platform)->RunIdleTasks(isolate,
      57      159240 :                                                         idle_time_in_seconds);
      58      159240 : }
      59             : 
      60           0 : void SetTracingController(
      61             :     v8::Platform* platform,
      62             :     v8::platform::tracing::TracingController* tracing_controller) {
      63             :   static_cast<DefaultPlatform*>(platform)->SetTracingController(
      64             :       std::unique_ptr<v8::TracingController>(tracing_controller));
      65           0 : }
      66             : 
      67             : const int DefaultPlatform::kMaxThreadPoolSize = 8;
      68             : 
      69       59619 : DefaultPlatform::DefaultPlatform(
      70             :     IdleTaskSupport idle_task_support,
      71             :     std::unique_ptr<v8::TracingController> tracing_controller)
      72             :     : thread_pool_size_(0),
      73             :       idle_task_support_(idle_task_support),
      74             :       tracing_controller_(std::move(tracing_controller)),
      75             :       page_allocator_(new v8::base::PageAllocator()),
      76      178857 :       time_function_for_testing_(nullptr) {
      77       59619 :   if (!tracing_controller_) {
      78       59618 :     tracing::TracingController* controller = new tracing::TracingController();
      79       59618 :     controller->Initialize(nullptr);
      80             :     tracing_controller_.reset(controller);
      81             :   }
      82       59619 : }
      83             : 
      84      169720 : DefaultPlatform::~DefaultPlatform() {
      85       56577 :   base::MutexGuard guard(&lock_);
      86       56577 :   if (worker_threads_task_runner_) worker_threads_task_runner_->Terminate();
      87      172260 :   for (auto it : foreground_task_runner_map_) {
      88       59106 :     it.second->Terminate();
      89             :   }
      90      113143 : }
      91             : 
      92       59610 : void DefaultPlatform::SetThreadPoolSize(int thread_pool_size) {
      93       59610 :   base::MutexGuard guard(&lock_);
      94             :   DCHECK_GE(thread_pool_size, 0);
      95       59610 :   if (thread_pool_size < 1) {
      96       59608 :     thread_pool_size = base::SysInfo::NumberOfProcessors() - 1;
      97             :   }
      98             :   thread_pool_size_ =
      99      119220 :       std::max(std::min(thread_pool_size, kMaxThreadPoolSize), 1);
     100       59610 : }
     101             : 
     102     1427514 : void DefaultPlatform::EnsureBackgroundTaskRunnerInitialized() {
     103     1427514 :   base::MutexGuard guard(&lock_);
     104     1427514 :   if (!worker_threads_task_runner_) {
     105      119218 :     worker_threads_task_runner_ =
     106             :         std::make_shared<DefaultWorkerThreadsTaskRunner>(thread_pool_size_);
     107             :   }
     108     1427514 : }
     109             : 
     110             : namespace {
     111             : 
     112       35804 : double DefaultTimeFunction() {
     113    87038205 :   return base::TimeTicks::HighResolutionNow().ToInternalValue() /
     114    29048944 :          static_cast<double>(base::Time::kMicrosecondsPerSecond);
     115             : }
     116             : 
     117             : }  // namespace
     118             : 
     119           8 : void DefaultPlatform::SetTimeFunctionForTesting(
     120             :     DefaultPlatform::TimeFunction time_function) {
     121           8 :   base::MutexGuard guard(&lock_);
     122           8 :   time_function_for_testing_ = time_function;
     123             :   // The time function has to be right after the construction of the platform.
     124             :   DCHECK(foreground_task_runner_map_.empty());
     125           8 : }
     126             : 
     127      244490 : bool DefaultPlatform::PumpMessageLoop(v8::Isolate* isolate,
     128             :                                       MessageLoopBehavior wait_for_work) {
     129             :   bool failed_result = wait_for_work == MessageLoopBehavior::kWaitForWork;
     130      244490 :   std::shared_ptr<DefaultForegroundTaskRunner> task_runner;
     131             :   {
     132      244490 :     base::MutexGuard guard(&lock_);
     133             :     auto it = foreground_task_runner_map_.find(isolate);
     134      244490 :     if (it == foreground_task_runner_map_.end()) return failed_result;
     135             :     task_runner = it->second;
     136             :   }
     137             : 
     138      244487 :   std::unique_ptr<Task> task = task_runner->PopTaskFromQueue(wait_for_work);
     139      244487 :   if (!task) return failed_result;
     140             : 
     141       58449 :   task->Run();
     142       58449 :   return true;
     143             : }
     144             : 
     145      159242 : void DefaultPlatform::RunIdleTasks(v8::Isolate* isolate,
     146             :                                    double idle_time_in_seconds) {
     147             :   DCHECK_EQ(IdleTaskSupport::kEnabled, idle_task_support_);
     148      159242 :   std::shared_ptr<DefaultForegroundTaskRunner> task_runner;
     149             :   {
     150      159242 :     base::MutexGuard guard(&lock_);
     151      159242 :     if (foreground_task_runner_map_.find(isolate) ==
     152             :         foreground_task_runner_map_.end()) {
     153             :       return;
     154             :     }
     155      159242 :     task_runner = foreground_task_runner_map_[isolate];
     156             :   }
     157             :   double deadline_in_seconds =
     158      159242 :       MonotonicallyIncreasingTime() + idle_time_in_seconds;
     159             : 
     160      322438 :   while (deadline_in_seconds > MonotonicallyIncreasingTime()) {
     161      163152 :     std::unique_ptr<IdleTask> task = task_runner->PopTaskFromIdleQueue();
     162      163152 :     if (!task) return;
     163        3954 :     task->Run(deadline_in_seconds);
     164             :   }
     165             : }
     166             : 
     167      251047 : std::shared_ptr<TaskRunner> DefaultPlatform::GetForegroundTaskRunner(
     168             :     v8::Isolate* isolate) {
     169      251047 :   base::MutexGuard guard(&lock_);
     170      251048 :   if (foreground_task_runner_map_.find(isolate) ==
     171             :       foreground_task_runner_map_.end()) {
     172             :     foreground_task_runner_map_.insert(std::make_pair(
     173             :         isolate, std::make_shared<DefaultForegroundTaskRunner>(
     174             :                      idle_task_support_, time_function_for_testing_
     175             :                                              ? time_function_for_testing_
     176      181107 :                                              : DefaultTimeFunction)));
     177             :   }
     178      502096 :   return foreground_task_runner_map_[isolate];
     179             : }
     180             : 
     181     1367876 : void DefaultPlatform::CallOnWorkerThread(std::unique_ptr<Task> task) {
     182     1367876 :   EnsureBackgroundTaskRunnerInitialized();
     183     4103628 :   worker_threads_task_runner_->PostTask(std::move(task));
     184     1367876 : }
     185             : 
     186          30 : void DefaultPlatform::CallDelayedOnWorkerThread(std::unique_ptr<Task> task,
     187             :                                                 double delay_in_seconds) {
     188          30 :   EnsureBackgroundTaskRunnerInitialized();
     189          30 :   worker_threads_task_runner_->PostDelayedTask(std::move(task),
     190          90 :                                                delay_in_seconds);
     191          30 : }
     192             : 
     193           3 : void DefaultPlatform::CallOnForegroundThread(v8::Isolate* isolate, Task* task) {
     194          12 :   GetForegroundTaskRunner(isolate)->PostTask(std::unique_ptr<Task>(task));
     195           3 : }
     196             : 
     197           4 : void DefaultPlatform::CallDelayedOnForegroundThread(Isolate* isolate,
     198             :                                                     Task* task,
     199             :                                                     double delay_in_seconds) {
     200           8 :   GetForegroundTaskRunner(isolate)->PostDelayedTask(std::unique_ptr<Task>(task),
     201          12 :                                                     delay_in_seconds);
     202           4 : }
     203             : 
     204           2 : void DefaultPlatform::CallIdleOnForegroundThread(Isolate* isolate,
     205             :                                                  IdleTask* task) {
     206           4 :   GetForegroundTaskRunner(isolate)->PostIdleTask(
     207           6 :       std::unique_ptr<IdleTask>(task));
     208           2 : }
     209             : 
     210      164819 : bool DefaultPlatform::IdleTasksEnabled(Isolate* isolate) {
     211      164819 :   return idle_task_support_ == IdleTaskSupport::kEnabled;
     212             : }
     213             : 
     214    28976127 : double DefaultPlatform::MonotonicallyIncreasingTime() {
     215    28976127 :   if (time_function_for_testing_) return time_function_for_testing_();
     216    28977336 :   return DefaultTimeFunction();
     217             : }
     218             : 
     219      165177 : double DefaultPlatform::CurrentClockTimeMillis() {
     220      165177 :   return base::OS::TimeCurrentMillis();
     221             : }
     222             : 
     223     1920776 : TracingController* DefaultPlatform::GetTracingController() {
     224     1920776 :   return tracing_controller_.get();
     225             : }
     226             : 
     227          25 : void DefaultPlatform::SetTracingController(
     228             :     std::unique_ptr<v8::TracingController> tracing_controller) {
     229             :   DCHECK_NOT_NULL(tracing_controller.get());
     230             :   tracing_controller_ = std::move(tracing_controller);
     231          25 : }
     232             : 
     233     1277501 : int DefaultPlatform::NumberOfWorkerThreads() { return thread_pool_size_; }
     234             : 
     235       59583 : Platform::StackTracePrinter DefaultPlatform::GetStackTracePrinter() {
     236       59583 :   return PrintStackTrace;
     237             : }
     238             : 
     239       59579 : v8::PageAllocator* DefaultPlatform::GetPageAllocator() {
     240       59579 :   return page_allocator_.get();
     241             : }
     242             : 
     243             : }  // namespace platform
     244             : }  // namespace v8

Generated by: LCOV version 1.10