LCOV - code coverage report
Current view: top level - src - d8-platforms.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 0 120 0.0 %
Date: 2019-04-17 Functions: 0 52 0.0 %

          Line data    Source code
       1             : // Copyright 2018 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 <memory>
       6             : #include <unordered_map>
       7             : 
       8             : #include "include/v8-platform.h"
       9             : #include "src/base/logging.h"
      10             : #include "src/base/macros.h"
      11             : #include "src/base/platform/mutex.h"
      12             : #include "src/base/platform/platform.h"
      13             : #include "src/base/platform/time.h"
      14             : #include "src/base/template-utils.h"
      15             : #include "src/base/utils/random-number-generator.h"
      16             : #include "src/d8-platforms.h"
      17             : 
      18             : namespace v8 {
      19             : 
      20           0 : class PredictablePlatform : public Platform {
      21             :  public:
      22             :   explicit PredictablePlatform(std::unique_ptr<Platform> platform)
      23           0 :       : platform_(std::move(platform)) {
      24             :     DCHECK_NOT_NULL(platform_);
      25             :   }
      26             : 
      27           0 :   PageAllocator* GetPageAllocator() override {
      28           0 :     return platform_->GetPageAllocator();
      29             :   }
      30             : 
      31           0 :   void OnCriticalMemoryPressure() override {
      32           0 :     platform_->OnCriticalMemoryPressure();
      33           0 :   }
      34             : 
      35           0 :   bool OnCriticalMemoryPressure(size_t length) override {
      36           0 :     return platform_->OnCriticalMemoryPressure(length);
      37             :   }
      38             : 
      39           0 :   std::shared_ptr<TaskRunner> GetForegroundTaskRunner(
      40             :       v8::Isolate* isolate) override {
      41           0 :     return platform_->GetForegroundTaskRunner(isolate);
      42             :   }
      43             : 
      44           0 :   int NumberOfWorkerThreads() override { return 0; }
      45             : 
      46           0 :   void CallOnWorkerThread(std::unique_ptr<Task> task) override {
      47             :     // It's not defined when background tasks are being executed, so we can just
      48             :     // execute them right away.
      49           0 :     task->Run();
      50           0 :   }
      51             : 
      52           0 :   void CallDelayedOnWorkerThread(std::unique_ptr<Task> task,
      53             :                                  double delay_in_seconds) override {
      54             :     // Never run delayed tasks.
      55           0 :   }
      56             : 
      57           0 :   void CallOnForegroundThread(v8::Isolate* isolate, Task* task) override {
      58             :     // This is a deprecated function and should not be called anymore.
      59           0 :     UNREACHABLE();
      60             :   }
      61             : 
      62           0 :   void CallDelayedOnForegroundThread(v8::Isolate* isolate, Task* task,
      63             :                                      double delay_in_seconds) override {
      64             :     // This is a deprecated function and should not be called anymore.
      65           0 :     UNREACHABLE();
      66             :   }
      67             : 
      68           0 :   void CallIdleOnForegroundThread(Isolate* isolate, IdleTask* task) override {
      69           0 :     UNREACHABLE();
      70             :   }
      71             : 
      72           0 :   bool IdleTasksEnabled(Isolate* isolate) override { return false; }
      73             : 
      74           0 :   double MonotonicallyIncreasingTime() override {
      75           0 :     return synthetic_time_in_sec_ += 0.00001;
      76             :   }
      77             : 
      78           0 :   double CurrentClockTimeMillis() override {
      79           0 :     return MonotonicallyIncreasingTime() * base::Time::kMillisecondsPerSecond;
      80             :   }
      81             : 
      82           0 :   v8::TracingController* GetTracingController() override {
      83           0 :     return platform_->GetTracingController();
      84             :   }
      85             : 
      86             :   Platform* platform() const { return platform_.get(); }
      87             : 
      88             :  private:
      89             :   double synthetic_time_in_sec_ = 0.0;
      90             :   std::unique_ptr<Platform> platform_;
      91             : 
      92             :   DISALLOW_COPY_AND_ASSIGN(PredictablePlatform);
      93             : };
      94             : 
      95           0 : std::unique_ptr<Platform> MakePredictablePlatform(
      96             :     std::unique_ptr<Platform> platform) {
      97           0 :   return base::make_unique<PredictablePlatform>(std::move(platform));
      98             : }
      99             : 
     100             : class DelayedTasksPlatform : public Platform {
     101             :  public:
     102           0 :   explicit DelayedTasksPlatform(std::unique_ptr<Platform> platform)
     103           0 :       : platform_(std::move(platform)) {
     104             :     DCHECK_NOT_NULL(platform_);
     105           0 :   }
     106             : 
     107           0 :   explicit DelayedTasksPlatform(std::unique_ptr<Platform> platform,
     108             :                                 int64_t random_seed)
     109           0 :       : platform_(std::move(platform)), rng_(random_seed) {
     110             :     DCHECK_NOT_NULL(platform_);
     111           0 :   }
     112             : 
     113           0 :   ~DelayedTasksPlatform() {
     114             :     // When the platform shuts down, all task runners must be freed.
     115             :     DCHECK_EQ(0, delayed_task_runners_.size());
     116           0 :   }
     117             : 
     118           0 :   PageAllocator* GetPageAllocator() override {
     119           0 :     return platform_->GetPageAllocator();
     120             :   }
     121             : 
     122           0 :   void OnCriticalMemoryPressure() override {
     123           0 :     platform_->OnCriticalMemoryPressure();
     124           0 :   }
     125             : 
     126           0 :   bool OnCriticalMemoryPressure(size_t length) override {
     127           0 :     return platform_->OnCriticalMemoryPressure(length);
     128             :   }
     129             : 
     130           0 :   std::shared_ptr<TaskRunner> GetForegroundTaskRunner(
     131             :       v8::Isolate* isolate) override {
     132             :     std::shared_ptr<TaskRunner> runner =
     133           0 :         platform_->GetForegroundTaskRunner(isolate);
     134             : 
     135           0 :     base::MutexGuard lock_guard(&mutex_);
     136             :     // Check if we can re-materialize the weak ptr in our map.
     137             :     std::weak_ptr<DelayedTaskRunner>& weak_delayed_runner =
     138           0 :         delayed_task_runners_[runner.get()];
     139             :     std::shared_ptr<DelayedTaskRunner> delayed_runner =
     140             :         weak_delayed_runner.lock();
     141             : 
     142           0 :     if (!delayed_runner) {
     143             :       // Create a new {DelayedTaskRunner} and keep a weak reference in our map.
     144           0 :       delayed_runner.reset(new DelayedTaskRunner(runner, this),
     145           0 :                            DelayedTaskRunnerDeleter{});
     146             :       weak_delayed_runner = delayed_runner;
     147             :     }
     148             : 
     149           0 :     return std::move(delayed_runner);
     150             :   }
     151             : 
     152           0 :   int NumberOfWorkerThreads() override {
     153           0 :     return platform_->NumberOfWorkerThreads();
     154             :   }
     155             : 
     156           0 :   void CallOnWorkerThread(std::unique_ptr<Task> task) override {
     157           0 :     platform_->CallOnWorkerThread(MakeDelayedTask(std::move(task)));
     158           0 :   }
     159             : 
     160           0 :   void CallDelayedOnWorkerThread(std::unique_ptr<Task> task,
     161             :                                  double delay_in_seconds) override {
     162           0 :     platform_->CallDelayedOnWorkerThread(MakeDelayedTask(std::move(task)),
     163           0 :                                          delay_in_seconds);
     164           0 :   }
     165             : 
     166           0 :   void CallOnForegroundThread(v8::Isolate* isolate, Task* task) override {
     167             :     // This is a deprecated function and should not be called anymore.
     168           0 :     UNREACHABLE();
     169             :   }
     170             : 
     171           0 :   void CallDelayedOnForegroundThread(v8::Isolate* isolate, Task* task,
     172             :                                      double delay_in_seconds) override {
     173             :     // This is a deprecated function and should not be called anymore.
     174           0 :     UNREACHABLE();
     175             :   }
     176             : 
     177           0 :   void CallIdleOnForegroundThread(Isolate* isolate, IdleTask* task) override {
     178             :     // This is a deprecated function and should not be called anymore.
     179           0 :     UNREACHABLE();
     180             :   }
     181             : 
     182           0 :   bool IdleTasksEnabled(Isolate* isolate) override {
     183           0 :     return platform_->IdleTasksEnabled(isolate);
     184             :   }
     185             : 
     186           0 :   double MonotonicallyIncreasingTime() override {
     187           0 :     return platform_->MonotonicallyIncreasingTime();
     188             :   }
     189             : 
     190           0 :   double CurrentClockTimeMillis() override {
     191           0 :     return platform_->CurrentClockTimeMillis();
     192             :   }
     193             : 
     194           0 :   v8::TracingController* GetTracingController() override {
     195           0 :     return platform_->GetTracingController();
     196             :   }
     197             : 
     198             :  private:
     199             :   class DelayedTaskRunnerDeleter;
     200           0 :   class DelayedTaskRunner final : public TaskRunner {
     201             :    public:
     202             :     DelayedTaskRunner(std::shared_ptr<TaskRunner> task_runner,
     203             :                       DelayedTasksPlatform* platform)
     204           0 :         : task_runner_(task_runner), platform_(platform) {}
     205             : 
     206           0 :     void PostTask(std::unique_ptr<Task> task) final {
     207           0 :       task_runner_->PostTask(platform_->MakeDelayedTask(std::move(task)));
     208           0 :     }
     209             : 
     210           0 :     void PostDelayedTask(std::unique_ptr<Task> task,
     211             :                          double delay_in_seconds) final {
     212           0 :       task_runner_->PostDelayedTask(platform_->MakeDelayedTask(std::move(task)),
     213           0 :                                     delay_in_seconds);
     214           0 :     }
     215             : 
     216           0 :     void PostIdleTask(std::unique_ptr<IdleTask> task) final {
     217             :       task_runner_->PostIdleTask(
     218           0 :           platform_->MakeDelayedIdleTask(std::move(task)));
     219           0 :     }
     220             : 
     221           0 :     bool IdleTasksEnabled() final { return task_runner_->IdleTasksEnabled(); }
     222             : 
     223             :    private:
     224             :     friend class DelayedTaskRunnerDeleter;
     225             :     std::shared_ptr<TaskRunner> task_runner_;
     226             :     DelayedTasksPlatform* platform_;
     227             :   };
     228             : 
     229             :   class DelayedTaskRunnerDeleter {
     230             :    public:
     231           0 :     void operator()(DelayedTaskRunner* runner) const {
     232           0 :       TaskRunner* original_runner = runner->task_runner_.get();
     233           0 :       base::MutexGuard lock_guard(&runner->platform_->mutex_);
     234           0 :       auto& delayed_task_runners = runner->platform_->delayed_task_runners_;
     235             :       DCHECK_EQ(1, delayed_task_runners.count(original_runner));
     236             :       delayed_task_runners.erase(original_runner);
     237           0 :     }
     238             :   };
     239             : 
     240           0 :   class DelayedTask : public Task {
     241             :    public:
     242             :     DelayedTask(std::unique_ptr<Task> task, int32_t delay_ms)
     243           0 :         : task_(std::move(task)), delay_ms_(delay_ms) {}
     244           0 :     void Run() final {
     245           0 :       base::OS::Sleep(base::TimeDelta::FromMicroseconds(delay_ms_));
     246           0 :       task_->Run();
     247           0 :     }
     248             : 
     249             :    private:
     250             :     std::unique_ptr<Task> task_;
     251             :     int32_t delay_ms_;
     252             :   };
     253             : 
     254           0 :   class DelayedIdleTask : public IdleTask {
     255             :    public:
     256             :     DelayedIdleTask(std::unique_ptr<IdleTask> task, int32_t delay_ms)
     257           0 :         : task_(std::move(task)), delay_ms_(delay_ms) {}
     258           0 :     void Run(double deadline_in_seconds) final {
     259           0 :       base::OS::Sleep(base::TimeDelta::FromMicroseconds(delay_ms_));
     260           0 :       task_->Run(deadline_in_seconds);
     261           0 :     }
     262             : 
     263             :    private:
     264             :     std::unique_ptr<IdleTask> task_;
     265             :     int32_t delay_ms_;
     266             :   };
     267             : 
     268             :   std::unique_ptr<Platform> platform_;
     269             : 
     270             :   // The Mutex protects the RNG, which is used by foreground and background
     271             :   // threads, and the {delayed_task_runners_} map might be accessed concurrently
     272             :   // by the shared_ptr destructor.
     273             :   base::Mutex mutex_;
     274             :   base::RandomNumberGenerator rng_;
     275             :   std::unordered_map<TaskRunner*, std::weak_ptr<DelayedTaskRunner>>
     276             :       delayed_task_runners_;
     277             : 
     278           0 :   int32_t GetRandomDelayInMilliseconds() {
     279           0 :     base::MutexGuard lock_guard(&mutex_);
     280           0 :     double delay_fraction = rng_.NextDouble();
     281             :     // Sleep up to 100ms (100000us). Square {delay_fraction} to shift
     282             :     // distribution towards shorter sleeps.
     283           0 :     return 1e5 * (delay_fraction * delay_fraction);
     284             :   }
     285             : 
     286           0 :   std::unique_ptr<Task> MakeDelayedTask(std::unique_ptr<Task> task) {
     287             :     return base::make_unique<DelayedTask>(std::move(task),
     288           0 :                                           GetRandomDelayInMilliseconds());
     289             :   }
     290             : 
     291           0 :   std::unique_ptr<IdleTask> MakeDelayedIdleTask(
     292             :       std::unique_ptr<IdleTask> task) {
     293             :     return base::make_unique<DelayedIdleTask>(std::move(task),
     294           0 :                                               GetRandomDelayInMilliseconds());
     295             :   }
     296             : 
     297             :   DISALLOW_COPY_AND_ASSIGN(DelayedTasksPlatform);
     298             : };
     299             : 
     300           0 : std::unique_ptr<Platform> MakeDelayedTasksPlatform(
     301             :     std::unique_ptr<Platform> platform, int64_t random_seed) {
     302           0 :   if (random_seed) {
     303           0 :     return base::make_unique<DelayedTasksPlatform>(std::move(platform),
     304             :                                                    random_seed);
     305             :   }
     306           0 :   return base::make_unique<DelayedTasksPlatform>(std::move(platform));
     307             : }
     308             : 
     309             : }  // namespace v8

Generated by: LCOV version 1.10