[zone] Add TypeTag type parameter to zone allocation functions

This will allow implementing per-type allocation stats.

Also migrate old-style zone allocations
  ... = new (zone) MyObject(...)

to the new style:
  ... = zone->New<MyObject>(...)

in several source files.

Bug: v8:10689
Change-Id: I1b044c9eccb4ac7e1b627276691f3c1fbad52137
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2288232
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/master@{#68781}
This commit is contained in:
Igor Sheludko 2020-07-09 11:54:06 +02:00 committed by Commit Bot
parent f33df41a76
commit 911a13ebdd
6 changed files with 38 additions and 18 deletions

View File

@ -121,9 +121,7 @@ class V8_EXPORT_PRIVATE OffThreadIsolate final
Address* NewHandle(Address object) {
DCHECK_NOT_NULL(handle_zone_);
Address* location =
static_cast<Address*>(handle_zone_->New(sizeof(Address)));
*location = object;
Address* location = handle_zone_->New<Address>(object);
return location;
}

View File

@ -185,8 +185,7 @@ MaybeHandle<Cell> SourceTextModule::ResolveExport(
if (result.second) {
// |module| wasn't in the map previously, so allocate a new name set.
Zone* zone = resolve_set->zone();
name_set =
new (zone->New(sizeof(UnorderedStringSet))) UnorderedStringSet(zone);
name_set = zone->New<UnorderedStringSet>(zone);
} else if (name_set->count(export_name)) {
// Cycle detected.
if (must_resolve) {

View File

@ -316,7 +316,7 @@ class GrowableBitVector {
class Iterator {
public:
Iterator(const GrowableBitVector* target, Zone* zone)
: it_(target->bits_ == nullptr ? new (zone) BitVector(1, zone)
: it_(target->bits_ == nullptr ? zone->New<BitVector>(1, zone)
: target->bits_) {}
bool Done() const { return it_.Done(); }
void Advance() { it_.Advance(); }
@ -328,7 +328,7 @@ class GrowableBitVector {
GrowableBitVector() : bits_(nullptr) {}
GrowableBitVector(int length, Zone* zone)
: bits_(new (zone) BitVector(length, zone)) {}
: bits_(zone->New<BitVector>(length, zone)) {}
bool Contains(int value) const {
if (!InBitsRange(value)) return false;
@ -363,7 +363,7 @@ class GrowableBitVector {
while (new_length <= value) new_length *= 2;
if (bits_ == nullptr) {
bits_ = new (zone) BitVector(new_length, zone);
bits_ = zone->New<BitVector>(new_length, zone);
} else {
bits_->Resize(new_length, zone);
}

View File

@ -119,8 +119,8 @@ class ZoneChunkList : public ZoneObject {
};
Chunk* NewChunk(const uint32_t capacity) {
Chunk* chunk =
new (zone_->New(sizeof(Chunk) + capacity * sizeof(T))) Chunk();
void* memory = zone_->Allocate<Chunk>(sizeof(Chunk) + capacity * sizeof(T));
Chunk* chunk = new (memory) Chunk();
chunk->capacity_ = capacity;
return chunk;
}

View File

@ -47,7 +47,7 @@ class ZoneHandleSet final {
data_ = reinterpret_cast<Address>(value) | kSingletonTag;
} else if ((data_ & kTagMask) == kSingletonTag) {
if (singleton() == value) return;
List* list = new (zone->New(sizeof(List))) List(zone);
List* list = zone->New<List>(zone);
if (singleton() < value) {
list->push_back(singleton());
list->push_back(value);
@ -64,7 +64,7 @@ class ZoneHandleSet final {
if (old_list->at(i) == value) return;
if (old_list->at(i) > value) break;
}
List* new_list = new (zone->New(sizeof(List))) List(zone);
List* new_list = zone->New<List>(zone);
new_list->reserve(old_list->size() + 1);
size_t i = 0;
for (; i < old_list->size(); ++i) {

View File

@ -39,9 +39,15 @@ class V8_EXPORT_PRIVATE Zone final {
Zone(AccountingAllocator* allocator, const char* name);
~Zone();
// Allocate 'size' bytes of memory in the Zone; expands the Zone by
// allocating new segments of memory on demand using malloc().
void* New(size_t size) {
// TODO(v8:10689): Remove once all allocation sites are migrated.
void* New(size_t size) { return Allocate<void>(size); }
// Allocate 'size' bytes of uninitialized memory in the Zone; expands the Zone
// by allocating new segments of memory on demand using AccountingAllocator
// (see AccountingAllocator::AllocateSegment()).
// TODO(v8:10689): account allocated bytes with the provided TypeTag type.
template <typename TypeTag>
void* Allocate(size_t size) {
#ifdef V8_USE_ADDRESS_SANITIZER
return AsanNew(size);
#else
@ -55,12 +61,25 @@ class V8_EXPORT_PRIVATE Zone final {
return reinterpret_cast<void*>(result);
#endif
}
void* AsanNew(size_t size);
template <typename T>
// Allocates memory for T instance and constructs object by calling respective
// Args... constructor.
// TODO(v8:10689): account allocated bytes with the T type.
template <typename T, typename... Args>
T* New(Args&&... args) {
size_t size = RoundUp(sizeof(T), kAlignmentInBytes);
void* memory = Allocate<T>(size);
return new (memory) T(std::forward<Args>(args)...);
}
// Allocates uninitialized memory for 'length' number of T instances.
// TODO(v8:10689): account allocated bytes with the provided TypeTag type.
// It might be useful to tag buffer allocations with meaningful names to make
// buffer allocation sites distinguishable between each other.
template <typename T, typename TypeTag = T[]>
T* NewArray(size_t length) {
DCHECK_LT(length, std::numeric_limits<size_t>::max() / sizeof(T));
return static_cast<T*>(New(length * sizeof(T)));
return static_cast<T*>(Allocate<TypeTag>(length * sizeof(T)));
}
template <typename T>
@ -106,6 +125,8 @@ class V8_EXPORT_PRIVATE Zone final {
AccountingAllocator* allocator() const { return allocator_; }
private:
void* AsanNew(size_t size);
// Deletes all objects and free all memory allocated in the Zone.
void DeleteAll();
@ -154,6 +175,8 @@ class ZoneObject {
public:
// Allocate a new ZoneObject of 'size' bytes in the Zone.
void* operator new(size_t size, Zone* zone) { return zone->New(size); }
// Allow non-allocating placement new.
void* operator new(size_t size, void* ptr) { return ptr; }
// Ideally, the delete operator should be private instead of
// public, but unfortunately the compiler sometimes synthesizes