Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(361)

Unified Diff: src/zone.h

Issue 2299753002: Made zone segments aligned in memory and included a pointer to the zone in the header. Larger objec…
Patch Set: Added a zone segment pool for small segments to avoid frequent sys calls Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/runtime/runtime-regexp.cc ('k') | src/zone.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/zone.h
diff --git a/src/zone.h b/src/zone.h
index 29055cb70d053547d44091cdfaf420e0f6736e2d..0b5b41c80a9f5b4e54701a41b49226df4f0318fc 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"
@@ -66,7 +67,13 @@ 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:
+ friend class ZoneObject;
+ friend class Segment;
// 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
// will be 8. ASan requires 8-byte alignment.
@@ -83,12 +90,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 +116,19 @@ 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);
+ // Creates a new normal segment, that can be used to quickly allocate memory
+ // for lots of smaller objects.
+ 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);
+ // Creates a large object segment, that is created to exactly fit one large
+ // object.
+ Address NewLargeObjectSegment(size_t size);
+
+ size_t CalculateSegmentSize(const size_t requested);
- // Deletes the given segment. Does not touch the segment chain.
- inline void DeleteSegment(Segment* segment, size_t size);
+ // Creates a new segment of the requested size and 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 +141,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 +148,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
@@ -162,7 +183,9 @@ class ZoneAllocationPolicy final {
public:
explicit ZoneAllocationPolicy(Zone* zone) : zone_(zone) { }
void* New(size_t size) { return zone()->New(size); }
- static void Delete(void* pointer) {}
+ static void Delete(void* pointer) {
+ DCHECK_IMPLIES(pointer != nullptr, Zone::GetZoneFromPointer(pointer));
+ }
Zone* zone() const { return zone_; }
private:
@@ -179,8 +202,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 +215,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(); }
};
« no previous file with comments | « src/runtime/runtime-regexp.cc ('k') | src/zone.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698