[vm] Simplify VirtualMemory::Truncate

Callers always want to try to unmap the trailing pages, and the
OS-specific FreeSubSegment helper routine can never fail. Simplify
code accordingly.

Change-Id: I32e4bc72f626e15032d73326bee76a4a2ef71025
Reviewed-on: https://dart-review.googlesource.com/c/91146
Auto-Submit: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Zach Anderson <zra@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
This commit is contained in:
Matthew Dempsky 2019-01-31 21:01:48 +00:00 committed by commit-bot@chromium.org
parent e717ecdc92
commit 9308cac681
6 changed files with 13 additions and 32 deletions

View file

@ -14,14 +14,12 @@ bool VirtualMemory::InSamePage(uword address0, uword address1) {
Utils::RoundDown(address1, PageSize()));
}
void VirtualMemory::Truncate(intptr_t new_size, bool try_unmap) {
ASSERT((new_size & (PageSize() - 1)) == 0);
void VirtualMemory::Truncate(intptr_t new_size) {
ASSERT(Utils::IsAligned(new_size, PageSize()));
ASSERT(new_size <= size());
if (try_unmap &&
(reserved_.size() ==
region_.size()) && /* Don't create holes in reservation. */
FreeSubSegment(reinterpret_cast<void*>(start() + new_size),
size() - new_size)) {
if (reserved_.size() == region_.size()) { // Don't create holes in reservation.
FreeSubSegment(reinterpret_cast<void*>(start() + new_size),
size() - new_size);
reserved_.set_size(new_size);
}
region_.Subregion(region_, 0, new_size);

View file

@ -57,10 +57,8 @@ class VirtualMemory {
static bool InSamePage(uword address0, uword address1);
// Truncate this virtual memory segment. If try_unmap is false, the
// memory beyond the new end is still accessible, but will be returned
// upon destruction.
void Truncate(intptr_t new_size, bool try_unmap = true);
// Truncate this virtual memory segment.
void Truncate(intptr_t new_size);
// False for a part of a snapshot added directly to the Dart heap, which
// belongs to the embedder and must not be deallocated or have its
@ -72,7 +70,7 @@ class VirtualMemory {
private:
// Free a sub segment. On operating systems that support it this
// can give back the virtual memory to the system. Returns true on success.
static bool FreeSubSegment(void* address, intptr_t size);
static void FreeSubSegment(void* address, intptr_t size);
// This constructor is only used internally when reserving new virtual spaces.
// It does not reserve any virtual address space on its own.

View file

@ -126,11 +126,10 @@ VirtualMemory::~VirtualMemory() {
}
}
bool VirtualMemory::FreeSubSegment(void* address, intptr_t size) {
void VirtualMemory::FreeSubSegment(void* address, intptr_t size) {
const uword start = reinterpret_cast<uword>(address);
unmap(zx_vmar_root_self(), start, start + size);
LOG_INFO("zx_vmar_unmap(%p, %lx) success\n", address, size);
return true;
}
void VirtualMemory::Protect(void* address, intptr_t size, Protection mode) {

View file

@ -76,11 +76,10 @@ VirtualMemory::~VirtualMemory() {
}
}
bool VirtualMemory::FreeSubSegment(void* address,
void VirtualMemory::FreeSubSegment(void* address,
intptr_t size) {
const uword start = reinterpret_cast<uword>(address);
unmap(start, start + size);
return true;
}
void VirtualMemory::Protect(void* address, intptr_t size, Protection mode) {

View file

@ -77,25 +77,13 @@ VM_UNIT_TEST_CASE(FreeVirtualMemory) {
for (intptr_t i = 0; i < kIterations; ++i) {
VirtualMemory* vm =
VirtualMemory::Allocate(kVirtualMemoryBlockSize, false, NULL);
vm->Truncate(kVirtualMemoryBlockSize / 2, true);
vm->Truncate(kVirtualMemoryBlockSize / 2);
delete vm;
}
for (intptr_t i = 0; i < kIterations; ++i) {
VirtualMemory* vm =
VirtualMemory::Allocate(kVirtualMemoryBlockSize, true, NULL);
vm->Truncate(kVirtualMemoryBlockSize / 2, false);
delete vm;
}
for (intptr_t i = 0; i < kIterations; ++i) {
VirtualMemory* vm =
VirtualMemory::Allocate(kVirtualMemoryBlockSize, true, NULL);
vm->Truncate(0, true);
delete vm;
}
for (intptr_t i = 0; i < kIterations; ++i) {
VirtualMemory* vm =
VirtualMemory::Allocate(kVirtualMemoryBlockSize, false, NULL);
vm->Truncate(0, false);
vm->Truncate(0);
delete vm;
}
}

View file

@ -62,12 +62,11 @@ VirtualMemory::~VirtualMemory() {
}
}
bool VirtualMemory::FreeSubSegment(void* address,
void VirtualMemory::FreeSubSegment(void* address,
intptr_t size) {
if (VirtualFree(address, size, MEM_DECOMMIT) == 0) {
FATAL1("VirtualFree failed: Error code %d\n", GetLastError());
}
return true;
}
void VirtualMemory::Protect(void* address, intptr_t size, Protection mode) {