Chromium Code Reviews| Index: src/zone.h |
| diff --git a/src/zone.h b/src/zone.h |
| index 29055cb70d053547d44091cdfaf420e0f6736e2d..94eeff3c376ee4f8a3fabe33f4738ad9a0b86dfe 100644 |
| --- a/src/zone.h |
| +++ b/src/zone.h |
| @@ -10,6 +10,7 @@ |
| #include "src/base/accounting-allocator.h" |
| #include "src/base/hashmap.h" |
| #include "src/base/logging.h" |
| +#include "src/base/platform/platform.h" |
| #include "src/globals.h" |
| #include "src/list.h" |
| #include "src/splay-tree.h" |
| @@ -34,6 +35,9 @@ class Segment; |
| // Note: The implementation is inherently not thread safe. Do not use |
| // from multi-threaded code. |
| class Zone final { |
| + friend class ZoneObject; |
| + friend class Segment; |
|
jochen (gone - plz use gerrit)
2016/09/01 12:04:52
nit. please move those declarations down to the pr
heimbuef
2016/09/05 12:38:14
Acknowledged.
|
| + |
| public: |
| explicit Zone(base::AccountingAllocator* allocator); |
| ~Zone(); |
| @@ -66,6 +70,10 @@ class Zone final { |
| base::AccountingAllocator* allocator() const { return allocator_; } |
| + // Returns the zone the pointer belongs to. Only works in case the pointer |
| + // actually lies within a zone segment. |
| + static Zone* GetZoneFromPointer(const void* ptr); |
| + |
| private: |
| // All pointers returned from New() have this alignment. In addition, if the |
| // object being allocated has a size that is divisible by 8 then its alignment |
| @@ -83,12 +91,24 @@ class Zone final { |
| // Never allocate segments larger than this size in bytes. |
| static const size_t kMaximumSegmentSize = 1 * MB; |
| + static const uint8_t kSegmentAlignmentBits = 20; |
| + |
| + // Always align new segments to this size |
| + static const size_t kSegmentAlignmentSize = 1 << kSegmentAlignmentBits; |
| + |
| + static const size_t kSegmentAlignmentMask = |
| + ~((1 << kSegmentAlignmentBits) - 1); |
| + |
| + STATIC_ASSERT(kMaximumSegmentSize <= kSegmentAlignmentSize); |
| + |
| // Never keep segments larger than this size in bytes around. |
| static const size_t kMaximumKeptSegmentSize = 64 * KB; |
| // Report zone excess when allocation exceeds this limit. |
| static const size_t kExcessLimit = 256 * MB; |
| + static Segment* GetZoneSegmentFromPointer(const void* ptr); |
| + |
| // The number of bytes allocated in this zone so far. |
| size_t allocation_size_; |
| @@ -97,18 +117,14 @@ class Zone final { |
| // the zone. |
| size_t segment_bytes_allocated_; |
| - // Expand the Zone to hold at least 'size' more bytes and allocate |
| - // the bytes. Returns the address of the newly allocated chunk of |
| - // memory in the Zone. Should only be called if there isn't enough |
| - // room in the Zone already. |
| - Address NewExpand(size_t size); |
| + Address NewNormalSegment(size_t size); |
| - // Creates a new segment, sets it size, and pushes it to the front |
| - // of the segment chain. Returns the new segment. |
| - inline Segment* NewSegment(size_t size); |
| + Address NewLargeObjectSegment(size_t size); |
| - // Deletes the given segment. Does not touch the segment chain. |
| - inline void DeleteSegment(Segment* segment, size_t size); |
| + size_t CalculateSegmentSize(const size_t requested); |
| + |
| + // Creates a new segment, initializes it. Returns the new segment. |
| + inline Segment* NewSegment(size_t size); |
| // The free region in the current (front) segment is represented as |
| // the half-open interval [position, limit). The 'position' variable |
| @@ -121,7 +137,6 @@ class Zone final { |
| Segment* segment_head_; |
| }; |
| - |
| // ZoneObject is an abstraction that helps define classes of objects |
| // allocated in the Zone. Use it as a base class; see ast.h. |
| class ZoneObject { |
| @@ -129,6 +144,8 @@ class ZoneObject { |
| // Allocate a new ZoneObject of 'size' bytes in the Zone. |
| void* operator new(size_t size, Zone* zone) { return zone->New(size); } |
| + Zone* zone() const { return Zone::GetZoneFromPointer(this); } |
| + |
| // Ideally, the delete operator should be private instead of |
| // public, but unfortunately the compiler sometimes synthesizes |
| // (unused) destructors for classes derived from ZoneObject, which |
| @@ -179,8 +196,9 @@ class ZoneList final : public List<T, ZoneAllocationPolicy> { |
| public: |
| // Construct a new ZoneList with the given capacity; the length is |
| // always zero. The capacity must be non-negative. |
| + // The lists storage will be placed in the given zone. |
| ZoneList(int capacity, Zone* zone) |
| - : List<T, ZoneAllocationPolicy>(capacity, ZoneAllocationPolicy(zone)) { } |
| + : List<T, ZoneAllocationPolicy>(capacity, ZoneAllocationPolicy(zone)) {} |
| void* operator new(size_t size, Zone* zone) { return zone->New(size); } |
| @@ -191,33 +209,53 @@ class ZoneList final : public List<T, ZoneAllocationPolicy> { |
| AddAll(other, zone); |
| } |
| - // We add some convenience wrappers so that we can pass in a Zone |
| - // instead of a (less convenient) ZoneAllocationPolicy. |
| void Add(const T& element, Zone* zone) { |
| + DCHECK_IMPLIES(this->has_storage_zone(), this->storage_zone() == zone); |
| List<T, ZoneAllocationPolicy>::Add(element, ZoneAllocationPolicy(zone)); |
| } |
| + |
| void AddAll(const List<T, ZoneAllocationPolicy>& other, Zone* zone) { |
| + DCHECK_IMPLIES(this->has_storage_zone(), this->storage_zone() == zone); |
| List<T, ZoneAllocationPolicy>::AddAll(other, ZoneAllocationPolicy(zone)); |
| } |
| + |
| void AddAll(const Vector<T>& other, Zone* zone) { |
| + DCHECK_IMPLIES(this->has_storage_zone(), this->storage_zone() == zone); |
| List<T, ZoneAllocationPolicy>::AddAll(other, ZoneAllocationPolicy(zone)); |
| } |
| + |
| void InsertAt(int index, const T& element, Zone* zone) { |
| + DCHECK_IMPLIES(this->has_storage_zone(), this->storage_zone() == zone); |
| List<T, ZoneAllocationPolicy>::InsertAt(index, element, |
| ZoneAllocationPolicy(zone)); |
| } |
| + |
| Vector<T> AddBlock(T value, int count, Zone* zone) { |
| + DCHECK_IMPLIES(this->has_storage_zone(), this->storage_zone() == zone); |
| return List<T, ZoneAllocationPolicy>::AddBlock(value, count, |
| ZoneAllocationPolicy(zone)); |
| } |
| + |
| void Allocate(int length, Zone* zone) { |
| + DCHECK_IMPLIES(this->has_storage_zone(), this->storage_zone() == zone); |
| List<T, ZoneAllocationPolicy>::Allocate(length, ZoneAllocationPolicy(zone)); |
| } |
| + |
| void Initialize(int capacity, Zone* zone) { |
| + DCHECK_IMPLIES(this->has_storage_zone(), this->storage_zone() == zone); |
| List<T, ZoneAllocationPolicy>::Initialize(capacity, |
| ZoneAllocationPolicy(zone)); |
| } |
| + bool has_storage_zone() const { return this->capacity() > 0; } |
| + |
| + // Returns the zone the storage is located in |
| + Zone* storage_zone() const { |
| + DCHECK(this->has_storage_zone()); |
| + // ZoneList storage lives in a zone, so this works. |
| + return Zone::GetZoneFromPointer(this->data()); |
| + } |
| + |
| void operator delete(void* pointer) { UNREACHABLE(); } |
| void operator delete(void* pointer, Zone* zone) { UNREACHABLE(); } |
| }; |