LCOV - code coverage report
Current view: top level - src - global-handles.h (source / functions) Hit Total Coverage
Test: app.info Lines: 7 8 87.5 %
Date: 2019-01-20 Functions: 1 1 100.0 %

          Line data    Source code
       1             : // Copyright 2011 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_GLOBAL_HANDLES_H_
       6             : #define V8_GLOBAL_HANDLES_H_
       7             : 
       8             : #include <type_traits>
       9             : #include <vector>
      10             : 
      11             : #include "include/v8.h"
      12             : #include "include/v8-profiler.h"
      13             : 
      14             : #include "src/handles.h"
      15             : #include "src/objects.h"
      16             : #include "src/utils.h"
      17             : 
      18             : namespace v8 {
      19             : namespace internal {
      20             : 
      21             : class HeapStats;
      22             : class RootVisitor;
      23             : 
      24             : // Structure for tracking global handles.
      25             : // A single list keeps all the allocated global handles.
      26             : // Destroyed handles stay in the list but is added to the free list.
      27             : // At GC the destroyed global handles are removed from the free list
      28             : // and deallocated.
      29             : 
      30             : enum WeaknessType {
      31             :   // Embedder gets a handle to the dying object.
      32             :   FINALIZER_WEAK,
      33             :   // In the following cases, the embedder gets the parameter they passed in
      34             :   // earlier, and 0 or 2 first embedder fields. Note that the internal
      35             :   // fields must contain aligned non-V8 pointers.  Getting pointers to V8
      36             :   // objects through this interface would be GC unsafe so in that case the
      37             :   // embedder gets a null pointer instead.
      38             :   PHANTOM_WEAK,
      39             :   PHANTOM_WEAK_2_EMBEDDER_FIELDS,
      40             :   // The handle is automatically reset by the garbage collector when
      41             :   // the object is no longer reachable.
      42             :   PHANTOM_WEAK_RESET_HANDLE
      43             : };
      44             : 
      45             : class GlobalHandles {
      46             :  public:
      47             :   ~GlobalHandles();
      48             : 
      49             :   // Creates a new global handle that is alive until Destroy is called.
      50             :   Handle<Object> Create(Object value);
      51             :   Handle<Object> Create(Address value);
      52             : 
      53             :   template <typename T>
      54             :   Handle<T> Create(T value) {
      55             :     static_assert(std::is_base_of<Object, T>::value, "static type violation");
      56             :     // The compiler should only pick this method if T is not Object.
      57             :     static_assert(!std::is_same<Object, T>::value, "compiler error");
      58     4158960 :     return Handle<T>::cast(Create(Object(value)));
      59             :   }
      60             : 
      61             :   // Copy a global handle
      62             :   static Handle<Object> CopyGlobal(Address* location);
      63             : 
      64             :   // Destroy a global handle.
      65             :   static void Destroy(Address* location);
      66             : 
      67             :   // Make the global handle weak and set the callback parameter for the
      68             :   // handle.  When the garbage collector recognizes that only weak global
      69             :   // handles point to an object the callback function is invoked (for each
      70             :   // handle) with the handle and corresponding parameter as arguments.  By
      71             :   // default the handle still contains a pointer to the object that is being
      72             :   // collected.  For this reason the object is not collected until the next
      73             :   // GC.  For a phantom weak handle the handle is cleared (set to a Smi)
      74             :   // before the callback is invoked, but the handle can still be identified
      75             :   // in the callback by using the location() of the handle.
      76             :   static void MakeWeak(Address* location, void* parameter,
      77             :                        WeakCallbackInfo<void>::Callback weak_callback,
      78             :                        v8::WeakCallbackType type);
      79             : 
      80             :   static void MakeWeak(Address** location_addr);
      81             : 
      82             :   static void AnnotateStrongRetainer(Address* location, const char* label);
      83             : 
      84             :   void RecordStats(HeapStats* stats);
      85             : 
      86             :   // Returns the current number of handles to global objects.
      87             :   int global_handles_count() const {
      88             :     return number_of_global_handles_;
      89             :   }
      90             : 
      91             :   size_t NumberOfPhantomHandleResets() {
      92             :     return number_of_phantom_handle_resets_;
      93             :   }
      94             : 
      95             :   void ResetNumberOfPhantomHandleResets() {
      96          15 :     number_of_phantom_handle_resets_ = 0;
      97             :   }
      98             : 
      99           0 :   size_t NumberOfNewSpaceNodes() { return new_space_nodes_.size(); }
     100             : 
     101             :   // Clear the weakness of a global handle.
     102             :   static void* ClearWeakness(Address* location);
     103             : 
     104             :   // Tells whether global handle is near death.
     105             :   static bool IsNearDeath(Address* location);
     106             : 
     107             :   // Tells whether global handle is weak.
     108             :   static bool IsWeak(Address* location);
     109             : 
     110             :   int InvokeFirstPassWeakCallbacks();
     111             : 
     112             :   // Process pending weak handles.
     113             :   // Returns the number of freed nodes.
     114             :   int PostGarbageCollectionProcessing(
     115             :       GarbageCollector collector, const v8::GCCallbackFlags gc_callback_flags);
     116             : 
     117             :   void IterateStrongRoots(RootVisitor* v);
     118             : 
     119             :   void IterateWeakRoots(RootVisitor* v);
     120             : 
     121             :   void IterateAllRoots(RootVisitor* v);
     122             : 
     123             :   void IterateAllNewSpaceRoots(RootVisitor* v);
     124             :   void IterateNewSpaceRoots(RootVisitor* v, size_t start, size_t end);
     125             : 
     126             :   // Iterates over all handles that have embedder-assigned class ID.
     127             :   void IterateAllRootsWithClassIds(v8::PersistentHandleVisitor* v);
     128             : 
     129             :   // Iterates over all handles in the new space that have embedder-assigned
     130             :   // class ID.
     131             :   void IterateAllRootsInNewSpaceWithClassIds(v8::PersistentHandleVisitor* v);
     132             : 
     133             :   // Iterate over all handles in the new space that are weak, unmodified
     134             :   // and have class IDs
     135             :   void IterateWeakRootsInNewSpaceWithClassIds(v8::PersistentHandleVisitor* v);
     136             : 
     137             :   // Iterates over weak roots on the heap.
     138             :   void IterateWeakRootsForFinalizers(RootVisitor* v);
     139             :   void IterateWeakRootsForPhantomHandles(
     140             :       WeakSlotCallbackWithHeap should_reset_handle);
     141             : 
     142             :   // Marks all handles that should be finalized based on the predicate
     143             :   // |should_reset_handle| as pending.
     144             :   void IdentifyWeakHandles(WeakSlotCallbackWithHeap should_reset_handle);
     145             : 
     146             :   // NOTE: Five ...NewSpace... functions below are used during
     147             :   // scavenge collections and iterate over sets of handles that are
     148             :   // guaranteed to contain all handles holding new space objects (but
     149             :   // may also include old space objects).
     150             : 
     151             :   // Iterates over strong and dependent handles. See the note above.
     152             :   void IterateNewSpaceStrongAndDependentRoots(RootVisitor* v);
     153             : 
     154             :   // Iterates over strong and dependent handles. See the note above.
     155             :   // Also marks unmodified nodes in the same iteration.
     156             :   void IterateNewSpaceStrongAndDependentRootsAndIdentifyUnmodified(
     157             :       RootVisitor* v, size_t start, size_t end);
     158             : 
     159             :   // Marks weak unmodified handles satisfying |is_dead| as pending.
     160             :   void MarkNewSpaceWeakUnmodifiedObjectsPending(
     161             :       WeakSlotCallbackWithHeap is_dead);
     162             : 
     163             :   // Iterates over weak independent or unmodified handles.
     164             :   // See the note above.
     165             :   void IterateNewSpaceWeakUnmodifiedRootsForFinalizers(RootVisitor* v);
     166             :   void IterateNewSpaceWeakUnmodifiedRootsForPhantomHandles(
     167             :       RootVisitor* v, WeakSlotCallbackWithHeap should_reset_handle);
     168             : 
     169             :   // Identify unmodified objects that are in weak state and marks them
     170             :   // unmodified
     171             :   void IdentifyWeakUnmodifiedObjects(WeakSlotCallback is_unmodified);
     172             : 
     173             :   // Tear down the global handle structure.
     174             :   void TearDown();
     175             : 
     176    13956144 :   Isolate* isolate() { return isolate_; }
     177             : 
     178             : #ifdef DEBUG
     179             :   void PrintStats();
     180             :   void Print();
     181             : #endif  // DEBUG
     182             : 
     183             :   void InvokeSecondPassPhantomCallbacks();
     184             : 
     185             :  private:
     186             :   // Internal node structures.
     187             :   class Node;
     188             :   template <class NodeType>
     189             :   class NodeBlock;
     190             :   template <class BlockType>
     191             :   class NodeIterator;
     192             :   template <class NodeType>
     193             :   class NodeSpace;
     194             :   class PendingPhantomCallback;
     195             : 
     196             :   explicit GlobalHandles(Isolate* isolate);
     197             : 
     198             :   void InvokeSecondPassPhantomCallbacksFromTask();
     199             :   int PostScavengeProcessing(int initial_post_gc_processing_count);
     200             :   int PostMarkSweepProcessing(int initial_post_gc_processing_count);
     201             :   void InvokeOrScheduleSecondPassPhantomCallbacks(bool synchronous_second_pass);
     202             :   void UpdateListOfNewSpaceNodes();
     203             :   void ApplyPersistentHandleVisitor(v8::PersistentHandleVisitor* visitor,
     204             :                                     Node* node);
     205             : 
     206             :   Isolate* isolate_;
     207             : 
     208             :   std::unique_ptr<NodeSpace<Node>> regular_nodes_;
     209             :   // Contains all nodes holding new space objects. Note: when the list
     210             :   // is accessed, some of the objects may have been promoted already.
     211             :   std::vector<Node*> new_space_nodes_;
     212             : 
     213             :   // Field always containing the number of handles to global objects.
     214             :   int number_of_global_handles_;
     215             : 
     216             :   int post_gc_processing_count_;
     217             : 
     218             :   size_t number_of_phantom_handle_resets_;
     219             : 
     220             :   std::vector<PendingPhantomCallback> pending_phantom_callbacks_;
     221             :   std::vector<PendingPhantomCallback> second_pass_callbacks_;
     222             :   bool second_pass_callbacks_task_posted_ = false;
     223             : 
     224             :   friend class Isolate;
     225             : 
     226             :   DISALLOW_COPY_AND_ASSIGN(GlobalHandles);
     227             : };
     228             : 
     229             : 
     230             : class GlobalHandles::PendingPhantomCallback {
     231             :  public:
     232             :   typedef v8::WeakCallbackInfo<void> Data;
     233             :   PendingPhantomCallback(
     234             :       Node* node, Data::Callback callback, void* parameter,
     235             :       void* embedder_fields[v8::kEmbedderFieldsInWeakCallback])
     236     3680826 :       : node_(node), callback_(callback), parameter_(parameter) {
     237     7361652 :     for (int i = 0; i < v8::kEmbedderFieldsInWeakCallback; ++i) {
     238     7361652 :       embedder_fields_[i] = embedder_fields[i];
     239             :     }
     240             :   }
     241             : 
     242             :   void Invoke(Isolate* isolate);
     243             : 
     244             :   Node* node() { return node_; }
     245             :   Data::Callback callback() { return callback_; }
     246             : 
     247             :  private:
     248             :   Node* node_;
     249             :   Data::Callback callback_;
     250             :   void* parameter_;
     251             :   void* embedder_fields_[v8::kEmbedderFieldsInWeakCallback];
     252             : };
     253             : 
     254             : 
     255             : class EternalHandles {
     256             :  public:
     257             :   EternalHandles();
     258             :   ~EternalHandles();
     259             : 
     260             :   int NumberOfHandles() { return size_; }
     261             : 
     262             :   // Create an EternalHandle, overwriting the index.
     263             :   void Create(Isolate* isolate, Object object, int* index);
     264             : 
     265             :   // Grab the handle for an existing EternalHandle.
     266             :   inline Handle<Object> Get(int index) {
     267             :     return Handle<Object>(GetLocation(index));
     268             :   }
     269             : 
     270             :   // Iterates over all handles.
     271             :   void IterateAllRoots(RootVisitor* visitor);
     272             :   // Iterates over all handles which might be in new space.
     273             :   void IterateNewSpaceRoots(RootVisitor* visitor);
     274             :   // Rebuilds new space list.
     275             :   void PostGarbageCollectionProcessing();
     276             : 
     277             :  private:
     278             :   static const int kInvalidIndex = -1;
     279             :   static const int kShift = 8;
     280             :   static const int kSize = 1 << kShift;
     281             :   static const int kMask = 0xff;
     282             : 
     283             :   // Gets the slot for an index. This returns an Address* rather than an
     284             :   // ObjectSlot in order to avoid #including slots.h in this header file.
     285             :   inline Address* GetLocation(int index) {
     286             :     DCHECK(index >= 0 && index < size_);
     287      152822 :     return &blocks_[index >> kShift][index & kMask];
     288             :   }
     289             : 
     290             :   int size_;
     291             :   std::vector<Address*> blocks_;
     292             :   std::vector<int> new_space_indices_;
     293             : 
     294             :   DISALLOW_COPY_AND_ASSIGN(EternalHandles);
     295             : };
     296             : 
     297             : 
     298             : }  // namespace internal
     299             : }  // namespace v8
     300             : 
     301             : #endif  // V8_GLOBAL_HANDLES_H_

Generated by: LCOV version 1.10