Commit da9d6899 authored by Dominik Inführ's avatar Dominik Inführ Committed by V8 LUCI CQ

[heap] Crash immediately when page allocation fails in deserialization

Fail immediately when page allocation fails during deserialization. We
would crash immediately in the GC following the allocation failure but
with a less descriptive error message.

Bug: v8:12514
Change-Id: I688d9bac5978ca7af3b24830999c992e1df32dce
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3568458Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Commit-Queue: Dominik Inführ <dinfuehr@chromium.org>
Cr-Commit-Position: refs/heads/main@{#79755}
parent f21e2a7f
...@@ -244,7 +244,7 @@ Address MemoryAllocator::AllocateAlignedMemory( ...@@ -244,7 +244,7 @@ Address MemoryAllocator::AllocateAlignedMemory(
DCHECK_LT(area_size, chunk_size); DCHECK_LT(area_size, chunk_size);
VirtualMemory reservation(page_allocator, chunk_size, hint, alignment); VirtualMemory reservation(page_allocator, chunk_size, hint, alignment);
if (!reservation.IsReserved()) return kNullAddress; if (!reservation.IsReserved()) return HandleAllocationFailure();
// We cannot use the last chunk in the address space because we would // We cannot use the last chunk in the address space because we would
// overflow when comparing top and limit if this chunk is used for a // overflow when comparing top and limit if this chunk is used for a
...@@ -256,7 +256,7 @@ Address MemoryAllocator::AllocateAlignedMemory( ...@@ -256,7 +256,7 @@ Address MemoryAllocator::AllocateAlignedMemory(
// Retry reserve virtual memory. // Retry reserve virtual memory.
reservation = VirtualMemory(page_allocator, chunk_size, hint, alignment); reservation = VirtualMemory(page_allocator, chunk_size, hint, alignment);
if (!reservation.IsReserved()) return kNullAddress; if (!reservation.IsReserved()) return HandleAllocationFailure();
} }
Address base = reservation.address(); Address base = reservation.address();
...@@ -265,7 +265,7 @@ Address MemoryAllocator::AllocateAlignedMemory( ...@@ -265,7 +265,7 @@ Address MemoryAllocator::AllocateAlignedMemory(
const size_t aligned_area_size = ::RoundUp(area_size, GetCommitPageSize()); const size_t aligned_area_size = ::RoundUp(area_size, GetCommitPageSize());
if (!SetPermissionsOnExecutableMemoryChunk(&reservation, base, if (!SetPermissionsOnExecutableMemoryChunk(&reservation, base,
aligned_area_size, chunk_size)) { aligned_area_size, chunk_size)) {
base = kNullAddress; return HandleAllocationFailure();
} }
} else { } else {
// No guard page between page header and object area. This allows us to make // No guard page between page header and object area. This allows us to make
...@@ -278,21 +278,23 @@ Address MemoryAllocator::AllocateAlignedMemory( ...@@ -278,21 +278,23 @@ Address MemoryAllocator::AllocateAlignedMemory(
PageAllocator::kReadWrite)) { PageAllocator::kReadWrite)) {
UpdateAllocatedSpaceLimits(base, base + commit_size); UpdateAllocatedSpaceLimits(base, base + commit_size);
} else { } else {
base = kNullAddress; return HandleAllocationFailure();
} }
} }
if (base == kNullAddress) {
// Failed to commit the body. Free the mapping and any partially committed
// regions inside it.
reservation.Free();
return kNullAddress;
}
*controller = std::move(reservation); *controller = std::move(reservation);
return base; return base;
} }
Address MemoryAllocator::HandleAllocationFailure() {
Heap* heap = isolate_->heap();
if (!heap->deserialization_complete()) {
heap->FatalProcessOutOfMemory(
"MemoryChunk allocation failed during deserialization.");
}
return kNullAddress;
}
size_t MemoryAllocator::ComputeChunkSize(size_t area_size, size_t MemoryAllocator::ComputeChunkSize(size_t area_size,
Executability executable) { Executability executable) {
if (executable == EXECUTABLE) { if (executable == EXECUTABLE) {
......
...@@ -258,6 +258,8 @@ class MemoryAllocator { ...@@ -258,6 +258,8 @@ class MemoryAllocator {
void UnregisterReadOnlyPage(ReadOnlyPage* page); void UnregisterReadOnlyPage(ReadOnlyPage* page);
Address HandleAllocationFailure();
private: private:
// Used to store all data about MemoryChunk allocation, e.g. in // Used to store all data about MemoryChunk allocation, e.g. in
// AllocateUninitializedChunk. // AllocateUninitializedChunk.
......
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