Home | History | Annotate | Download | only in zone
      1 // Copyright 2016 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_ACCOUNTING_ALLOCATOR_H_
      6 #define V8_ZONE_ACCOUNTING_ALLOCATOR_H_
      7 
      8 #include "include/v8-platform.h"
      9 #include "src/base/atomic-utils.h"
     10 #include "src/base/atomicops.h"
     11 #include "src/base/macros.h"
     12 #include "src/base/platform/mutex.h"
     13 #include "src/base/platform/semaphore.h"
     14 #include "src/base/platform/time.h"
     15 #include "src/zone/zone-segment.h"
     16 #include "testing/gtest/include/gtest/gtest_prod.h"
     17 
     18 namespace v8 {
     19 namespace internal {
     20 
     21 class V8_EXPORT_PRIVATE AccountingAllocator {
     22  public:
     23   static const size_t kMaxPoolSizeLowMemoryDevice = 8ul * KB;
     24   static const size_t kMaxPoolSizeMediumMemoryDevice = 8ul * KB;
     25   static const size_t kMaxPoolSizeHighMemoryDevice = 8ul * KB;
     26   static const size_t kMaxPoolSizeHugeMemoryDevice = 8ul * KB;
     27 
     28   AccountingAllocator();
     29   virtual ~AccountingAllocator();
     30 
     31   // Gets an empty segment from the pool or creates a new one.
     32   virtual Segment* GetSegment(size_t bytes);
     33   // Return unneeded segments to either insert them into the pool or release
     34   // them if the pool is already full or memory pressure is high.
     35   virtual void ReturnSegment(Segment* memory);
     36 
     37   size_t GetCurrentMemoryUsage() const;
     38   size_t GetMaxMemoryUsage() const;
     39 
     40   size_t GetCurrentPoolSize() const;
     41 
     42   void MemoryPressureNotification(MemoryPressureLevel level);
     43   // Configures the zone segment pool size limits so the pool does not
     44   // grow bigger than max_pool_size.
     45   // TODO(heimbuef): Do not accept segments to pool that are larger than
     46   // their size class requires. Sometimes the zones generate weird segments.
     47   void ConfigureSegmentPool(const size_t max_pool_size);
     48 
     49   virtual void ZoneCreation(const Zone* zone) {}
     50   virtual void ZoneDestruction(const Zone* zone) {}
     51 
     52  private:
     53   FRIEND_TEST(Zone, SegmentPoolConstraints);
     54 
     55   static const size_t kMinSegmentSizePower = 13;
     56   static const size_t kMaxSegmentSizePower = 18;
     57 
     58   STATIC_ASSERT(kMinSegmentSizePower <= kMaxSegmentSizePower);
     59 
     60   static const size_t kNumberBuckets =
     61       1 + kMaxSegmentSizePower - kMinSegmentSizePower;
     62 
     63   // Allocates a new segment. Returns nullptr on failed allocation.
     64   Segment* AllocateSegment(size_t bytes);
     65   void FreeSegment(Segment* memory);
     66 
     67   // Returns a segment from the pool of at least the requested size.
     68   Segment* GetSegmentFromPool(size_t requested_size);
     69   // Trys to add a segment to the pool. Returns false if the pool is full.
     70   bool AddSegmentToPool(Segment* segment);
     71 
     72   // Empties the pool and puts all its contents onto the garbage stack.
     73   void ClearPool();
     74 
     75   Segment* unused_segments_heads_[kNumberBuckets];
     76 
     77   size_t unused_segments_sizes_[kNumberBuckets];
     78   size_t unused_segments_max_sizes_[kNumberBuckets];
     79 
     80   base::Mutex unused_segments_mutex_;
     81 
     82   base::AtomicWord current_memory_usage_ = 0;
     83   base::AtomicWord max_memory_usage_ = 0;
     84   base::AtomicWord current_pool_size_ = 0;
     85 
     86   base::AtomicValue<MemoryPressureLevel> memory_pressure_level_;
     87 
     88   DISALLOW_COPY_AND_ASSIGN(AccountingAllocator);
     89 };
     90 
     91 }  // namespace internal
     92 }  // namespace v8
     93 
     94 #endif  // V8_ZONE_ACCOUNTING_ALLOCATOR_H_
     95