LCOV - code coverage report
Current view: top level - src - microtask-queue.h (source / functions) Hit Total Coverage
Test: app.info Lines: 7 7 100.0 %
Date: 2019-04-17 Functions: 0 2 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             : #ifndef V8_MICROTASK_QUEUE_H_
       6             : #define V8_MICROTASK_QUEUE_H_
       7             : 
       8             : #include <stdint.h>
       9             : #include <memory>
      10             : #include <vector>
      11             : 
      12             : #include "include/v8-internal.h"  // For Address.
      13             : #include "include/v8.h"
      14             : #include "src/base/macros.h"
      15             : 
      16             : namespace v8 {
      17             : namespace internal {
      18             : 
      19             : class Isolate;
      20             : class Microtask;
      21             : class Object;
      22             : class RootVisitor;
      23             : 
      24       62436 : class V8_EXPORT_PRIVATE MicrotaskQueue final : public v8::MicrotaskQueue {
      25             :  public:
      26             :   static void SetUpDefaultMicrotaskQueue(Isolate* isolate);
      27             :   static std::unique_ptr<MicrotaskQueue> New(Isolate* isolate);
      28             : 
      29             :   ~MicrotaskQueue();
      30             : 
      31             :   // Uses raw Address values because it's called via ExternalReference.
      32             :   // {raw_microtask} is a tagged Microtask pointer.
      33             :   // Returns a tagged Object pointer.
      34             :   static Address CallEnqueueMicrotask(Isolate* isolate,
      35             :                                       intptr_t microtask_queue_pointer,
      36             :                                       Address raw_microtask);
      37             : 
      38             :   // v8::MicrotaskQueue implementations.
      39             :   void EnqueueMicrotask(v8::Isolate* isolate,
      40             :                         v8::Local<Function> microtask) override;
      41             :   void EnqueueMicrotask(v8::Isolate* isolate, v8::MicrotaskCallback callback,
      42             :                         void* data) override;
      43             :   void PerformCheckpoint(v8::Isolate* isolate) override;
      44             : 
      45             :   void EnqueueMicrotask(Microtask microtask);
      46             :   void AddMicrotasksCompletedCallback(
      47             :       MicrotasksCompletedCallbackWithData callback, void* data) override;
      48             :   void RemoveMicrotasksCompletedCallback(
      49             :       MicrotasksCompletedCallbackWithData callback, void* data) override;
      50      121776 :   bool IsRunningMicrotasks() const override { return is_running_microtasks_; }
      51             : 
      52             :   // Runs all queued Microtasks.
      53             :   // Returns -1 if the execution is terminating, otherwise, returns the number
      54             :   // of microtasks that ran in this round.
      55             :   int RunMicrotasks(Isolate* isolate);
      56             : 
      57             :   // Iterate all pending Microtasks in this queue as strong roots, so that
      58             :   // builtins can update the queue directly without the write barrier.
      59             :   void IterateMicrotasks(RootVisitor* visitor);
      60             : 
      61             :   // Microtasks scope depth represents nested scopes controlling microtasks
      62             :   // invocation, which happens when depth reaches zero.
      63      143103 :   void IncrementMicrotasksScopeDepth() { ++microtasks_depth_; }
      64      143110 :   void DecrementMicrotasksScopeDepth() { --microtasks_depth_; }
      65             :   int GetMicrotasksScopeDepth() const override;
      66             : 
      67             :   // Possibly nested microtasks suppression scopes prevent microtasks
      68             :   // from running.
      69       38081 :   void IncrementMicrotasksSuppressions() { ++microtasks_suppressions_; }
      70       38081 :   void DecrementMicrotasksSuppressions() { --microtasks_suppressions_; }
      71             :   bool HasMicrotasksSuppressions() const {
      72             :     return microtasks_suppressions_ != 0;
      73             :   }
      74             : 
      75             : #ifdef DEBUG
      76             :   // In debug we check that calls not intended to invoke microtasks are
      77             :   // still correctly wrapped with microtask scopes.
      78             :   void IncrementDebugMicrotasksScopeDepth() { ++debug_microtasks_depth_; }
      79             :   void DecrementDebugMicrotasksScopeDepth() { --debug_microtasks_depth_; }
      80             :   bool DebugMicrotasksScopeDepthIsZero() const {
      81             :     return debug_microtasks_depth_ == 0;
      82             :   }
      83             : #endif
      84             : 
      85             :   void set_microtasks_policy(v8::MicrotasksPolicy microtasks_policy) {
      86        2329 :     microtasks_policy_ = microtasks_policy;
      87             :   }
      88             :   v8::MicrotasksPolicy microtasks_policy() const { return microtasks_policy_; }
      89             : 
      90             :   void FireMicrotasksCompletedCallback(Isolate* isolate) const;
      91             : 
      92             :   intptr_t capacity() const { return capacity_; }
      93             :   intptr_t size() const { return size_; }
      94             :   intptr_t start() const { return start_; }
      95             : 
      96             :   Microtask get(intptr_t index) const;
      97             : 
      98             :   MicrotaskQueue* next() const { return next_; }
      99             :   MicrotaskQueue* prev() const { return prev_; }
     100             : 
     101             :   static const size_t kRingBufferOffset;
     102             :   static const size_t kCapacityOffset;
     103             :   static const size_t kSizeOffset;
     104             :   static const size_t kStartOffset;
     105             :   static const size_t kFinishedMicrotaskCountOffset;
     106             : 
     107             :   static const intptr_t kMinimumCapacity;
     108             : 
     109             :  private:
     110             :   void OnCompleted(Isolate* isolate);
     111             : 
     112             :   MicrotaskQueue();
     113             :   void ResizeBuffer(intptr_t new_capacity);
     114             : 
     115             :   // A ring buffer to hold Microtask instances.
     116             :   // ring_buffer_[(start_ + i) % capacity_] contains |i|th Microtask for each
     117             :   // |i| in [0, size_).
     118             :   intptr_t size_ = 0;
     119             :   intptr_t capacity_ = 0;
     120             :   intptr_t start_ = 0;
     121             :   Address* ring_buffer_ = nullptr;
     122             : 
     123             :   // The number of finished microtask.
     124             :   intptr_t finished_microtask_count_ = 0;
     125             : 
     126             :   // MicrotaskQueue instances form a doubly linked list loop, so that all
     127             :   // instances are reachable through |next_|.
     128             :   MicrotaskQueue* next_ = nullptr;
     129             :   MicrotaskQueue* prev_ = nullptr;
     130             : 
     131             :   int microtasks_depth_ = 0;
     132             :   int microtasks_suppressions_ = 0;
     133             : #ifdef DEBUG
     134             :   int debug_microtasks_depth_ = 0;
     135             : #endif
     136             : 
     137             :   v8::MicrotasksPolicy microtasks_policy_ = v8::MicrotasksPolicy::kAuto;
     138             : 
     139             :   bool is_running_microtasks_ = false;
     140             :   using CallbackWithData =
     141             :       std::pair<MicrotasksCompletedCallbackWithData, void*>;
     142             :   std::vector<CallbackWithData> microtasks_completed_callbacks_;
     143             : };
     144             : 
     145             : }  // namespace internal
     146             : }  // namespace v8
     147             : 
     148             : #endif  // V8_MICROTASK_QUEUE_H_

Generated by: LCOV version 1.10