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

Generated by: LCOV version 1.10