Commit e262e1cb authored by Anton Bikineev's avatar Anton Bikineev Committed by V8 LUCI CQ

[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/+/3172760Reviewed-by: 's avatarIgor Sheludko <ishell@chromium.org>
Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Commit-Queue: Anton Bikineev <bikineev@chromium.org>
Cr-Commit-Position: refs/heads/main@{#77012}
parent 74ca05b0
...@@ -516,6 +516,18 @@ class PageAllocator { ...@@ -516,6 +516,18 @@ class PageAllocator {
virtual bool CanAllocateSharedPages() { return false; } 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. * V8 Platform abstraction layer.
* *
...@@ -534,6 +546,14 @@ class Platform { ...@@ -534,6 +546,14 @@ class Platform {
return nullptr; 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 * 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 * blocks of memory. V8 retries the failed allocation once after calling this
......
...@@ -141,10 +141,10 @@ char* StrNDup(const char* str, size_t n) { ...@@ -141,10 +141,10 @@ char* StrNDup(const char* str, size_t n) {
return result; return result;
} }
void* AllocWithRetry(size_t size) { void* AllocWithRetry(size_t size, MallocFn malloc_fn) {
void* result = nullptr; void* result = nullptr;
for (int i = 0; i < kAllocationTries; ++i) { for (int i = 0; i < kAllocationTries; ++i) {
result = base::Malloc(size); result = malloc_fn(size);
if (result != nullptr) break; if (result != nullptr) break;
if (!OnCriticalMemoryPressure(size)) break; if (!OnCriticalMemoryPressure(size)) break;
} }
......
...@@ -90,9 +90,11 @@ class FreeStoreAllocationPolicy { ...@@ -90,9 +90,11 @@ class FreeStoreAllocationPolicy {
} }
}; };
using MallocFn = void* (*)(size_t);
// Performs a malloc, with retry logic on failure. Returns nullptr on failure. // Performs a malloc, with retry logic on failure. Returns nullptr on failure.
// Call free to release memory allocated with this function. // 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* AlignedAlloc(size_t size, size_t alignment);
V8_EXPORT_PRIVATE void AlignedFree(void* ptr); V8_EXPORT_PRIVATE void AlignedFree(void* ptr);
......
...@@ -65,7 +65,11 @@ std::unique_ptr<v8::base::BoundedPageAllocator> CreateBoundedAllocator( ...@@ -65,7 +65,11 @@ std::unique_ptr<v8::base::BoundedPageAllocator> CreateBoundedAllocator(
} // namespace } // namespace
AccountingAllocator::AccountingAllocator() { AccountingAllocator::AccountingAllocator()
: zone_backing_malloc_(
V8::GetCurrentPlatform()->GetZoneBackingAllocator()->GetMallocFn()),
zone_backing_free_(
V8::GetCurrentPlatform()->GetZoneBackingAllocator()->GetFreeFn()) {
if (COMPRESS_ZONES_BOOL) { if (COMPRESS_ZONES_BOOL) {
v8::PageAllocator* platform_page_allocator = GetPlatformPageAllocator(); v8::PageAllocator* platform_page_allocator = GetPlatformPageAllocator();
VirtualMemory memory = ReserveAddressSpace(platform_page_allocator); VirtualMemory memory = ReserveAddressSpace(platform_page_allocator);
...@@ -86,7 +90,7 @@ Segment* AccountingAllocator::AllocateSegment(size_t bytes, ...@@ -86,7 +90,7 @@ Segment* AccountingAllocator::AllocateSegment(size_t bytes,
kZonePageSize, PageAllocator::kReadWrite); kZonePageSize, PageAllocator::kReadWrite);
} else { } else {
memory = AllocWithRetry(bytes); memory = AllocWithRetry(bytes, zone_backing_malloc_);
} }
if (memory == nullptr) return nullptr; if (memory == nullptr) return nullptr;
...@@ -110,7 +114,7 @@ void AccountingAllocator::ReturnSegment(Segment* segment, ...@@ -110,7 +114,7 @@ void AccountingAllocator::ReturnSegment(Segment* segment,
if (COMPRESS_ZONES_BOOL && supports_compression) { if (COMPRESS_ZONES_BOOL && supports_compression) {
CHECK(FreePages(bounded_page_allocator_.get(), segment, segment_size)); CHECK(FreePages(bounded_page_allocator_.get(), segment, segment_size));
} else { } else {
base::Free(segment); zone_backing_free_(segment);
} }
} }
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <atomic> #include <atomic>
#include <memory> #include <memory>
#include "include/v8-platform.h"
#include "src/base/macros.h" #include "src/base/macros.h"
#include "src/logging/tracing-flags.h" #include "src/logging/tracing-flags.h"
...@@ -71,6 +72,9 @@ class V8_EXPORT_PRIVATE AccountingAllocator { ...@@ -71,6 +72,9 @@ class V8_EXPORT_PRIVATE AccountingAllocator {
std::unique_ptr<VirtualMemory> reserved_area_; std::unique_ptr<VirtualMemory> reserved_area_;
std::unique_ptr<base::BoundedPageAllocator> bounded_page_allocator_; std::unique_ptr<base::BoundedPageAllocator> bounded_page_allocator_;
ZoneBackingAllocator::MallocFn zone_backing_malloc_ = nullptr;
ZoneBackingAllocator::FreeFn zone_backing_free_ = nullptr;
}; };
} // namespace internal } // namespace internal
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment