[vm] Fix deallocation of compressed heap

When VirtualMemory object for the whole compressed pointers heap
region is destroyed in VirtualMemory::~VirtualMemory(), it tests
if the reservation address belongs to a compressed heap via

  VirtualMemoryCompressedHeap::Contains(reserved_.pointer())

If the heap region happens to be reserved at the 4GB aligned address
by the O/S, then reservation address would match base address of
the compressed pointers heap, and this check would pass and
the whole reserved heap region would be passed to
VirtualMemoryCompressedHeap::Free.

However, the reservation size of the whole heap region is
(8GB - 1 page) which is not aligned to kCompressedPageSize (512K).
This would trigger assertion

  ASSERT(Utils::IsAligned(size, kCompressedPageSize));

inside VirtualMemoryCompressedHeap::Free.

The fix is to detect when the whole compressed heap region is being
destroyed and avoid calling VirtualMemoryCompressedHeap::Free
as the region reserved for the whole heap is not managed by
the compressed heap itself.

TEST=python3 tools/test.py -n vm-win-debug-x64c --repeat 10000 co19/LibTest/typed_data/Uint32List/Uint32List.view_A01_t01
Fixes https://github.com/dart-lang/sdk/issues/51170

Change-Id: Icdf02eb0e2e3f39e435cba76fa647726bb383928
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/352962
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Liam Appelbe <liama@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
This commit is contained in:
Alexander Markov 2024-02-16 01:05:49 +00:00 committed by Commit Queue
parent 688917045f
commit 9c34f96822
2 changed files with 4 additions and 2 deletions

View file

@ -365,7 +365,8 @@ void VirtualMemory::Decommit(void* address, intptr_t size) {
VirtualMemory::~VirtualMemory() {
#if defined(DART_COMPRESSED_POINTERS)
if (VirtualMemoryCompressedHeap::Contains(reserved_.pointer())) {
if (VirtualMemoryCompressedHeap::Contains(reserved_.pointer()) &&
(this != compressed_heap_)) {
Decommit(reserved_.pointer(), reserved_.size());
VirtualMemoryCompressedHeap::Free(reserved_.pointer(), reserved_.size());
return;

View file

@ -178,7 +178,8 @@ VirtualMemory::~VirtualMemory() {
// itself. The only way to release the mapping is to invoke VirtualFree
// with original base pointer and MEM_RELEASE.
#if defined(DART_COMPRESSED_POINTERS)
if (VirtualMemoryCompressedHeap::Contains(reserved_.pointer())) {
if (VirtualMemoryCompressedHeap::Contains(reserved_.pointer()) &&
(this != compressed_heap_)) {
Decommit(reserved_.pointer(), reserved_.size());
VirtualMemoryCompressedHeap::Free(reserved_.pointer(), reserved_.size());
return;