LCOV - code coverage report
Current view: top level - src/heap - scavenger.h (source / functions) Hit Total Coverage
Test: app.info Lines: 7 7 100.0 %
Date: 2019-03-21 Functions: 1 5 20.0 %

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

Generated by: LCOV version 1.10