LCOV - code coverage report
Current view: top level - src/zone - zone.h (source / functions) Hit Total Coverage
Test: app.info Lines: 26 28 92.9 %
Date: 2017-04-26 Functions: 107 129 82.9 %

          Line data    Source code
       1             : // Copyright 2012 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_H_
       6             : #define V8_ZONE_ZONE_H_
       7             : 
       8             : #include <limits>
       9             : 
      10             : #include "src/base/hashmap.h"
      11             : #include "src/base/logging.h"
      12             : #include "src/globals.h"
      13             : #include "src/list.h"
      14             : #include "src/splay-tree.h"
      15             : #include "src/zone/accounting-allocator.h"
      16             : 
      17             : #ifndef ZONE_NAME
      18             : #define STRINGIFY(x) #x
      19             : #define TOSTRING(x) STRINGIFY(x)
      20             : #define ZONE_NAME __FILE__ ":" TOSTRING(__LINE__)
      21             : #endif
      22             : 
      23             : namespace v8 {
      24             : namespace internal {
      25             : 
      26             : // The Zone supports very fast allocation of small chunks of
      27             : // memory. The chunks cannot be deallocated individually, but instead
      28             : // the Zone supports deallocating all chunks in one fast
      29             : // operation. The Zone is used to hold temporary data structures like
      30             : // the abstract syntax tree, which is deallocated after compilation.
      31             : //
      32             : // Note: There is no need to initialize the Zone; the first time an
      33             : // allocation is attempted, a segment of memory will be requested
      34             : // through the allocator.
      35             : //
      36             : // Note: The implementation is inherently not thread safe. Do not use
      37             : // from multi-threaded code.
      38             : class V8_EXPORT_PRIVATE Zone final {
      39             :  public:
      40             :   Zone(AccountingAllocator* allocator, const char* name);
      41             :   ~Zone();
      42             : 
      43             :   // Allocate 'size' bytes of memory in the Zone; expands the Zone by
      44             :   // allocating new segments of memory on demand using malloc().
      45             :   void* New(size_t size);
      46             : 
      47             :   template <typename T>
      48             :   T* NewArray(size_t length) {
      49             :     DCHECK_LT(length, std::numeric_limits<size_t>::max() / sizeof(T));
      50   701555742 :     return static_cast<T*>(New(length * sizeof(T)));
      51             :   }
      52             : 
      53             :   // Seals the zone to prevent any further allocation.
      54           0 :   void Seal() { sealed_ = true; }
      55             : 
      56             :   // Returns true if more memory has been allocated in zones than
      57             :   // the limit allows.
      58             :   bool excess_allocation() const {
      59             :     return segment_bytes_allocated_ > kExcessLimit;
      60             :   }
      61             : 
      62             :   const char* name() const { return name_; }
      63             : 
      64             :   size_t allocation_size() const { return allocation_size_; }
      65             : 
      66             :   AccountingAllocator* allocator() const { return allocator_; }
      67             : 
      68             :  private:
      69             :   // All pointers returned from New() are 8-byte aligned.
      70             :   static const size_t kAlignmentInBytes = 8;
      71             : 
      72             :   // Never allocate segments smaller than this size in bytes.
      73             :   static const size_t kMinimumSegmentSize = 8 * KB;
      74             : 
      75             :   // Never allocate segments larger than this size in bytes.
      76             :   static const size_t kMaximumSegmentSize = 1 * MB;
      77             : 
      78             :   // Report zone excess when allocation exceeds this limit.
      79             :   static const size_t kExcessLimit = 256 * MB;
      80             : 
      81             :   // Deletes all objects and free all memory allocated in the Zone.
      82             :   void DeleteAll();
      83             : 
      84             :   // The number of bytes allocated in this zone so far.
      85             :   size_t allocation_size_;
      86             : 
      87             :   // The number of bytes allocated in segments.  Note that this number
      88             :   // includes memory allocated from the OS but not yet allocated from
      89             :   // the zone.
      90             :   size_t segment_bytes_allocated_;
      91             : 
      92             :   // Expand the Zone to hold at least 'size' more bytes and allocate
      93             :   // the bytes. Returns the address of the newly allocated chunk of
      94             :   // memory in the Zone. Should only be called if there isn't enough
      95             :   // room in the Zone already.
      96             :   Address NewExpand(size_t size);
      97             : 
      98             :   // Creates a new segment, sets it size, and pushes it to the front
      99             :   // of the segment chain. Returns the new segment.
     100             :   inline Segment* NewSegment(size_t requested_size);
     101             : 
     102             :   // The free region in the current (front) segment is represented as
     103             :   // the half-open interval [position, limit). The 'position' variable
     104             :   // is guaranteed to be aligned as dictated by kAlignment.
     105             :   Address position_;
     106             :   Address limit_;
     107             : 
     108             :   AccountingAllocator* allocator_;
     109             : 
     110             :   Segment* segment_head_;
     111             :   const char* name_;
     112             :   bool sealed_;
     113             : };
     114             : 
     115             : // ZoneObject is an abstraction that helps define classes of objects
     116             : // allocated in the Zone. Use it as a base class; see ast.h.
     117             : class ZoneObject {
     118             :  public:
     119             :   // Allocate a new ZoneObject of 'size' bytes in the Zone.
     120  1324252538 :   void* operator new(size_t size, Zone* zone) { return zone->New(size); }
     121             : 
     122             :   // Ideally, the delete operator should be private instead of
     123             :   // public, but unfortunately the compiler sometimes synthesizes
     124             :   // (unused) destructors for classes derived from ZoneObject, which
     125             :   // require the operator to be visible. MSVC requires the delete
     126             :   // operator to be public.
     127             : 
     128             :   // ZoneObjects should never be deleted individually; use
     129             :   // Zone::DeleteAll() to delete all zone objects in one go.
     130           0 :   void operator delete(void*, size_t) { UNREACHABLE(); }
     131             :   void operator delete(void* pointer, Zone* zone) { UNREACHABLE(); }
     132             : };
     133             : 
     134             : // The ZoneAllocationPolicy is used to specialize generic data
     135             : // structures to allocate themselves and their elements in the Zone.
     136             : class ZoneAllocationPolicy final {
     137             :  public:
     138  1073004339 :   explicit ZoneAllocationPolicy(Zone* zone) : zone_(zone) {}
     139   660957938 :   void* New(size_t size) { return zone()->New(size); }
     140             :   static void Delete(void* pointer) {}
     141   351013884 :   Zone* zone() const { return zone_; }
     142             : 
     143             :  private:
     144             :   Zone* zone_;
     145             : };
     146             : 
     147             : // ZoneLists are growable lists with constant-time access to the
     148             : // elements. The list itself and all its elements are allocated in the
     149             : // Zone. ZoneLists cannot be deleted individually; you can delete all
     150             : // objects in the Zone by calling Zone::DeleteAll().
     151             : template <typename T>
     152             : class ZoneList final : public List<T, ZoneAllocationPolicy> {
     153             :  public:
     154             :   // Construct a new ZoneList with the given capacity; the length is
     155             :   // always zero. The capacity must be non-negative.
     156   323237808 :   ZoneList(int capacity, Zone* zone)
     157   323237739 :       : List<T, ZoneAllocationPolicy>(capacity, ZoneAllocationPolicy(zone)) {}
     158             : 
     159             :   // Construct a new ZoneList from a std::initializer_list
     160       10540 :   ZoneList(std::initializer_list<T> list, Zone* zone)
     161             :       : List<T, ZoneAllocationPolicy>(static_cast<int>(list.size()),
     162       10540 :                                       ZoneAllocationPolicy(zone)) {
     163       31830 :     for (auto& i : list) Add(i, zone);
     164       10540 :   }
     165             : 
     166    56672965 :   void* operator new(size_t size, Zone* zone) { return zone->New(size); }
     167             : 
     168             :   // Construct a new ZoneList by copying the elements of the given ZoneList.
     169     2424849 :   ZoneList(const ZoneList<T>& other, Zone* zone)
     170             :       : List<T, ZoneAllocationPolicy>(other.length(),
     171     2424849 :                                       ZoneAllocationPolicy(zone)) {
     172             :     AddAll(other, zone);
     173     2424853 :   }
     174             : 
     175             :   // We add some convenience wrappers so that we can pass in a Zone
     176             :   // instead of a (less convenient) ZoneAllocationPolicy.
     177   247774718 :   void Add(const T& element, Zone* zone) {
     178  1042378281 :     List<T, ZoneAllocationPolicy>::Add(element, ZoneAllocationPolicy(zone));
     179   245360295 :   }
     180             :   void AddAll(const List<T, ZoneAllocationPolicy>& other, Zone* zone) {
     181    17500656 :     List<T, ZoneAllocationPolicy>::AddAll(other, ZoneAllocationPolicy(zone));
     182             :   }
     183             :   void AddAll(const Vector<T>& other, Zone* zone) {
     184             :     List<T, ZoneAllocationPolicy>::AddAll(other, ZoneAllocationPolicy(zone));
     185             :   }
     186             :   void InsertAt(int index, const T& element, Zone* zone) {
     187     6575676 :     List<T, ZoneAllocationPolicy>::InsertAt(index, element,
     188    13150694 :                                             ZoneAllocationPolicy(zone));
     189             :   }
     190    12191913 :   Vector<T> AddBlock(T value, int count, Zone* zone) {
     191             :     return List<T, ZoneAllocationPolicy>::AddBlock(value, count,
     192    24383853 :                                                    ZoneAllocationPolicy(zone));
     193             :   }
     194             :   void Allocate(int length, Zone* zone) {
     195             :     List<T, ZoneAllocationPolicy>::Allocate(length, ZoneAllocationPolicy(zone));
     196             :   }
     197      785261 :   void Initialize(int capacity, Zone* zone) {
     198             :     List<T, ZoneAllocationPolicy>::Initialize(capacity,
     199             :                                               ZoneAllocationPolicy(zone));
     200      785261 :   }
     201             : 
     202             :   void operator delete(void* pointer) { UNREACHABLE(); }
     203             :   void operator delete(void* pointer, Zone* zone) { UNREACHABLE(); }
     204             : };
     205             : 
     206             : // A zone splay tree.  The config type parameter encapsulates the
     207             : // different configurations of a concrete splay tree (see splay-tree.h).
     208             : // The tree itself and all its elements are allocated in the Zone.
     209             : template <typename Config>
     210             : class ZoneSplayTree final : public SplayTree<Config, ZoneAllocationPolicy> {
     211             :  public:
     212             :   explicit ZoneSplayTree(Zone* zone)
     213             :       : SplayTree<Config, ZoneAllocationPolicy>(ZoneAllocationPolicy(zone)) {}
     214             :   ~ZoneSplayTree() {
     215             :     // Reset the root to avoid unneeded iteration over all tree nodes
     216             :     // in the destructor.  For a zone-allocated tree, nodes will be
     217             :     // freed by the Zone.
     218             :     SplayTree<Config, ZoneAllocationPolicy>::ResetRoot();
     219             :   }
     220             : 
     221     1635717 :   void* operator new(size_t size, Zone* zone) { return zone->New(size); }
     222             : 
     223             :   void operator delete(void* pointer) { UNREACHABLE(); }
     224             :   void operator delete(void* pointer, Zone* zone) { UNREACHABLE(); }
     225             : };
     226             : 
     227             : typedef base::PointerTemplateHashMapImpl<ZoneAllocationPolicy> ZoneHashMap;
     228             : 
     229             : typedef base::CustomMatcherTemplateHashMapImpl<ZoneAllocationPolicy>
     230             :     CustomMatcherZoneHashMap;
     231             : 
     232             : }  // namespace internal
     233             : }  // namespace v8
     234             : 
     235             : #endif  // V8_ZONE_ZONE_H_

Generated by: LCOV version 1.10