[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:
parent
74ca05b05f
commit
e262e1cb4a
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user