LCOV - code coverage report
Current view: top level - src/heap - scavenger.h (source / functions) Hit Total Coverage
Test: app.info Lines: 8 9 88.9 %
Date: 2019-02-19 Functions: 3 8 37.5 %

          Line data    Source code
       1             : // Copyright 2015 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_HEAP_SCAVENGER_H_
       6             : #define V8_HEAP_SCAVENGER_H_
       7             : 
       8             : #include "src/base/platform/condition-variable.h"
       9             : #include "src/heap/local-allocator.h"
      10             : #include "src/heap/objects-visiting.h"
      11             : #include "src/heap/slot-set.h"
      12             : #include "src/heap/worklist.h"
      13             : 
      14             : namespace v8 {
      15             : namespace internal {
      16             : 
      17             : class OneshotBarrier;
      18             : 
      19             : enum class CopyAndForwardResult {
      20             :   SUCCESS_YOUNG_GENERATION,
      21             :   SUCCESS_OLD_GENERATION,
      22             :   FAILURE
      23             : };
      24             : 
      25             : using ObjectAndSize = std::pair<HeapObject, int>;
      26             : using SurvivingNewLargeObjectsMap =
      27             :     std::unordered_map<HeapObject, Map, Object::Hasher>;
      28             : using SurvivingNewLargeObjectMapEntry = std::pair<HeapObject, Map>;
      29             : 
      30      122068 : class ScavengerCollector {
      31             :  public:
      32             :   static const int kMaxScavengerTasks = 8;
      33             :   static const int kMaxWaitTimeMs = 2;
      34             : 
      35             :   explicit ScavengerCollector(Heap* heap);
      36             : 
      37             :   void CollectGarbage();
      38             : 
      39             :  private:
      40             :   void MergeSurvivingNewLargeObjects(
      41             :       const SurvivingNewLargeObjectsMap& objects);
      42             : 
      43             :   int NumberOfScavengeTasks();
      44             : 
      45             :   void HandleSurvivingNewLargeObjects();
      46             : 
      47             :   Isolate* const isolate_;
      48             :   Heap* const heap_;
      49             :   base::Semaphore parallel_scavenge_semaphore_;
      50             :   SurvivingNewLargeObjectsMap surviving_new_large_objects_;
      51             : 
      52             :   friend class Scavenger;
      53             : };
      54             : 
      55      113550 : class Scavenger {
      56             :  public:
      57      426697 :   struct PromotionListEntry {
      58             :     HeapObject heap_object;
      59             :     Map map;
      60             :     int size;
      61             :   };
      62             : 
      63       23490 :   class PromotionList {
      64             :    public:
      65             :     class View {
      66             :      public:
      67             :       View(PromotionList* promotion_list, int task_id)
      68       37850 :           : promotion_list_(promotion_list), task_id_(task_id) {}
      69             : 
      70             :       inline void PushRegularObject(HeapObject object, int size);
      71             :       inline void PushLargeObject(HeapObject object, Map map, int size);
      72             :       inline bool IsEmpty();
      73             :       inline size_t LocalPushSegmentSize();
      74             :       inline bool Pop(struct PromotionListEntry* entry);
      75             :       inline bool IsGlobalPoolEmpty();
      76             :       inline bool ShouldEagerlyProcessPromotionList();
      77             : 
      78             :      private:
      79             :       PromotionList* promotion_list_;
      80             :       int task_id_;
      81             :     };
      82             : 
      83             :     explicit PromotionList(int num_tasks)
      84             :         : regular_object_promotion_list_(num_tasks),
      85       23490 :           large_object_promotion_list_(num_tasks) {}
      86             : 
      87             :     inline void PushRegularObject(int task_id, HeapObject object, int size);
      88             :     inline void PushLargeObject(int task_id, HeapObject object, Map map,
      89             :                                 int size);
      90             :     inline bool IsEmpty();
      91             :     inline size_t LocalPushSegmentSize(int task_id);
      92             :     inline bool Pop(int task_id, struct PromotionListEntry* entry);
      93             :     inline bool IsGlobalPoolEmpty();
      94             :     inline bool ShouldEagerlyProcessPromotionList(int task_id);
      95             : 
      96             :    private:
      97             :     static const int kRegularObjectPromotionListSegmentSize = 256;
      98             :     static const int kLargeObjectPromotionListSegmentSize = 4;
      99             : 
     100             :     using RegularObjectPromotionList =
     101             :         Worklist<ObjectAndSize, kRegularObjectPromotionListSegmentSize>;
     102             :     using LargeObjectPromotionList =
     103             :         Worklist<PromotionListEntry, kLargeObjectPromotionListSegmentSize>;
     104             : 
     105             :     RegularObjectPromotionList regular_object_promotion_list_;
     106             :     LargeObjectPromotionList large_object_promotion_list_;
     107             :   };
     108             : 
     109             :   static const int kCopiedListSegmentSize = 256;
     110             : 
     111             :   using CopiedList = Worklist<ObjectAndSize, kCopiedListSegmentSize>;
     112             : 
     113             :   Scavenger(ScavengerCollector* collector, Heap* heap, bool is_logging,
     114             :             CopiedList* copied_list, PromotionList* promotion_list,
     115             :             int task_id);
     116             : 
     117             :   // Entry point for scavenging an old generation page. For scavenging single
     118             :   // objects see RootScavengingVisitor and ScavengeVisitor below.
     119             :   void ScavengePage(MemoryChunk* page);
     120             : 
     121             :   // Processes remaining work (=objects) after single objects have been
     122             :   // manually scavenged using ScavengeObject or CheckAndScavengeObject.
     123             :   void Process(OneshotBarrier* barrier = nullptr);
     124             : 
     125             :   // Finalize the Scavenger. Needs to be called from the main thread.
     126             :   void Finalize();
     127             : 
     128             :   size_t bytes_copied() const { return copied_size_; }
     129             :   size_t bytes_promoted() const { return promoted_size_; }
     130             : 
     131             :  private:
     132             :   // Number of objects to process before interrupting for potentially waking
     133             :   // up other tasks.
     134             :   static const int kInterruptThreshold = 128;
     135             :   static const int kInitialLocalPretenuringFeedbackCapacity = 256;
     136             : 
     137   232744506 :   inline Heap* heap() { return heap_; }
     138             : 
     139             :   inline void PageMemoryFence(MaybeObject object);
     140             : 
     141             :   void AddPageToSweeperIfNecessary(MemoryChunk* page);
     142             : 
     143             :   // Potentially scavenges an object referenced from |slot| if it is
     144             :   // indeed a HeapObject and resides in from space.
     145             :   template <typename TSlot>
     146             :   inline SlotCallbackResult CheckAndScavengeObject(Heap* heap, TSlot slot);
     147             : 
     148             :   // Scavenges an object |object| referenced from slot |p|. |object| is required
     149             :   // to be in from space.
     150             :   template <typename THeapObjectSlot>
     151             :   inline SlotCallbackResult ScavengeObject(THeapObjectSlot p,
     152             :                                            HeapObject object);
     153             : 
     154             :   // Copies |source| to |target| and sets the forwarding pointer in |source|.
     155             :   V8_INLINE bool MigrateObject(Map map, HeapObject source, HeapObject target,
     156             :                                int size);
     157             : 
     158             :   V8_INLINE SlotCallbackResult
     159             :   RememberedSetEntryNeeded(CopyAndForwardResult result);
     160             : 
     161             :   template <typename THeapObjectSlot>
     162             :   V8_INLINE CopyAndForwardResult
     163             :   SemiSpaceCopyObject(Map map, THeapObjectSlot slot, HeapObject object,
     164             :                       int object_size, ObjectFields object_fields);
     165             : 
     166             :   template <typename THeapObjectSlot>
     167             :   V8_INLINE CopyAndForwardResult PromoteObject(Map map, THeapObjectSlot slot,
     168             :                                                HeapObject object,
     169             :                                                int object_size,
     170             :                                                ObjectFields object_fields);
     171             : 
     172             :   template <typename THeapObjectSlot>
     173             :   V8_INLINE SlotCallbackResult EvacuateObject(THeapObjectSlot slot, Map map,
     174             :                                               HeapObject source);
     175             : 
     176             :   V8_INLINE bool HandleLargeObject(Map map, HeapObject object, int object_size,
     177             :                                    ObjectFields object_fields);
     178             : 
     179             :   // Different cases for object evacuation.
     180             :   template <typename THeapObjectSlot>
     181             :   V8_INLINE SlotCallbackResult
     182             :   EvacuateObjectDefault(Map map, THeapObjectSlot slot, HeapObject object,
     183             :                         int object_size, ObjectFields object_fields);
     184             : 
     185             :   template <typename THeapObjectSlot>
     186             :   inline SlotCallbackResult EvacuateThinString(Map map, THeapObjectSlot slot,
     187             :                                                ThinString object,
     188             :                                                int object_size);
     189             : 
     190             :   template <typename THeapObjectSlot>
     191             :   inline SlotCallbackResult EvacuateShortcutCandidate(Map map,
     192             :                                                       THeapObjectSlot slot,
     193             :                                                       ConsString object,
     194             :                                                       int object_size);
     195             : 
     196             :   void IterateAndScavengePromotedObject(HeapObject target, Map map, int size);
     197             : 
     198             :   ScavengerCollector* const collector_;
     199             :   Heap* const heap_;
     200             :   PromotionList::View promotion_list_;
     201             :   CopiedList::View copied_list_;
     202             :   Heap::PretenuringFeedbackMap local_pretenuring_feedback_;
     203             :   size_t copied_size_;
     204             :   size_t promoted_size_;
     205             :   LocalAllocator allocator_;
     206             :   SurvivingNewLargeObjectsMap surviving_new_large_objects_;
     207             :   const bool is_logging_;
     208             :   const bool is_incremental_marking_;
     209             :   const bool is_compacting_;
     210             : 
     211             :   friend class IterateAndScavengePromotedObjectsVisitor;
     212             :   friend class RootScavengeVisitor;
     213             :   friend class ScavengeVisitor;
     214             : };
     215             : 
     216             : // Helper class for turning the scavenger into an object visitor that is also
     217             : // filtering out non-HeapObjects and objects which do not reside in new space.
     218       23490 : class RootScavengeVisitor final : public RootVisitor {
     219             :  public:
     220             :   explicit RootScavengeVisitor(Scavenger* scavenger);
     221             : 
     222             :   void VisitRootPointer(Root root, const char* description,
     223             :                         FullObjectSlot p) final;
     224             :   void VisitRootPointers(Root root, const char* description,
     225             :                          FullObjectSlot start, FullObjectSlot end) final;
     226             : 
     227             :  private:
     228             :   void ScavengePointer(FullObjectSlot p);
     229             : 
     230             :   Scavenger* const scavenger_;
     231             : };
     232             : 
     233           0 : class ScavengeVisitor final : public NewSpaceVisitor<ScavengeVisitor> {
     234             :  public:
     235             :   explicit ScavengeVisitor(Scavenger* scavenger);
     236             : 
     237             :   V8_INLINE void VisitPointers(HeapObject host, ObjectSlot start,
     238             :                                ObjectSlot end) final;
     239             : 
     240             :   V8_INLINE void VisitPointers(HeapObject host, MaybeObjectSlot start,
     241             :                                MaybeObjectSlot end) final;
     242             : 
     243             :   V8_INLINE void VisitCodeTarget(Code host, RelocInfo* rinfo) final;
     244             :   V8_INLINE void VisitEmbeddedPointer(Code host, RelocInfo* rinfo) final;
     245             : 
     246             :  private:
     247             :   template <typename TSlot>
     248             :   V8_INLINE void VisitHeapObjectImpl(TSlot slot, HeapObject heap_object);
     249             : 
     250             :   template <typename TSlot>
     251             :   V8_INLINE void VisitPointersImpl(HeapObject host, TSlot start, TSlot end);
     252             : 
     253             :   Scavenger* const scavenger_;
     254             : };
     255             : 
     256             : }  // namespace internal
     257             : }  // namespace v8
     258             : 
     259             : #endif  // V8_HEAP_SCAVENGER_H_

Generated by: LCOV version 1.10