LCOV - code coverage report
Current view: top level - src/zone - zone-allocator.h (source / functions) Hit Total Coverage
Test: app.info Lines: 20 20 100.0 %
Date: 2017-04-26 Functions: 57 76 75.0 %

          Line data    Source code
       1             : // Copyright 2014 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_ZONE_ZONE_ALLOCATOR_H_
       6             : #define V8_ZONE_ZONE_ALLOCATOR_H_
       7             : #include <limits>
       8             : 
       9             : #include "src/zone/zone.h"
      10             : 
      11             : namespace v8 {
      12             : namespace internal {
      13             : 
      14             : template <typename T>
      15             : class ZoneAllocator {
      16             :  public:
      17             :   typedef T* pointer;
      18             :   typedef const T* const_pointer;
      19             :   typedef T& reference;
      20             :   typedef const T& const_reference;
      21             :   typedef T value_type;
      22             :   typedef size_t size_type;
      23             :   typedef ptrdiff_t difference_type;
      24             :   template <class O>
      25             :   struct rebind {
      26             :     typedef ZoneAllocator<O> other;
      27             :   };
      28             : 
      29             : #ifdef V8_CC_MSVC
      30             :   // MSVS unfortunately requires the default constructor to be defined.
      31             :   ZoneAllocator() : ZoneAllocator(nullptr) { UNREACHABLE(); }
      32             : #endif
      33   483690641 :   explicit ZoneAllocator(Zone* zone) throw() : zone_(zone) {}
      34             :   explicit ZoneAllocator(const ZoneAllocator& other) throw()
      35   128401420 :       : ZoneAllocator<T>(other.zone_) {}
      36             :   template <typename U>
      37             :   ZoneAllocator(const ZoneAllocator<U>& other) throw()
      38    45567967 :       : ZoneAllocator<T>(other.zone_) {}
      39             :   template <typename U>
      40             :   friend class ZoneAllocator;
      41             : 
      42             :   T* address(T& x) const { return &x; }
      43             :   const T* address(const T& x) const { return &x; }
      44             : 
      45             :   T* allocate(size_t n, const void* hint = 0) {
      46   540217315 :     return static_cast<T*>(zone_->NewArray<T>(static_cast<int>(n)));
      47             :   }
      48             :   void deallocate(T* p, size_t) { /* noop for Zones */
      49             :   }
      50             : 
      51             :   size_t max_size() const throw() {
      52             :     return std::numeric_limits<int>::max() / sizeof(T);
      53             :   }
      54             :   template <typename U, typename... Args>
      55     1452585 :   void construct(U* p, Args&&... args) {
      56             :     void* v_p = const_cast<void*>(static_cast<const void*>(p));
      57  5546329591 :     new (v_p) U(std::forward<Args>(args)...);
      58     1452585 :   }
      59             :   template <typename U>
      60             :   void destroy(U* p) {
      61       28129 :     p->~U();
      62             :   }
      63             : 
      64             :   bool operator==(ZoneAllocator const& other) const {
      65             :     return zone_ == other.zone_;
      66             :   }
      67             :   bool operator!=(ZoneAllocator const& other) const {
      68     5207890 :     return zone_ != other.zone_;
      69             :   }
      70             : 
      71             :   Zone* zone() { return zone_; }
      72             : 
      73             :  private:
      74             :   Zone* zone_;
      75             : };
      76             : 
      77             : // A recycling zone allocator maintains a free list of deallocated chunks
      78             : // to reuse on subsiquent allocations. The free list management is purposely
      79             : // very simple and works best for data-structures which regularly allocate and
      80             : // free blocks of similar sized memory (such as std::deque).
      81             : template <typename T>
      82             : class RecyclingZoneAllocator : public ZoneAllocator<T> {
      83             :  public:
      84             :   template <class O>
      85             :   struct rebind {
      86             :     typedef RecyclingZoneAllocator<O> other;
      87             :   };
      88             : 
      89             : #ifdef V8_CC_MSVC
      90             :   // MSVS unfortunately requires the default constructor to be defined.
      91             :   RecyclingZoneAllocator()
      92             :       : ZoneAllocator(nullptr, nullptr), free_list_(nullptr) {
      93             :     UNREACHABLE();
      94             :   }
      95             : #endif
      96             :   explicit RecyclingZoneAllocator(Zone* zone) throw()
      97    23135725 :       : ZoneAllocator<T>(zone), free_list_(nullptr) {}
      98             :   explicit RecyclingZoneAllocator(const RecyclingZoneAllocator& other) throw()
      99    40065488 :       : ZoneAllocator<T>(other), free_list_(nullptr) {}
     100             :   template <typename U>
     101             :   RecyclingZoneAllocator(const RecyclingZoneAllocator<U>& other) throw()
     102    40142280 :       : ZoneAllocator<T>(other), free_list_(nullptr) {}
     103             :   template <typename U>
     104             :   friend class RecyclingZoneAllocator;
     105             : 
     106    88292700 :   T* allocate(size_t n, const void* hint = 0) {
     107             :     // Only check top block in free list, since this will be equal to or larger
     108             :     // than the other blocks in the free list.
     109    88292700 :     if (free_list_ && free_list_->size >= n) {
     110             :       T* return_val = reinterpret_cast<T*>(free_list_);
     111     5761707 :       free_list_ = free_list_->next;
     112             :       return return_val;
     113             :     } else {
     114             :       return ZoneAllocator<T>::allocate(n, hint);
     115             :     }
     116             :   }
     117             : 
     118             :   void deallocate(T* p, size_t n) {
     119    37341156 :     if ((sizeof(T) * n < sizeof(FreeBlock))) return;
     120             : 
     121             :     // Only add block to free_list if it is equal or larger than previous block
     122             :     // so that allocation stays O(1) only having to look at the top block.
     123    45002179 :     if (!free_list_ || free_list_->size <= n) {
     124             :       // Store the free-list within the block being deallocated.
     125             :       DCHECK((sizeof(T) * n >= sizeof(FreeBlock)));
     126             :       FreeBlock* new_free_block = reinterpret_cast<FreeBlock*>(p);
     127             : 
     128    82343174 :       new_free_block->size = n;
     129    82343174 :       new_free_block->next = free_list_;
     130    45002101 :       free_list_ = new_free_block;
     131             :     }
     132             :   }
     133             : 
     134             :  private:
     135             :   struct FreeBlock {
     136             :     FreeBlock* next;
     137             :     size_t size;
     138             :   };
     139             : 
     140             :   FreeBlock* free_list_;
     141             : };
     142             : 
     143             : typedef ZoneAllocator<bool> ZoneBoolAllocator;
     144             : typedef ZoneAllocator<int> ZoneIntAllocator;
     145             : 
     146             : }  // namespace internal
     147             : }  // namespace v8
     148             : 
     149             : #endif  // V8_ZONE_ZONE_ALLOCATOR_H_

Generated by: LCOV version 1.10