LCOV - code coverage report
Current view: top level - src/zone - zone-allocator.h (source / functions) Hit Total Coverage
Test: app.info Lines: 25 25 100.0 %
Date: 2019-02-19 Functions: 63 80 78.8 %

          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   144878019 :   explicit ZoneAllocator(Zone* zone) : zone_(zone) {}
      34             :   template <typename U>
      35             :   ZoneAllocator(const ZoneAllocator<U>& other) V8_NOEXCEPT
      36   111282812 :       : ZoneAllocator<T>(other.zone_) {}
      37             :   template <typename U>
      38             :   friend class ZoneAllocator;
      39             : 
      40             :   T* address(T& x) const { return &x; }
      41             :   const T* address(const T& x) const { return &x; }
      42             : 
      43       60408 :   T* allocate(size_t n, const void* hint = nullptr) {
      44  1299875276 :     return static_cast<T*>(zone_->NewArray<T>(static_cast<int>(n)));
      45             :   }
      46       60408 :   void deallocate(T* p, size_t) { /* noop for Zones */
      47       60408 :   }
      48             : 
      49       71880 :   size_t max_size() const {
      50       71880 :     return std::numeric_limits<int>::max() / sizeof(T);
      51             :   }
      52             :   template <typename U, typename... Args>
      53     1246115 :   void construct(U* p, Args&&... args) {
      54      116968 :     void* v_p = const_cast<void*>(static_cast<const void*>(p));
      55  7869752749 :     new (v_p) U(std::forward<Args>(args)...);
      56     1246115 :   }
      57             :   template <typename U>
      58      116968 :   void destroy(U* p) {
      59      910531 :     p->~U();
      60      116968 :   }
      61             : 
      62             :   bool operator==(ZoneAllocator const& other) const {
      63             :     return zone_ == other.zone_;
      64             :   }
      65             :   bool operator!=(ZoneAllocator const& other) const {
      66      154152 :     return zone_ != other.zone_;
      67             :   }
      68             : 
      69             :   Zone* zone() { return zone_; }
      70             : 
      71             :  private:
      72             :   Zone* zone_;
      73             : };
      74             : 
      75             : // A recycling zone allocator maintains a free list of deallocated chunks
      76             : // to reuse on subsiquent allocations. The free list management is purposely
      77             : // very simple and works best for data-structures which regularly allocate and
      78             : // free blocks of similar sized memory (such as std::deque).
      79             : template <typename T>
      80             : class RecyclingZoneAllocator : public ZoneAllocator<T> {
      81             :  public:
      82             :   template <class O>
      83             :   struct rebind {
      84             :     typedef RecyclingZoneAllocator<O> other;
      85             :   };
      86             : 
      87             : #ifdef V8_CC_MSVC
      88             :   // MSVS unfortunately requires the default constructor to be defined.
      89             :   RecyclingZoneAllocator()
      90             :       : ZoneAllocator(nullptr, nullptr), free_list_(nullptr) {
      91             :     UNREACHABLE();
      92             :   }
      93             : #endif
      94             :   explicit RecyclingZoneAllocator(Zone* zone)
      95    44586726 :       : ZoneAllocator<T>(zone), free_list_(nullptr) {}
      96             :   template <typename U>
      97             :   RecyclingZoneAllocator(const RecyclingZoneAllocator<U>& other) V8_NOEXCEPT
      98             :       : ZoneAllocator<T>(other),
      99             :         free_list_(nullptr) {}
     100             :   template <typename U>
     101             :   friend class RecyclingZoneAllocator;
     102             : 
     103   158124552 :   T* allocate(size_t n, const void* hint = nullptr) {
     104             :     // Only check top block in free list, since this will be equal to or larger
     105             :     // than the other blocks in the free list.
     106   158124552 :     if (free_list_ && free_list_->size >= n) {
     107             :       T* return_val = reinterpret_cast<T*>(free_list_);
     108     8810198 :       free_list_ = free_list_->next;
     109             :       return return_val;
     110             :     } else {
     111             :       return ZoneAllocator<T>::allocate(n, hint);
     112             :     }
     113             :   }
     114             : 
     115             :   void deallocate(T* p, size_t n) {
     116    64031366 :     if ((sizeof(T) * n < sizeof(FreeBlock))) return;
     117             : 
     118             :     // Only add block to free_list if it is equal or larger than previous block
     119             :     // so that allocation stays O(1) only having to look at the top block.
     120    75349678 :     if (!free_list_ || free_list_->size <= n) {
     121             :       // Store the free-list within the block being deallocated.
     122             :       DCHECK((sizeof(T) * n >= sizeof(FreeBlock)));
     123             :       FreeBlock* new_free_block = reinterpret_cast<FreeBlock*>(p);
     124             : 
     125   139380567 :       new_free_block->size = n;
     126   139380567 :       new_free_block->next = free_list_;
     127    75349419 :       free_list_ = new_free_block;
     128             :     }
     129             :   }
     130             : 
     131             :  private:
     132             :   struct FreeBlock {
     133             :     FreeBlock* next;
     134             :     size_t size;
     135             :   };
     136             : 
     137             :   FreeBlock* free_list_;
     138             : };
     139             : 
     140             : typedef ZoneAllocator<bool> ZoneBoolAllocator;
     141             : typedef ZoneAllocator<int> ZoneIntAllocator;
     142             : 
     143             : }  // namespace internal
     144             : }  // namespace v8
     145             : 
     146             : #endif  // V8_ZONE_ZONE_ALLOCATOR_H_

Generated by: LCOV version 1.10