LCOV - code coverage report
Current view: top level - include/llvm/Support - Recycler.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 9 9 100.0 %
Date: 2017-09-14 15:23:50 Functions: 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      731154 : 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             :   FreeNode *pop_val() {
      44    20306008 :     auto *Val = FreeList;
      45             :     __asan_unpoison_memory_region(Val, Size);
      46    20306008 :     FreeList = FreeList->Next;
      47             :     __msan_allocated_memory(Val, Size);
      48             :     return Val;
      49             :   }
      50             : 
      51             :   void push(FreeNode *N) {
      52     3622121 :     N->Next = FreeList;
      53    25381151 :     FreeList = N;
      54             :     __asan_poison_memory_region(N, Size);
      55             :   }
      56             : 
      57             : public:
      58             :   ~Recycler() {
      59             :     // If this fails, either the callee has lost track of some allocation,
      60             :     // or the callee isn't tracking allocations and should just call
      61             :     // clear() before deleting the Recycler.
      62             :     assert(!FreeList && "Non-empty recycler deleted!");
      63      290640 :   }
      64             : 
      65             :   /// clear - Release all the tracked allocations to the allocator. The
      66             :   /// recycler must be free of any tracked allocations before being
      67             :   /// deleted; calling clear is one way to ensure this.
      68             :   template<class AllocatorType>
      69             :   void clear(AllocatorType &Allocator) {
      70             :     while (FreeList) {
      71             :       T *t = reinterpret_cast<T *>(pop_val());
      72             :       Allocator.Deallocate(t);
      73             :     }
      74             :   }
      75             : 
      76             :   /// Special case for BumpPtrAllocator which has an empty Deallocate()
      77             :   /// function.
      78             :   ///
      79             :   /// There is no need to traverse the free list, pulling all the objects into
      80             :   /// cache.
      81      730820 :   void clear(BumpPtrAllocator &) { FreeList = nullptr; }
      82             : 
      83             :   template<class SubClass, class AllocatorType>
      84             :   SubClass *Allocate(AllocatorType &Allocator) {
      85             :     static_assert(alignof(SubClass) <= Align,
      86             :                   "Recycler allocation alignment is less than object align!");
      87             :     static_assert(sizeof(SubClass) <= Size,
      88             :                   "Recycler allocation size is less than object size!");
      89    48827124 :     return FreeList ? reinterpret_cast<SubClass *>(pop_val())
      90             :                     : static_cast<SubClass *>(Allocator.Allocate(Size, Align));
      91             :   }
      92             : 
      93             :   template<class AllocatorType>
      94             :   T *Allocate(AllocatorType &Allocator) {
      95             :     return Allocate<T>(Allocator);
      96             :   }
      97             : 
      98             :   template<class SubClass, class AllocatorType>
      99             :   void Deallocate(AllocatorType & /*Allocator*/, SubClass* Element) {
     100    25381151 :     push(reinterpret_cast<FreeNode *>(Element));
     101             :   }
     102             : 
     103             :   void PrintStats();
     104             : };
     105             : 
     106             : template <class T, size_t Size, size_t Align>
     107             : void Recycler<T, Size, Align>::PrintStats() {
     108             :   size_t S = 0;
     109             :   for (auto *I = FreeList; I; I = I->Next)
     110             :     ++S;
     111             :   PrintRecyclerStats(Size, Align, S);
     112             : }
     113             : 
     114             : }
     115             : 
     116             : #endif

Generated by: LCOV version 1.13