LCOV - code coverage report
Current view: top level - src - global-handles.h (source / functions) Hit Total Coverage
Test: app.info Lines: 14 14 100.0 %
Date: 2017-04-26 Functions: 4 4 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             : 
      10             : #include "include/v8.h"
      11             : #include "include/v8-profiler.h"
      12             : 
      13             : #include "src/handles.h"
      14             : #include "src/list.h"
      15             : #include "src/utils.h"
      16             : 
      17             : namespace v8 {
      18             : namespace internal {
      19             : 
      20             : class HeapStats;
      21             : class RootVisitor;
      22             : 
      23             : // Structure for tracking global handles.
      24             : // A single list keeps all the allocated global handles.
      25             : // Destroyed handles stay in the list but is added to the free list.
      26             : // At GC the destroyed global handles are removed from the free list
      27             : // and deallocated.
      28             : 
      29             : enum WeaknessType {
      30             :   // Embedder gets a handle to the dying object.
      31             :   FINALIZER_WEAK,
      32             :   // In the following cases, the embedder gets the parameter they passed in
      33             :   // earlier, and 0 or 2 first embedder fields. Note that the internal
      34             :   // fields must contain aligned non-V8 pointers.  Getting pointers to V8
      35             :   // objects through this interface would be GC unsafe so in that case the
      36             :   // embedder gets a null pointer instead.
      37             :   PHANTOM_WEAK,
      38             :   PHANTOM_WEAK_2_EMBEDDER_FIELDS,
      39             :   // The handle is automatically reset by the garbage collector when
      40             :   // the object is no longer reachable.
      41             :   PHANTOM_WEAK_RESET_HANDLE
      42             : };
      43             : 
      44             : class GlobalHandles {
      45             :  public:
      46             :   enum IterationMode {
      47             :     HANDLE_PHANTOM_NODES_VISIT_OTHERS,
      48             :     VISIT_OTHERS,
      49             :     HANDLE_PHANTOM_NODES
      50             :   };
      51             : 
      52             :   ~GlobalHandles();
      53             : 
      54             :   // Creates a new global handle that is alive until Destroy is called.
      55             :   Handle<Object> Create(Object* value);
      56             : 
      57             :   template <typename T>
      58       48439 :   Handle<T> Create(T* value) {
      59             :     static_assert(std::is_base_of<Object, T>::value, "static type violation");
      60             :     // The compiler should only pick this method if T is not Object.
      61             :     static_assert(!std::is_same<Object, T>::value, "compiler error");
      62      196449 :     return Handle<T>::cast(Create(static_cast<Object*>(value)));
      63             :   }
      64             : 
      65             :   // Copy a global handle
      66             :   static Handle<Object> CopyGlobal(Object** location);
      67             : 
      68             :   // Destroy a global handle.
      69             :   static void Destroy(Object** location);
      70             : 
      71             :   // Make the global handle weak and set the callback parameter for the
      72             :   // handle.  When the garbage collector recognizes that only weak global
      73             :   // handles point to an object the callback function is invoked (for each
      74             :   // handle) with the handle and corresponding parameter as arguments.  By
      75             :   // default the handle still contains a pointer to the object that is being
      76             :   // collected.  For this reason the object is not collected until the next
      77             :   // GC.  For a phantom weak handle the handle is cleared (set to a Smi)
      78             :   // before the callback is invoked, but the handle can still be identified
      79             :   // in the callback by using the location() of the handle.
      80             :   static void MakeWeak(Object** location, void* parameter,
      81             :                        WeakCallbackInfo<void>::Callback weak_callback,
      82             :                        v8::WeakCallbackType type);
      83             : 
      84             :   static void MakeWeak(Object*** location_addr);
      85             : 
      86             :   void RecordStats(HeapStats* stats);
      87             : 
      88             :   // Returns the current number of weak handles.
      89             :   int NumberOfWeakHandles();
      90             : 
      91             :   // Returns the current number of weak handles to global objects.
      92             :   // These handles are also included in NumberOfWeakHandles().
      93             :   int NumberOfGlobalObjectWeakHandles();
      94             : 
      95             :   // Returns the current number of handles to global objects.
      96             :   int global_handles_count() const {
      97             :     return number_of_global_handles_;
      98             :   }
      99             : 
     100             :   size_t NumberOfPhantomHandleResets() {
     101             :     return number_of_phantom_handle_resets_;
     102             :   }
     103             : 
     104             :   void ResetNumberOfPhantomHandleResets() {
     105          18 :     number_of_phantom_handle_resets_ = 0;
     106             :   }
     107             : 
     108             :   // Clear the weakness of a global handle.
     109             :   static void* ClearWeakness(Object** location);
     110             : 
     111             :   // Mark the reference to this object independent.
     112             :   static void MarkIndependent(Object** location);
     113             : 
     114             :   static bool IsIndependent(Object** location);
     115             : 
     116             :   // Tells whether global handle is near death.
     117             :   static bool IsNearDeath(Object** location);
     118             : 
     119             :   // Tells whether global handle is weak.
     120             :   static bool IsWeak(Object** location);
     121             : 
     122             :   // Process pending weak handles.
     123             :   // Returns the number of freed nodes.
     124             :   int PostGarbageCollectionProcessing(
     125             :       GarbageCollector collector, const v8::GCCallbackFlags gc_callback_flags);
     126             : 
     127             :   // Iterates over all strong handles.
     128             :   void IterateStrongRoots(RootVisitor* v);
     129             : 
     130             :   // Iterates over all handles.
     131             :   void IterateAllRoots(RootVisitor* v);
     132             : 
     133             :   // Iterates over all handles that have embedder-assigned class ID.
     134             :   void IterateAllRootsWithClassIds(v8::PersistentHandleVisitor* v);
     135             : 
     136             :   // Iterates over all handles in the new space that have embedder-assigned
     137             :   // class ID.
     138             :   void IterateAllRootsInNewSpaceWithClassIds(v8::PersistentHandleVisitor* v);
     139             : 
     140             :   // Iterate over all handles in the new space that are weak, unmodified
     141             :   // and have class IDs
     142             :   void IterateWeakRootsInNewSpaceWithClassIds(v8::PersistentHandleVisitor* v);
     143             : 
     144             :   // Iterates over all weak roots in heap.
     145             :   void IterateWeakRoots(RootVisitor* v);
     146             : 
     147             :   // Find all weak handles satisfying the callback predicate, mark
     148             :   // them as pending.
     149             :   void IdentifyWeakHandles(WeakSlotCallback f);
     150             : 
     151             :   // NOTE: Five ...NewSpace... functions below are used during
     152             :   // scavenge collections and iterate over sets of handles that are
     153             :   // guaranteed to contain all handles holding new space objects (but
     154             :   // may also include old space objects).
     155             : 
     156             :   // Iterates over strong and dependent handles. See the node above.
     157             :   void IterateNewSpaceStrongAndDependentRoots(RootVisitor* v);
     158             : 
     159             :   // Finds weak independent or partially independent handles satisfying
     160             :   // the callback predicate and marks them as pending. See the note above.
     161             :   void IdentifyNewSpaceWeakIndependentHandles(WeakSlotCallbackWithHeap f);
     162             : 
     163             :   // Iterates over weak independent or partially independent handles.
     164             :   // See the note above.
     165             :   void IterateNewSpaceWeakIndependentRoots(RootVisitor* v);
     166             : 
     167             :   // Finds weak independent or unmodified handles satisfying
     168             :   // the callback predicate and marks them as pending. See the note above.
     169             :   void MarkNewSpaceWeakUnmodifiedObjectsPending(
     170             :       WeakSlotCallbackWithHeap is_unscavenged);
     171             : 
     172             :   // Iterates over weak independent or unmodified handles.
     173             :   // See the note above.
     174             :   template <IterationMode mode>
     175             :   void IterateNewSpaceWeakUnmodifiedRoots(RootVisitor* v);
     176             : 
     177             :   // Identify unmodified objects that are in weak state and marks them
     178             :   // unmodified
     179             :   void IdentifyWeakUnmodifiedObjects(WeakSlotCallback is_unmodified);
     180             : 
     181             :   // Tear down the global handle structure.
     182             :   void TearDown();
     183             : 
     184             :   Isolate* isolate() { return isolate_; }
     185             : 
     186             : #ifdef DEBUG
     187             :   void PrintStats();
     188             :   void Print();
     189             : #endif  // DEBUG
     190             : 
     191             :  private:
     192             :   // Internal node structures.
     193             :   class Node;
     194             :   class NodeBlock;
     195             :   class NodeIterator;
     196             :   class PendingPhantomCallback;
     197             :   class PendingPhantomCallbacksSecondPassTask;
     198             : 
     199             :   explicit GlobalHandles(Isolate* isolate);
     200             : 
     201             :   // Helpers for PostGarbageCollectionProcessing.
     202             :   static void InvokeSecondPassPhantomCallbacks(
     203             :       List<PendingPhantomCallback>* callbacks, Isolate* isolate);
     204             :   int PostScavengeProcessing(int initial_post_gc_processing_count);
     205             :   int PostMarkSweepProcessing(int initial_post_gc_processing_count);
     206             :   int DispatchPendingPhantomCallbacks(bool synchronous_second_pass);
     207             :   void UpdateListOfNewSpaceNodes();
     208             :   void ApplyPersistentHandleVisitor(v8::PersistentHandleVisitor* visitor,
     209             :                                     Node* node);
     210             : 
     211             :   Isolate* isolate_;
     212             : 
     213             :   // Field always containing the number of handles to global objects.
     214             :   int number_of_global_handles_;
     215             : 
     216             :   // List of all allocated node blocks.
     217             :   NodeBlock* first_block_;
     218             : 
     219             :   // List of node blocks with used nodes.
     220             :   NodeBlock* first_used_block_;
     221             : 
     222             :   // Free list of nodes.
     223             :   Node* first_free_;
     224             : 
     225             :   // Contains all nodes holding new space objects. Note: when the list
     226             :   // is accessed, some of the objects may have been promoted already.
     227             :   List<Node*> new_space_nodes_;
     228             : 
     229             :   int post_gc_processing_count_;
     230             : 
     231             :   size_t number_of_phantom_handle_resets_;
     232             : 
     233             :   List<PendingPhantomCallback> pending_phantom_callbacks_;
     234             : 
     235             :   friend class Isolate;
     236             : 
     237             :   DISALLOW_COPY_AND_ASSIGN(GlobalHandles);
     238             : };
     239             : 
     240             : 
     241             : class GlobalHandles::PendingPhantomCallback {
     242             :  public:
     243             :   typedef v8::WeakCallbackInfo<void> Data;
     244             :   PendingPhantomCallback(
     245             :       Node* node, Data::Callback callback, void* parameter,
     246             :       void* embedder_fields[v8::kEmbedderFieldsInWeakCallback])
     247       16016 :       : node_(node), callback_(callback), parameter_(parameter) {
     248       32032 :     for (int i = 0; i < v8::kEmbedderFieldsInWeakCallback; ++i) {
     249       32032 :       embedder_fields_[i] = embedder_fields[i];
     250             :     }
     251             :   }
     252             : 
     253             :   void Invoke(Isolate* isolate);
     254             : 
     255             :   Node* node() { return node_; }
     256             :   Data::Callback callback() { return callback_; }
     257             : 
     258             :  private:
     259             :   Node* node_;
     260             :   Data::Callback callback_;
     261             :   void* parameter_;
     262             :   void* embedder_fields_[v8::kEmbedderFieldsInWeakCallback];
     263             : };
     264             : 
     265             : 
     266             : class EternalHandles {
     267             :  public:
     268             :   enum SingletonHandle {
     269             :     DATE_CACHE_VERSION,
     270             : 
     271             :     NUMBER_OF_SINGLETON_HANDLES
     272             :   };
     273             : 
     274             :   EternalHandles();
     275             :   ~EternalHandles();
     276             : 
     277             :   int NumberOfHandles() { return size_; }
     278             : 
     279             :   // Create an EternalHandle, overwriting the index.
     280             :   void Create(Isolate* isolate, Object* object, int* index);
     281             : 
     282             :   // Grab the handle for an existing EternalHandle.
     283             :   inline Handle<Object> Get(int index) {
     284             :     return Handle<Object>(GetLocation(index));
     285             :   }
     286             : 
     287             :   // Grab the handle for an existing SingletonHandle.
     288      114008 :   inline Handle<Object> GetSingleton(SingletonHandle singleton) {
     289             :     DCHECK(Exists(singleton));
     290      228016 :     return Get(singleton_handles_[singleton]);
     291             :   }
     292             : 
     293             :   // Checks whether a SingletonHandle has been assigned.
     294      114008 :   inline bool Exists(SingletonHandle singleton) {
     295      114015 :     return singleton_handles_[singleton] != kInvalidIndex;
     296             :   }
     297             : 
     298             :   // Assign a SingletonHandle to an empty slot and returns the handle.
     299          98 :   Handle<Object> CreateSingleton(Isolate* isolate,
     300             :                                  Object* object,
     301             :                                  SingletonHandle singleton) {
     302          98 :     Create(isolate, object, &singleton_handles_[singleton]);
     303         196 :     return Get(singleton_handles_[singleton]);
     304             :   }
     305             : 
     306             :   // Iterates over all handles.
     307             :   void IterateAllRoots(RootVisitor* visitor);
     308             :   // Iterates over all handles which might be in new space.
     309             :   void IterateNewSpaceRoots(RootVisitor* visitor);
     310             :   // Rebuilds new space list.
     311             :   void PostGarbageCollectionProcessing(Heap* heap);
     312             : 
     313             :  private:
     314             :   static const int kInvalidIndex = -1;
     315             :   static const int kShift = 8;
     316             :   static const int kSize = 1 << kShift;
     317             :   static const int kMask = 0xff;
     318             : 
     319             :   // Gets the slot for an index
     320             :   inline Object** GetLocation(int index) {
     321             :     DCHECK(index >= 0 && index < size_);
     322      386962 :     return &blocks_[index >> kShift][index & kMask];
     323             :   }
     324             : 
     325             :   int size_;
     326             :   List<Object**> blocks_;
     327             :   List<int> new_space_indices_;
     328             :   int singleton_handles_[NUMBER_OF_SINGLETON_HANDLES];
     329             : 
     330             :   DISALLOW_COPY_AND_ASSIGN(EternalHandles);
     331             : };
     332             : 
     333             : 
     334             : }  // namespace internal
     335             : }  // namespace v8
     336             : 
     337             : #endif  // V8_GLOBAL_HANDLES_H_

Generated by: LCOV version 1.10