[zone] Provide a way to configure allocator for zone backings

The CL provides a way for the embedder to hook in a special malloc-like
allocator that will be used for zone allocations.

An alternative approach would be to use weak functions with branches,
checking whether the functions were available at link-time. Those
branches could be optimized away with LTOs, so they would essentially
be free. However, the weak function approach is not portable (e.g.
there is no easy way to emulate it with msvc). The approach can be
revisited if indirect call turns out to be expensive (e.g. on hardware
with weak branch target predictors).

The CL is a prerequisite for running PCScan in the renderer process.

Bug: chromium:1249550
Change-Id: I221dcb2486c13e8e6e6761839ba391978319bde4
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3172760
Reviewed-by: Igor Sheludko <ishell@chromium.org>
Reviewed-by: Michael Lippautz <mlippautz@chromium.org>
Commit-Queue: Anton Bikineev <bikineev@chromium.org>
Cr-Commit-Position: refs/heads/main@{#77012}
This commit is contained in:
Anton Bikineev 2021-09-21 20:51:40 +02:00 committed by V8 LUCI CQ
parent 74ca05b05f
commit e262e1cb4a
5 changed files with 36 additions and 6 deletions

View File

@ -516,6 +516,18 @@ class PageAllocator {
virtual bool CanAllocateSharedPages() { return false; }
};
/**
* V8 Allocator used for allocating zone backings.
*/
class ZoneBackingAllocator {
public:
using MallocFn = void* (*)(size_t);
using FreeFn = void (*)(void*);
virtual MallocFn GetMallocFn() const { return ::malloc; }
virtual FreeFn GetFreeFn() const { return ::free; }
};
/**
* V8 Platform abstraction layer.
*
@ -534,6 +546,14 @@ class Platform {
return nullptr;
}
/**
* Allows the embedder to specify a custom allocator used for zones.
*/
virtual ZoneBackingAllocator* GetZoneBackingAllocator() {
static ZoneBackingAllocator default_allocator;
return &default_allocator;
}
/**
* Enables the embedder to respond in cases where V8 can't allocate large
* blocks of memory. V8 retries the failed allocation once after calling this

View File

@ -141,10 +141,10 @@ char* StrNDup(const char* str, size_t n) {
return result;
}
void* AllocWithRetry(size_t size) {
void* AllocWithRetry(size_t size, MallocFn malloc_fn) {
void* result = nullptr;
for (int i = 0; i < kAllocationTries; ++i) {
result = base::Malloc(size);
result = malloc_fn(size);
if (result != nullptr) break;
if (!OnCriticalMemoryPressure(size)) break;
}

View File

@ -90,9 +90,11 @@ class FreeStoreAllocationPolicy {
}
};
using MallocFn = void* (*)(size_t);
// Performs a malloc, with retry logic on failure. Returns nullptr on failure.
// Call free to release memory allocated with this function.
void* AllocWithRetry(size_t size);
void* AllocWithRetry(size_t size, MallocFn = base::Malloc);
V8_EXPORT_PRIVATE void* AlignedAlloc(size_t size, size_t alignment);
V8_EXPORT_PRIVATE void AlignedFree(void* ptr);

View File

@ -65,7 +65,11 @@ std::unique_ptr<v8::base::BoundedPageAllocator> CreateBoundedAllocator(
} // namespace
AccountingAllocator::AccountingAllocator() {
AccountingAllocator::AccountingAllocator()
: zone_backing_malloc_(
V8::GetCurrentPlatform()->GetZoneBackingAllocator()->GetMallocFn()),
zone_backing_free_(
V8::GetCurrentPlatform()->GetZoneBackingAllocator()->GetFreeFn()) {
if (COMPRESS_ZONES_BOOL) {
v8::PageAllocator* platform_page_allocator = GetPlatformPageAllocator();
VirtualMemory memory = ReserveAddressSpace(platform_page_allocator);
@ -86,7 +90,7 @@ Segment* AccountingAllocator::AllocateSegment(size_t bytes,
kZonePageSize, PageAllocator::kReadWrite);
} else {
memory = AllocWithRetry(bytes);
memory = AllocWithRetry(bytes, zone_backing_malloc_);
}
if (memory == nullptr) return nullptr;
@ -110,7 +114,7 @@ void AccountingAllocator::ReturnSegment(Segment* segment,
if (COMPRESS_ZONES_BOOL && supports_compression) {
CHECK(FreePages(bounded_page_allocator_.get(), segment, segment_size));
} else {
base::Free(segment);
zone_backing_free_(segment);
}
}

View File

@ -8,6 +8,7 @@
#include <atomic>
#include <memory>
#include "include/v8-platform.h"
#include "src/base/macros.h"
#include "src/logging/tracing-flags.h"
@ -71,6 +72,9 @@ class V8_EXPORT_PRIVATE AccountingAllocator {
std::unique_ptr<VirtualMemory> reserved_area_;
std::unique_ptr<base::BoundedPageAllocator> bounded_page_allocator_;
ZoneBackingAllocator::MallocFn zone_backing_malloc_ = nullptr;
ZoneBackingAllocator::FreeFn zone_backing_free_ = nullptr;
};
} // namespace internal