LCOV - code coverage report
Current view: top level - src - global-handles.h (source / functions) Hit Total Coverage
Test: app.info Lines: 7 7 100.0 %
Date: 2019-04-17 Functions: 0 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 <utility>
      10             : #include <vector>
      11             : 
      12             : #include "include/v8.h"
      13             : #include "include/v8-profiler.h"
      14             : 
      15             : #include "src/handles.h"
      16             : #include "src/objects.h"
      17             : #include "src/utils.h"
      18             : 
      19             : namespace v8 {
      20             : namespace internal {
      21             : 
      22             : class HeapStats;
      23             : class RootVisitor;
      24             : 
      25             : enum WeaknessType {
      26             :   // Embedder gets a handle to the dying object.
      27             :   FINALIZER_WEAK,
      28             :   // In the following cases, the embedder gets the parameter they passed in
      29             :   // earlier, and 0 or 2 first embedder fields. Note that the internal
      30             :   // fields must contain aligned non-V8 pointers.  Getting pointers to V8
      31             :   // objects through this interface would be GC unsafe so in that case the
      32             :   // embedder gets a null pointer instead.
      33             :   PHANTOM_WEAK,
      34             :   PHANTOM_WEAK_2_EMBEDDER_FIELDS,
      35             :   // The handle is automatically reset by the garbage collector when
      36             :   // the object is no longer reachable.
      37             :   PHANTOM_WEAK_RESET_HANDLE
      38             : };
      39             : 
      40             : // Global handles hold handles that are independent of stack-state and can have
      41             : // callbacks and finalizers attached to them.
      42             : class V8_EXPORT_PRIVATE GlobalHandles final {
      43             :  public:
      44             :   template <class NodeType>
      45             :   class NodeBlock;
      46             : 
      47             :   //
      48             :   // API for regular handles.
      49             :   //
      50             : 
      51             :   static void MoveGlobal(Address** from, Address** to);
      52             : 
      53             :   static Handle<Object> CopyGlobal(Address* location);
      54             : 
      55             :   static void Destroy(Address* location);
      56             : 
      57             :   // Make the global handle weak and set the callback parameter for the
      58             :   // handle.  When the garbage collector recognizes that only weak global
      59             :   // handles point to an object the callback function is invoked (for each
      60             :   // handle) with the handle and corresponding parameter as arguments.  By
      61             :   // default the handle still contains a pointer to the object that is being
      62             :   // collected.  For this reason the object is not collected until the next
      63             :   // GC.  For a phantom weak handle the handle is cleared (set to a Smi)
      64             :   // before the callback is invoked, but the handle can still be identified
      65             :   // in the callback by using the location() of the handle.
      66             :   static void MakeWeak(Address* location, void* parameter,
      67             :                        WeakCallbackInfo<void>::Callback weak_callback,
      68             :                        v8::WeakCallbackType type);
      69             :   static void MakeWeak(Address** location_addr);
      70             : 
      71             :   static void AnnotateStrongRetainer(Address* location, const char* label);
      72             : 
      73             :   // Clear the weakness of a global handle.
      74             :   static void* ClearWeakness(Address* location);
      75             : 
      76             :   // Tells whether global handle is weak.
      77             :   static bool IsWeak(Address* location);
      78             : 
      79             :   //
      80             :   // API for traced handles.
      81             :   //
      82             : 
      83             :   static void MoveTracedGlobal(Address** from, Address** to);
      84             :   static void DestroyTraced(Address* location);
      85             :   static void SetFinalizationCallbackForTraced(
      86             :       Address* location, void* parameter,
      87             :       WeakCallbackInfo<void>::Callback callback);
      88             : 
      89             :   explicit GlobalHandles(Isolate* isolate);
      90             :   ~GlobalHandles();
      91             : 
      92             :   // Creates a new global handle that is alive until Destroy is called.
      93             :   Handle<Object> Create(Object value);
      94             :   Handle<Object> Create(Address value);
      95             : 
      96             :   template <typename T>
      97             :   Handle<T> Create(T value) {
      98             :     static_assert(std::is_base_of<Object, T>::value, "static type violation");
      99             :     // The compiler should only pick this method if T is not Object.
     100             :     static_assert(!std::is_same<Object, T>::value, "compiler error");
     101     3928389 :     return Handle<T>::cast(Create(Object(value)));
     102             :   }
     103             : 
     104             :   Handle<Object> CreateTraced(Object value, Address* slot);
     105             :   Handle<Object> CreateTraced(Address value, Address* slot);
     106             : 
     107             :   void RecordStats(HeapStats* stats);
     108             : 
     109             :   size_t InvokeFirstPassWeakCallbacks();
     110             :   void InvokeSecondPassPhantomCallbacks();
     111             : 
     112             :   // Process pending weak handles.
     113             :   // Returns the number of freed nodes.
     114             :   size_t PostGarbageCollectionProcessing(
     115             :       GarbageCollector collector, const v8::GCCallbackFlags gc_callback_flags);
     116             : 
     117             :   void IterateStrongRoots(RootVisitor* v);
     118             :   void IterateWeakRoots(RootVisitor* v);
     119             :   void IterateAllRoots(RootVisitor* v);
     120             :   void IterateAllYoungRoots(RootVisitor* v);
     121             : 
     122             :   // Iterates over all handles that have embedder-assigned class ID.
     123             :   void IterateAllRootsWithClassIds(v8::PersistentHandleVisitor* v);
     124             : 
     125             :   // Iterates over all handles in the new space that have embedder-assigned
     126             :   // class ID.
     127             :   void IterateAllYoungRootsWithClassIds(v8::PersistentHandleVisitor* v);
     128             : 
     129             :   // Iterate over all handles in the new space that are weak, unmodified
     130             :   // and have class IDs
     131             :   void IterateYoungWeakRootsWithClassIds(v8::PersistentHandleVisitor* v);
     132             : 
     133             :   // Iterates over all traces handles represented by TracedGlobal.
     134             :   void IterateTracedNodes(
     135             :       v8::EmbedderHeapTracer::TracedGlobalHandleVisitor* visitor);
     136             : 
     137             :   // Marks handles with finalizers on the predicate |should_reset_handle| as
     138             :   // pending.
     139             :   void IterateWeakRootsIdentifyFinalizers(
     140             :       WeakSlotCallbackWithHeap should_reset_handle);
     141             :   // Uses the provided visitor |v| to mark handles with finalizers that are
     142             :   // pending.
     143             :   void IterateWeakRootsForFinalizers(RootVisitor* v);
     144             :   // Marks handles that are phantom or have callbacks based on the predicate
     145             :   // |should_reset_handle| as pending.
     146             :   void IterateWeakRootsForPhantomHandles(
     147             :       WeakSlotCallbackWithHeap should_reset_handle);
     148             : 
     149             :   //  Note: The following *Young* methods are used for the Scavenger to
     150             :   //  identify and process handles in the young generation. The set of young
     151             :   //  handles is complete but the methods may encounter handles that are
     152             :   //  already in old space.
     153             : 
     154             :   // Iterates over strong and dependent handles. See the note above.
     155             :   void IterateYoungStrongAndDependentRoots(RootVisitor* v);
     156             : 
     157             :   // Marks weak unmodified handles satisfying |is_dead| as pending.
     158             :   void MarkYoungWeakUnmodifiedObjectsPending(WeakSlotCallbackWithHeap is_dead);
     159             : 
     160             :   // Iterates over weak independent or unmodified handles.
     161             :   // See the note above.
     162             :   void IterateYoungWeakUnmodifiedRootsForFinalizers(RootVisitor* v);
     163             :   void IterateYoungWeakUnmodifiedRootsForPhantomHandles(
     164             :       RootVisitor* v, WeakSlotCallbackWithHeap should_reset_handle);
     165             : 
     166             :   // Identify unmodified objects that are in weak state and marks them
     167             :   // unmodified
     168             :   void IdentifyWeakUnmodifiedObjects(WeakSlotCallback is_unmodified);
     169             : 
     170             :   Isolate* isolate() const { return isolate_; }
     171             : 
     172             :   // Number of global handles.
     173             :   size_t handles_count() const { return handles_count_; }
     174             : 
     175             :   size_t GetAndResetGlobalHandleResetCount() {
     176          15 :     size_t old = number_of_phantom_handle_resets_;
     177          15 :     number_of_phantom_handle_resets_ = 0;
     178             :     return old;
     179             :   }
     180             : 
     181             : #ifdef DEBUG
     182             :   void PrintStats();
     183             :   void Print();
     184             : #endif  // DEBUG
     185             : 
     186             :  private:
     187             :   // Internal node structures.
     188             :   class Node;
     189             :   template <class BlockType>
     190             :   class NodeIterator;
     191             :   template <class NodeType>
     192             :   class NodeSpace;
     193             :   class PendingPhantomCallback;
     194             :   class TracedNode;
     195             : 
     196             :   bool InRecursiveGC(unsigned gc_processing_counter);
     197             : 
     198             :   void InvokeSecondPassPhantomCallbacksFromTask();
     199             :   void InvokeOrScheduleSecondPassPhantomCallbacks(bool synchronous_second_pass);
     200             :   size_t PostScavengeProcessing(unsigned post_processing_count);
     201             :   size_t PostMarkSweepProcessing(unsigned post_processing_count);
     202             : 
     203             :   template <typename T>
     204             :   size_t InvokeFirstPassWeakCallbacks(
     205             :       std::vector<std::pair<T*, PendingPhantomCallback>>* pending);
     206             : 
     207             :   template <typename T>
     208             :   void UpdateAndCompactListOfYoungNode(std::vector<T*>* node_list);
     209             :   void UpdateListOfYoungNodes();
     210             : 
     211             :   void ApplyPersistentHandleVisitor(v8::PersistentHandleVisitor* visitor,
     212             :                                     Node* node);
     213             : 
     214             :   Isolate* const isolate_;
     215             : 
     216             :   std::unique_ptr<NodeSpace<Node>> regular_nodes_;
     217             :   // Contains all nodes holding young objects. Note: when the list
     218             :   // is accessed, some of the objects may have been promoted already.
     219             :   std::vector<Node*> young_nodes_;
     220             : 
     221             :   std::unique_ptr<NodeSpace<TracedNode>> traced_nodes_;
     222             :   std::vector<TracedNode*> traced_young_nodes_;
     223             : 
     224             :   // Field always containing the number of handles to global objects.
     225             :   size_t handles_count_ = 0;
     226             :   size_t number_of_phantom_handle_resets_ = 0;
     227             : 
     228             :   std::vector<std::pair<Node*, PendingPhantomCallback>>
     229             :       regular_pending_phantom_callbacks_;
     230             :   std::vector<std::pair<TracedNode*, PendingPhantomCallback>>
     231             :       traced_pending_phantom_callbacks_;
     232             :   std::vector<PendingPhantomCallback> second_pass_callbacks_;
     233             :   bool second_pass_callbacks_task_posted_ = false;
     234             : 
     235             :   // Counter for recursive garbage collections during callback processing.
     236             :   unsigned post_gc_processing_count_ = 0;
     237             : 
     238             :   DISALLOW_COPY_AND_ASSIGN(GlobalHandles);
     239             : };
     240             : 
     241             : class GlobalHandles::PendingPhantomCallback final {
     242             :  public:
     243             :   typedef v8::WeakCallbackInfo<void> Data;
     244             : 
     245             :   enum InvocationType { kFirstPass, kSecondPass };
     246             : 
     247             :   PendingPhantomCallback(
     248             :       Data::Callback callback, void* parameter,
     249             :       void* embedder_fields[v8::kEmbedderFieldsInWeakCallback])
     250             :       : callback_(callback), parameter_(parameter) {
     251    15282605 :     for (int i = 0; i < v8::kEmbedderFieldsInWeakCallback; ++i) {
     252     6113042 :       embedder_fields_[i] = embedder_fields[i];
     253             :     }
     254             :   }
     255             : 
     256             :   void Invoke(Isolate* isolate, InvocationType type);
     257             : 
     258             :   Data::Callback callback() const { return callback_; }
     259             : 
     260             :  private:
     261             :   Data::Callback callback_;
     262             :   void* parameter_;
     263             :   void* embedder_fields_[v8::kEmbedderFieldsInWeakCallback];
     264             : };
     265             : 
     266             : class EternalHandles final {
     267             :  public:
     268             :   EternalHandles() = default;
     269             :   ~EternalHandles();
     270             : 
     271             :   // Create an EternalHandle, overwriting the index.
     272             :   V8_EXPORT_PRIVATE void Create(Isolate* isolate, Object object, int* index);
     273             : 
     274             :   // Grab the handle for an existing EternalHandle.
     275             :   inline Handle<Object> Get(int index) {
     276             :     return Handle<Object>(GetLocation(index));
     277             :   }
     278             : 
     279             :   // Iterates over all handles.
     280             :   void IterateAllRoots(RootVisitor* visitor);
     281             :   // Iterates over all handles which might be in the young generation.
     282             :   void IterateYoungRoots(RootVisitor* visitor);
     283             :   // Rebuilds new space list.
     284             :   void PostGarbageCollectionProcessing();
     285             : 
     286          15 :   size_t handles_count() const { return size_; }
     287             : 
     288             :  private:
     289             :   static const int kInvalidIndex = -1;
     290             :   static const int kShift = 8;
     291             :   static const int kSize = 1 << kShift;
     292             :   static const int kMask = 0xff;
     293             : 
     294             :   // Gets the slot for an index. This returns an Address* rather than an
     295             :   // ObjectSlot in order to avoid #including slots.h in this header file.
     296             :   inline Address* GetLocation(int index) {
     297             :     DCHECK(index >= 0 && index < size_);
     298      152470 :     return &blocks_[index >> kShift][index & kMask];
     299             :   }
     300             : 
     301             :   int size_ = 0;
     302             :   std::vector<Address*> blocks_;
     303             :   std::vector<int> young_node_indices_;
     304             : 
     305             :   DISALLOW_COPY_AND_ASSIGN(EternalHandles);
     306             : };
     307             : 
     308             : }  // namespace internal
     309             : }  // namespace v8
     310             : 
     311             : #endif  // V8_GLOBAL_HANDLES_H_

Generated by: LCOV version 1.10