LCOV - code coverage report
Current view: top level - include/llvm/Support - Recycler.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 18 65 27.7 %
Date: 2018-10-20 13:21:21 Functions: 0 47 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //==- llvm/Support/Recycler.h - Recycling Allocator --------------*- C++ -*-==//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : //
      10             : // This file defines the Recycler class template.  See the doxygen comment for
      11             : // Recycler for more details.
      12             : //
      13             : //===----------------------------------------------------------------------===//
      14             : 
      15             : #ifndef LLVM_SUPPORT_RECYCLER_H
      16             : #define LLVM_SUPPORT_RECYCLER_H
      17             : 
      18             : #include "llvm/ADT/ilist.h"
      19             : #include "llvm/Support/Allocator.h"
      20             : #include "llvm/Support/ErrorHandling.h"
      21             : #include <cassert>
      22             : 
      23             : namespace llvm {
      24             : 
      25             : /// PrintRecyclingAllocatorStats - Helper for RecyclingAllocator for
      26             : /// printing statistics.
      27             : ///
      28             : void PrintRecyclerStats(size_t Size, size_t Align, size_t FreeListSize);
      29             : 
      30             : /// Recycler - This class manages a linked-list of deallocated nodes
      31             : /// and facilitates reusing deallocated memory in place of allocating
      32             : /// new memory.
      33             : ///
      34             : template <class T, size_t Size = sizeof(T), size_t Align = alignof(T)>
      35     1253281 : class Recycler {
      36             :   struct FreeNode {
      37             :     FreeNode *Next;
      38             :   };
      39             : 
      40             :   /// List of nodes that have deleted contents and are not in active use.
      41             :   FreeNode *FreeList = nullptr;
      42             : 
      43           0 :   FreeNode *pop_val() {
      44           0 :     auto *Val = FreeList;
      45             :     __asan_unpoison_memory_region(Val, Size);
      46    39361940 :     FreeList = FreeList->Next;
      47             :     __msan_allocated_memory(Val, Size);
      48           0 :     return Val;
      49             :   }
      50           0 : 
      51           0 :   void push(FreeNode *N) {
      52    58644730 :     N->Next = FreeList;
      53    58644730 :     FreeList = N;
      54             :     __asan_poison_memory_region(N, Size);
      55           0 :   }
      56             : 
      57           0 : public:
      58           0 :   ~Recycler() {
      59             :     // If this fails, either the callee has lost track of some allocation,
      60           0 :     // or the callee isn't tracking allocations and should just call
      61             :     // clear() before deleting the Recycler.
      62           0 :     assert(!FreeList && "Non-empty recycler deleted!");
      63             :   }
      64           0 : 
      65           0 :   /// clear - Release all the tracked allocations to the allocator. The
      66    21403966 :   /// recycler must be free of any tracked allocations before being
      67    21403966 :   /// deleted; calling clear is one way to ensure this.
      68             :   template<class AllocatorType>
      69           0 :   void clear(AllocatorType &Allocator) {
      70           0 :     while (FreeList) {
      71           0 :       T *t = reinterpret_cast<T *>(pop_val());
      72           0 :       Allocator.Deallocate(t);
      73     3202792 :     }
      74     3202792 :   }
      75           0 : 
      76           0 :   /// Special case for BumpPtrAllocator which has an empty Deallocate()
      77           0 :   /// function.
      78           0 :   ///
      79           0 :   /// There is no need to traverse the free list, pulling all the objects into
      80             :   /// cache.
      81       51102 :   void clear(BumpPtrAllocator &) { FreeList = nullptr; }
      82           0 : 
      83           0 :   template<class SubClass, class AllocatorType>
      84           0 :   SubClass *Allocate(AllocatorType &Allocator) {
      85             :     static_assert(alignof(SubClass) <= Align,
      86           0 :                   "Recycler allocation alignment is less than object align!");
      87      410945 :     static_assert(sizeof(SubClass) <= Size,
      88           0 :                   "Recycler allocation size is less than object size!");
      89    31335630 :     return FreeList ? reinterpret_cast<SubClass *>(pop_val())
      90     1346113 :                     : static_cast<SubClass *>(Allocator.Allocate(Size, Align));
      91           0 :   }
      92             : 
      93             :   template<class AllocatorType>
      94             :   T *Allocate(AllocatorType &Allocator) {
      95             :     return Allocate<T>(Allocator);
      96             :   }
      97             : 
      98             :   template<class SubClass, class AllocatorType>
      99           0 :   void Deallocate(AllocatorType & /*Allocator*/, SubClass* Element) {
     100             :     push(reinterpret_cast<FreeNode *>(Element));
     101           0 :   }
     102           0 : 
     103             :   void PrintStats();
     104           0 : };
     105      822130 : 
     106             : template <class T, size_t Size, size_t Align>
     107           0 : void Recycler<T, Size, Align>::PrintStats() {
     108           0 :   size_t S = 0;
     109             :   for (auto *I = FreeList; I; I = I->Next)
     110           0 :     ++S;
     111           0 :   PrintRecyclerStats(Size, Align, S);
     112             : }
     113    55890161 : 
     114    47180718 : }
     115             : 
     116             : #endif

Generated by: LCOV version 1.13