LCOV - code coverage report
Current view: top level - src/libplatform - default-platform.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 100 109 91.7 %
Date: 2019-01-20 Functions: 26 29 89.7 %

          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       61306 : 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       61306 :   if (in_process_stack_dumping == InProcessStackDumping::kEnabled) {
      39       28763 :     v8::base::debug::EnableInProcessStackDumping();
      40             :   }
      41             :   std::unique_ptr<DefaultPlatform> platform(
      42      122612 :       new DefaultPlatform(idle_task_support, std::move(tracing_controller)));
      43       61306 :   platform->SetThreadPoolSize(thread_pool_size);
      44       61306 :   platform->EnsureBackgroundTaskRunnerInitialized();
      45       61306 :   return std::move(platform);
      46             : }
      47             : 
      48           0 : v8::Platform* CreateDefaultPlatform(
      49             :     int thread_pool_size, IdleTaskSupport idle_task_support,
      50             :     InProcessStackDumping in_process_stack_dumping,
      51             :     v8::TracingController* tracing_controller) {
      52             :   return NewDefaultPlatform(
      53             :              thread_pool_size, idle_task_support, in_process_stack_dumping,
      54             :              std::unique_ptr<v8::TracingController>(tracing_controller))
      55           0 :       .release();
      56             : }
      57             : 
      58      278645 : bool PumpMessageLoop(v8::Platform* platform, v8::Isolate* isolate,
      59             :                      MessageLoopBehavior behavior) {
      60             :   return static_cast<DefaultPlatform*>(platform)->PumpMessageLoop(isolate,
      61      278645 :                                                                   behavior);
      62             : }
      63             : 
      64      158175 : void RunIdleTasks(v8::Platform* platform, v8::Isolate* isolate,
      65             :                   double idle_time_in_seconds) {
      66             :   static_cast<DefaultPlatform*>(platform)->RunIdleTasks(isolate,
      67      158175 :                                                         idle_time_in_seconds);
      68      158175 : }
      69             : 
      70           0 : void SetTracingController(
      71             :     v8::Platform* platform,
      72             :     v8::platform::tracing::TracingController* tracing_controller) {
      73             :   static_cast<DefaultPlatform*>(platform)->SetTracingController(
      74             :       std::unique_ptr<v8::TracingController>(tracing_controller));
      75           0 : }
      76             : 
      77             : const int DefaultPlatform::kMaxThreadPoolSize = 8;
      78             : 
      79       61317 : 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      183951 :       time_function_for_testing_(nullptr) {
      87       61317 :   if (!tracing_controller_) {
      88       61316 :     tracing::TracingController* controller = new tracing::TracingController();
      89       61316 :     controller->Initialize(nullptr);
      90             :     tracing_controller_.reset(controller);
      91             :   }
      92       61317 : }
      93             : 
      94      174844 : DefaultPlatform::~DefaultPlatform() {
      95       58285 :   base::MutexGuard guard(&lock_);
      96       58285 :   if (worker_threads_task_runner_) worker_threads_task_runner_->Terminate();
      97      177503 :   for (auto it : foreground_task_runner_map_) {
      98       60933 :     it.second->Terminate();
      99             :   }
     100      116559 : }
     101             : 
     102       61308 : void DefaultPlatform::SetThreadPoolSize(int thread_pool_size) {
     103       61308 :   base::MutexGuard guard(&lock_);
     104             :   DCHECK_GE(thread_pool_size, 0);
     105       61308 :   if (thread_pool_size < 1) {
     106       61306 :     thread_pool_size = base::SysInfo::NumberOfProcessors() - 1;
     107             :   }
     108             :   thread_pool_size_ =
     109      122616 :       std::max(std::min(thread_pool_size, kMaxThreadPoolSize), 1);
     110       61308 : }
     111             : 
     112     1514738 : void DefaultPlatform::EnsureBackgroundTaskRunnerInitialized() {
     113     1514738 :   base::MutexGuard guard(&lock_);
     114     1514738 :   if (!worker_threads_task_runner_) {
     115      122614 :     worker_threads_task_runner_ =
     116             :         std::make_shared<DefaultWorkerThreadsTaskRunner>(thread_pool_size_);
     117             :   }
     118     1514738 : }
     119             : 
     120             : namespace {
     121             : 
     122       22819 : double DefaultTimeFunction() {
     123    87134210 :   return base::TimeTicks::HighResolutionNow().ToInternalValue() /
     124    29068386 :          static_cast<double>(base::Time::kMicrosecondsPerSecond);
     125             : }
     126             : 
     127             : }  // namespace
     128             : 
     129           8 : void DefaultPlatform::SetTimeFunctionForTesting(
     130             :     DefaultPlatform::TimeFunction time_function) {
     131           8 :   base::MutexGuard guard(&lock_);
     132           8 :   time_function_for_testing_ = time_function;
     133             :   // The time function has to be right after the construction of the platform.
     134             :   DCHECK(foreground_task_runner_map_.empty());
     135           8 : }
     136             : 
     137      278665 : bool DefaultPlatform::PumpMessageLoop(v8::Isolate* isolate,
     138             :                                       MessageLoopBehavior wait_for_work) {
     139             :   bool failed_result = wait_for_work == MessageLoopBehavior::kWaitForWork;
     140      278665 :   std::shared_ptr<DefaultForegroundTaskRunner> task_runner;
     141             :   {
     142      278665 :     base::MutexGuard guard(&lock_);
     143             :     auto it = foreground_task_runner_map_.find(isolate);
     144      278665 :     if (it == foreground_task_runner_map_.end()) return failed_result;
     145             :     task_runner = it->second;
     146             :   }
     147             : 
     148      278662 :   std::unique_ptr<Task> task = task_runner->PopTaskFromQueue(wait_for_work);
     149      278662 :   if (!task) return failed_result;
     150             : 
     151       91156 :   task->Run();
     152       91156 :   return true;
     153             : }
     154             : 
     155      158177 : void DefaultPlatform::RunIdleTasks(v8::Isolate* isolate,
     156             :                                    double idle_time_in_seconds) {
     157             :   DCHECK_EQ(IdleTaskSupport::kEnabled, idle_task_support_);
     158      158177 :   std::shared_ptr<DefaultForegroundTaskRunner> task_runner;
     159             :   {
     160      158177 :     base::MutexGuard guard(&lock_);
     161      158177 :     if (foreground_task_runner_map_.find(isolate) ==
     162             :         foreground_task_runner_map_.end()) {
     163             :       return;
     164             :     }
     165      158177 :     task_runner = foreground_task_runner_map_[isolate];
     166             :   }
     167             :   double deadline_in_seconds =
     168      158177 :       MonotonicallyIncreasingTime() + idle_time_in_seconds;
     169             : 
     170      320219 :   while (deadline_in_seconds > MonotonicallyIncreasingTime()) {
     171      162008 :     std::unique_ptr<IdleTask> task = task_runner->PopTaskFromIdleQueue();
     172      162008 :     if (!task) return;
     173        3865 :     task->Run(deadline_in_seconds);
     174             :   }
     175             : }
     176             : 
     177     1733424 : std::shared_ptr<TaskRunner> DefaultPlatform::GetForegroundTaskRunner(
     178             :     v8::Isolate* isolate) {
     179     1733424 :   base::MutexGuard guard(&lock_);
     180     1733426 :   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      186588 :                                              : DefaultTimeFunction)));
     187             :   }
     188     3466852 :   return foreground_task_runner_map_[isolate];
     189             : }
     190             : 
     191     1453402 : void DefaultPlatform::CallOnWorkerThread(std::unique_ptr<Task> task) {
     192     1453402 :   EnsureBackgroundTaskRunnerInitialized();
     193     4360206 :   worker_threads_task_runner_->PostTask(std::move(task));
     194     1453402 : }
     195             : 
     196          30 : void DefaultPlatform::CallDelayedOnWorkerThread(std::unique_ptr<Task> task,
     197             :                                                 double delay_in_seconds) {
     198          30 :   EnsureBackgroundTaskRunnerInitialized();
     199          30 :   worker_threads_task_runner_->PostDelayedTask(std::move(task),
     200          90 :                                                delay_in_seconds);
     201          30 : }
     202             : 
     203           3 : void DefaultPlatform::CallOnForegroundThread(v8::Isolate* isolate, Task* task) {
     204          12 :   GetForegroundTaskRunner(isolate)->PostTask(std::unique_ptr<Task>(task));
     205           3 : }
     206             : 
     207           4 : void DefaultPlatform::CallDelayedOnForegroundThread(Isolate* isolate,
     208             :                                                     Task* task,
     209             :                                                     double delay_in_seconds) {
     210           8 :   GetForegroundTaskRunner(isolate)->PostDelayedTask(std::unique_ptr<Task>(task),
     211          12 :                                                     delay_in_seconds);
     212           4 : }
     213             : 
     214           2 : void DefaultPlatform::CallIdleOnForegroundThread(Isolate* isolate,
     215             :                                                  IdleTask* task) {
     216           4 :   GetForegroundTaskRunner(isolate)->PostIdleTask(
     217           6 :       std::unique_ptr<IdleTask>(task));
     218           2 : }
     219             : 
     220      163669 : bool DefaultPlatform::IdleTasksEnabled(Isolate* isolate) {
     221      163669 :   return idle_task_support_ == IdleTaskSupport::kEnabled;
     222             : }
     223             : 
     224    29020263 : double DefaultPlatform::MonotonicallyIncreasingTime() {
     225    29020263 :   if (time_function_for_testing_) return time_function_for_testing_();
     226    29022748 :   return DefaultTimeFunction();
     227             : }
     228             : 
     229      165476 : double DefaultPlatform::CurrentClockTimeMillis() {
     230      165476 :   return base::OS::TimeCurrentMillis();
     231             : }
     232             : 
     233     2036589 : TracingController* DefaultPlatform::GetTracingController() {
     234             :   return tracing_controller_.get();
     235             : }
     236             : 
     237          25 : 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);
     241          25 : }
     242             : 
     243     1570312 : int DefaultPlatform::NumberOfWorkerThreads() { return thread_pool_size_; }
     244             : 
     245       61281 : Platform::StackTracePrinter DefaultPlatform::GetStackTracePrinter() {
     246       61281 :   return PrintStackTrace;
     247             : }
     248             : 
     249       61279 : v8::PageAllocator* DefaultPlatform::GetPageAllocator() {
     250       61279 :   return page_allocator_.get();
     251             : }
     252             : 
     253             : }  // namespace platform
     254             : }  // namespace v8

Generated by: LCOV version 1.10