LCOV - code coverage report
Current view: top level - src/libplatform - default-platform.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 104 111 93.7 %
Date: 2019-04-17 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       61022 : 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       61022 :   if (in_process_stack_dumping == InProcessStackDumping::kEnabled) {
      39       30092 :     v8::base::debug::EnableInProcessStackDumping();
      40             :   }
      41             :   std::unique_ptr<DefaultPlatform> platform(
      42      122044 :       new DefaultPlatform(idle_task_support, std::move(tracing_controller)));
      43       61022 :   platform->SetThreadPoolSize(thread_pool_size);
      44       61022 :   platform->EnsureBackgroundTaskRunnerInitialized();
      45       61022 :   return std::move(platform);
      46             : }
      47             : 
      48      247551 : bool PumpMessageLoop(v8::Platform* platform, v8::Isolate* isolate,
      49             :                      MessageLoopBehavior behavior) {
      50             :   return static_cast<DefaultPlatform*>(platform)->PumpMessageLoop(isolate,
      51      247551 :                                                                   behavior);
      52             : }
      53             : 
      54      162208 : void RunIdleTasks(v8::Platform* platform, v8::Isolate* isolate,
      55             :                   double idle_time_in_seconds) {
      56             :   static_cast<DefaultPlatform*>(platform)->RunIdleTasks(isolate,
      57      162208 :                                                         idle_time_in_seconds);
      58      162208 : }
      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       61033 : 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      183099 :       time_function_for_testing_(nullptr) {
      77       61033 :   if (!tracing_controller_) {
      78       61032 :     tracing::TracingController* controller = new tracing::TracingController();
      79       61032 :     controller->Initialize(nullptr);
      80             :     tracing_controller_.reset(controller);
      81             :   }
      82       61033 : }
      83             : 
      84      231749 : DefaultPlatform::~DefaultPlatform() {
      85       57940 :   base::MutexGuard guard(&lock_);
      86       57940 :   if (worker_threads_task_runner_) worker_threads_task_runner_->Terminate();
      87      118256 :   for (auto it : foreground_task_runner_map_) {
      88       60316 :     it.second->Terminate();
      89             :   }
      90      115869 : }
      91             : 
      92       61024 : void DefaultPlatform::SetThreadPoolSize(int thread_pool_size) {
      93       61024 :   base::MutexGuard guard(&lock_);
      94             :   DCHECK_GE(thread_pool_size, 0);
      95       61024 :   if (thread_pool_size < 1) {
      96       61022 :     thread_pool_size = base::SysInfo::NumberOfProcessors() - 1;
      97             :   }
      98             :   thread_pool_size_ =
      99      122048 :       std::max(std::min(thread_pool_size, kMaxThreadPoolSize), 1);
     100       61024 : }
     101             : 
     102             : namespace {
     103             : 
     104     4114300 : double DefaultTimeFunction() {
     105   110199136 :   return base::TimeTicks::HighResolutionNow().ToInternalValue() /
     106    40852231 :          static_cast<double>(base::Time::kMicrosecondsPerSecond);
     107             : }
     108             : 
     109             : }  // namespace
     110             : 
     111     1832328 : void DefaultPlatform::EnsureBackgroundTaskRunnerInitialized() {
     112     1832328 :   base::MutexGuard guard(&lock_);
     113     1832328 :   if (!worker_threads_task_runner_) {
     114             :     worker_threads_task_runner_ =
     115      122046 :         std::make_shared<DefaultWorkerThreadsTaskRunner>(
     116       61023 :             thread_pool_size_, time_function_for_testing_
     117             :                                    ? time_function_for_testing_
     118             :                                    : DefaultTimeFunction);
     119             :   }
     120     1832327 : }
     121             : 
     122           8 : void DefaultPlatform::SetTimeFunctionForTesting(
     123             :     DefaultPlatform::TimeFunction time_function) {
     124           8 :   base::MutexGuard guard(&lock_);
     125           8 :   time_function_for_testing_ = time_function;
     126             :   // The time function has to be right after the construction of the platform.
     127             :   DCHECK(foreground_task_runner_map_.empty());
     128           8 : }
     129             : 
     130      247571 : bool DefaultPlatform::PumpMessageLoop(v8::Isolate* isolate,
     131             :                                       MessageLoopBehavior wait_for_work) {
     132             :   bool failed_result = wait_for_work == MessageLoopBehavior::kWaitForWork;
     133      247571 :   std::shared_ptr<DefaultForegroundTaskRunner> task_runner;
     134             :   {
     135      247571 :     base::MutexGuard guard(&lock_);
     136             :     auto it = foreground_task_runner_map_.find(isolate);
     137      247571 :     if (it == foreground_task_runner_map_.end()) return failed_result;
     138             :     task_runner = it->second;
     139             :   }
     140             : 
     141      247568 :   std::unique_ptr<Task> task = task_runner->PopTaskFromQueue(wait_for_work);
     142      247568 :   if (!task) return failed_result;
     143             : 
     144       57860 :   task->Run();
     145       57860 :   return true;
     146             : }
     147             : 
     148      162210 : void DefaultPlatform::RunIdleTasks(v8::Isolate* isolate,
     149             :                                    double idle_time_in_seconds) {
     150             :   DCHECK_EQ(IdleTaskSupport::kEnabled, idle_task_support_);
     151      162210 :   std::shared_ptr<DefaultForegroundTaskRunner> task_runner;
     152             :   {
     153      162210 :     base::MutexGuard guard(&lock_);
     154      162210 :     if (foreground_task_runner_map_.find(isolate) ==
     155             :         foreground_task_runner_map_.end()) {
     156             :       return;
     157             :     }
     158      162210 :     task_runner = foreground_task_runner_map_[isolate];
     159             :   }
     160             :   double deadline_in_seconds =
     161      162210 :       MonotonicallyIncreasingTime() + idle_time_in_seconds;
     162             : 
     163      165953 :   while (deadline_in_seconds > MonotonicallyIncreasingTime()) {
     164      165942 :     std::unique_ptr<IdleTask> task = task_runner->PopTaskFromIdleQueue();
     165      165942 :     if (!task) return;
     166        3743 :     task->Run(deadline_in_seconds);
     167             :   }
     168             : }
     169             : 
     170      253084 : std::shared_ptr<TaskRunner> DefaultPlatform::GetForegroundTaskRunner(
     171             :     v8::Isolate* isolate) {
     172      253084 :   base::MutexGuard guard(&lock_);
     173      253084 :   if (foreground_task_runner_map_.find(isolate) ==
     174             :       foreground_task_runner_map_.end()) {
     175       61603 :     foreground_task_runner_map_.insert(std::make_pair(
     176      123206 :         isolate, std::make_shared<DefaultForegroundTaskRunner>(
     177       61603 :                      idle_task_support_, time_function_for_testing_
     178             :                                              ? time_function_for_testing_
     179             :                                              : DefaultTimeFunction)));
     180             :   }
     181      506168 :   return foreground_task_runner_map_[isolate];
     182             : }
     183             : 
     184     1771276 : void DefaultPlatform::CallOnWorkerThread(std::unique_ptr<Task> task) {
     185     1771276 :   EnsureBackgroundTaskRunnerInitialized();
     186     5313826 :   worker_threads_task_runner_->PostTask(std::move(task));
     187     1771276 : }
     188             : 
     189          30 : void DefaultPlatform::CallDelayedOnWorkerThread(std::unique_ptr<Task> task,
     190             :                                                 double delay_in_seconds) {
     191          30 :   EnsureBackgroundTaskRunnerInitialized();
     192          30 :   worker_threads_task_runner_->PostDelayedTask(std::move(task),
     193          60 :                                                delay_in_seconds);
     194          30 : }
     195             : 
     196           3 : void DefaultPlatform::CallOnForegroundThread(v8::Isolate* isolate, Task* task) {
     197          12 :   GetForegroundTaskRunner(isolate)->PostTask(std::unique_ptr<Task>(task));
     198           3 : }
     199             : 
     200           4 : void DefaultPlatform::CallDelayedOnForegroundThread(Isolate* isolate,
     201             :                                                     Task* task,
     202             :                                                     double delay_in_seconds) {
     203          12 :   GetForegroundTaskRunner(isolate)->PostDelayedTask(std::unique_ptr<Task>(task),
     204           8 :                                                     delay_in_seconds);
     205           4 : }
     206             : 
     207           2 : void DefaultPlatform::CallIdleOnForegroundThread(Isolate* isolate,
     208             :                                                  IdleTask* task) {
     209           6 :   GetForegroundTaskRunner(isolate)->PostIdleTask(
     210           4 :       std::unique_ptr<IdleTask>(task));
     211           2 : }
     212             : 
     213      168396 : bool DefaultPlatform::IdleTasksEnabled(Isolate* isolate) {
     214      168396 :   return idle_task_support_ == IdleTaskSupport::kEnabled;
     215             : }
     216             : 
     217    32608982 : double DefaultPlatform::MonotonicallyIncreasingTime() {
     218    32608982 :   if (time_function_for_testing_) return time_function_for_testing_();
     219    32623629 :   return DefaultTimeFunction();
     220             : }
     221             : 
     222     1155073 : double DefaultPlatform::CurrentClockTimeMillis() {
     223     1155073 :   return base::OS::TimeCurrentMillis();
     224             : }
     225             : 
     226     2426330 : TracingController* DefaultPlatform::GetTracingController() {
     227     2426330 :   return tracing_controller_.get();
     228             : }
     229             : 
     230          30 : void DefaultPlatform::SetTracingController(
     231             :     std::unique_ptr<v8::TracingController> tracing_controller) {
     232             :   DCHECK_NOT_NULL(tracing_controller.get());
     233             :   tracing_controller_ = std::move(tracing_controller);
     234          30 : }
     235             : 
     236     1276897 : int DefaultPlatform::NumberOfWorkerThreads() { return thread_pool_size_; }
     237             : 
     238       60992 : Platform::StackTracePrinter DefaultPlatform::GetStackTracePrinter() {
     239       60992 :   return PrintStackTrace;
     240             : }
     241             : 
     242       60988 : v8::PageAllocator* DefaultPlatform::GetPageAllocator() {
     243       60988 :   return page_allocator_.get();
     244             : }
     245             : 
     246             : }  // namespace platform
     247             : }  // namespace v8

Generated by: LCOV version 1.10