Commit b73ee334 authored by Bill Budge's avatar Bill Budge Committed by Commit Bot

[Memory] Eliminate OS::ReleaseRegion.

- Eliminates OS::ReleaseRegion, replacing with calls to OS::Free.
- Adds bool return value to OS::Free.
- Cleans up types of flags, protection on Windows and Cygwin.

Bug: chromium:756050
Cq-Include-Trybots: master.tryserver.chromium.linux:linux_chromium_rel_ng
Change-Id: I6a642374e33876966a5552fb0cdf552dc6d79aaa
Reviewed-on: https://chromium-review.googlesource.com/762345
Commit-Queue: Bill Budge <bbudge@chromium.org>
Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#49305}
parent 4d3bc552
...@@ -129,9 +129,7 @@ VirtualMemory::VirtualMemory(size_t size, void* hint, size_t alignment) ...@@ -129,9 +129,7 @@ VirtualMemory::VirtualMemory(size_t size, void* hint, size_t alignment)
VirtualMemory::~VirtualMemory() { VirtualMemory::~VirtualMemory() {
if (IsReserved()) { if (IsReserved()) {
bool result = base::OS::ReleaseRegion(address(), size()); Release();
DCHECK(result);
USE(result);
} }
} }
...@@ -185,7 +183,7 @@ void VirtualMemory::Release() { ...@@ -185,7 +183,7 @@ void VirtualMemory::Release() {
size_t size = size_; size_t size = size_;
CHECK(InVM(address, size)); CHECK(InVM(address, size));
Reset(); Reset();
bool result = base::OS::ReleaseRegion(address, size); bool result = base::OS::Free(address, size);
USE(result); USE(result);
DCHECK(result); DCHECK(result);
} }
......
...@@ -509,7 +509,9 @@ class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator { ...@@ -509,7 +509,9 @@ class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
return Free(data, length); return Free(data, length);
} }
case v8::ArrayBuffer::Allocator::AllocationMode::kReservation: { case v8::ArrayBuffer::Allocator::AllocationMode::kReservation: {
base::OS::ReleaseRegion(data, length); bool result = base::OS::Free(data, length);
DCHECK(result);
USE(result);
return; return;
} }
} }
......
...@@ -28,13 +28,13 @@ namespace base { ...@@ -28,13 +28,13 @@ namespace base {
namespace { namespace {
// The VirtualMemory implementation is taken from platform-win32.cc. // The memory allocation implementation is taken from platform-win32.cc.
// The mmap-based virtual memory implementation as it is used on most posix // The mmap-based virtual memory implementation as it is used on most posix
// platforms does not work well because Cygwin does not support MAP_FIXED. // platforms does not work well because Cygwin does not support MAP_FIXED.
// This causes VirtualMemory::Commit to not always commit the memory region // This causes OS::CommitRegion to not always commit the memory region
// specified. // specified.
int GetProtectionFromMemoryPermission(OS::MemoryPermission access) { DWORD GetProtectionFromMemoryPermission(OS::MemoryPermission access) {
switch (access) { switch (access) {
case OS::MemoryPermission::kNoAccess: case OS::MemoryPermission::kNoAccess:
return PAGE_NOACCESS; return PAGE_NOACCESS;
...@@ -46,17 +46,17 @@ int GetProtectionFromMemoryPermission(OS::MemoryPermission access) { ...@@ -46,17 +46,17 @@ int GetProtectionFromMemoryPermission(OS::MemoryPermission access) {
UNREACHABLE(); UNREACHABLE();
} }
static void* RandomizedVirtualAlloc(size_t size, int action, int protection, void* RandomizedVirtualAlloc(size_t size, DWORD flags, DWORD protect,
void* hint) { void* hint) {
LPVOID base = nullptr; LPVOID base = nullptr;
if (protection == PAGE_EXECUTE_READWRITE || protection == PAGE_NOACCESS) { if (protect == PAGE_EXECUTE_READWRITE || protect == PAGE_NOACCESS) {
// For exectutable pages try and randomize the allocation address // For exectutable pages try and randomize the allocation address
base = VirtualAlloc(hint, size, action, protection); base = VirtualAlloc(hint, size, flags, protect);
} }
// After three attempts give up and let the OS find an address to use. // If that fails, let the OS find an address to use.
if (base == nullptr) base = VirtualAlloc(nullptr, size, action, protection); if (base == nullptr) base = VirtualAlloc(nullptr, size, flags, protect);
return base; return base;
} }
...@@ -92,6 +92,7 @@ double CygwinTimezoneCache::LocalTimeOffset() { ...@@ -92,6 +92,7 @@ double CygwinTimezoneCache::LocalTimeOffset() {
(loc->tm_isdst > 0 ? 3600 * msPerSecond : 0)); (loc->tm_isdst > 0 ? 3600 * msPerSecond : 0));
} }
// static
void* OS::Allocate(void* address, size_t size, size_t alignment, void* OS::Allocate(void* address, size_t size, size_t alignment,
MemoryPermission access) { MemoryPermission access) {
size_t page_size = AllocatePageSize(); size_t page_size = AllocatePageSize();
...@@ -101,12 +102,12 @@ void* OS::Allocate(void* address, size_t size, size_t alignment, ...@@ -101,12 +102,12 @@ void* OS::Allocate(void* address, size_t size, size_t alignment,
// Add the maximum misalignment so we are guaranteed an aligned base address. // Add the maximum misalignment so we are guaranteed an aligned base address.
size_t request_size = size + (alignment - page_size); size_t request_size = size + (alignment - page_size);
int flags = (access == OS::MemoryPermission::kNoAccess) DWORD flags = (access == OS::MemoryPermission::kNoAccess)
? MEM_RESERVE ? MEM_RESERVE
: MEM_RESERVE | MEM_COMMIT; : MEM_RESERVE | MEM_COMMIT;
int prot = GetProtectionFromMemoryPermission(access); DWORD protect = GetProtectionFromMemoryPermission(access);
void* base = RandomizedVirtualAlloc(request_size, flags, prot, address); void* base = RandomizedVirtualAlloc(request_size, flags, protect, address);
if (base == nullptr) return nullptr; if (base == nullptr) return nullptr;
uint8_t* aligned_base = RoundUp(static_cast<uint8_t*>(base), alignment); uint8_t* aligned_base = RoundUp(static_cast<uint8_t*>(base), alignment);
...@@ -117,7 +118,7 @@ void* OS::Allocate(void* address, size_t size, size_t alignment, ...@@ -117,7 +118,7 @@ void* OS::Allocate(void* address, size_t size, size_t alignment,
// base. Retry logic is needed since we may lose the memory due to a race. // base. Retry logic is needed since we may lose the memory due to a race.
Free(base, request_size); Free(base, request_size);
if (resize_attempts == kMaxResizeAttempts) return nullptr; if (resize_attempts == kMaxResizeAttempts) return nullptr;
base = RandomizedVirtualAlloc(size, flags, prot, aligned_base); base = RandomizedVirtualAlloc(size, flags, protect, aligned_base);
if (base == nullptr) return nullptr; if (base == nullptr) return nullptr;
aligned_base = RoundUp(static_cast<uint8_t*>(base), alignment); aligned_base = RoundUp(static_cast<uint8_t*>(base), alignment);
resize_attempts++; resize_attempts++;
...@@ -126,19 +127,15 @@ void* OS::Allocate(void* address, size_t size, size_t alignment, ...@@ -126,19 +127,15 @@ void* OS::Allocate(void* address, size_t size, size_t alignment,
return static_cast<void*>(aligned_base); return static_cast<void*>(aligned_base);
} }
void OS::Free(void* address, const size_t size) { // static
// TODO(1240712): VirtualFree has a return value which is ignored here. bool OS::Free(void* address, const size_t size) {
VirtualFree(address, 0, MEM_RELEASE); return VirtualFree(address, 0, MEM_RELEASE) != 0;
USE(size);
} }
// static // static
bool OS::CommitRegion(void* address, size_t size, bool is_executable) { bool OS::CommitRegion(void* address, size_t size, bool is_executable) {
int prot = is_executable ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE; DWORD protect = is_executable ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE;
if (nullptr == VirtualAlloc(address, size, MEM_COMMIT, prot)) { return VirtualAlloc(address, size, MEM_COMMIT, protect) != nullptr;
return false;
}
return true;
} }
// static // static
...@@ -146,11 +143,6 @@ bool OS::UncommitRegion(void* address, size_t size) { ...@@ -146,11 +143,6 @@ bool OS::UncommitRegion(void* address, size_t size) {
return VirtualFree(address, size, MEM_DECOMMIT) != 0; return VirtualFree(address, size, MEM_DECOMMIT) != 0;
} }
// static
bool OS::ReleaseRegion(void* address, size_t size) {
return VirtualFree(address, 0, MEM_RELEASE) != 0;
}
// static // static
bool OS::ReleasePartialRegion(void* address, size_t size) { bool OS::ReleasePartialRegion(void* address, size_t size) {
return VirtualFree(address, size, MEM_DECOMMIT) != 0; return VirtualFree(address, size, MEM_DECOMMIT) != 0;
......
...@@ -73,6 +73,12 @@ void* OS::Allocate(void* address, size_t size, size_t alignment, ...@@ -73,6 +73,12 @@ void* OS::Allocate(void* address, size_t size, size_t alignment,
return static_cast<void*>(aligned_base); return static_cast<void*>(aligned_base);
} }
// static
bool OS::Free(void* address, size_t size) {
return zx_vmar_unmap(zx_vmar_root_self(),
reinterpret_cast<uintptr_t>(address), size) == ZX_OK;
}
// static // static
void OS::Guard(void* address, size_t size) { void OS::Guard(void* address, size_t size) {
CHECK_EQ(ZX_OK, zx_vmar_protect(zx_vmar_root_self(), CHECK_EQ(ZX_OK, zx_vmar_protect(zx_vmar_root_self(),
...@@ -96,12 +102,6 @@ bool OS::UncommitRegion(void* address, size_t size) { ...@@ -96,12 +102,6 @@ bool OS::UncommitRegion(void* address, size_t size) {
0 /*no permissions*/) == ZX_OK; 0 /*no permissions*/) == ZX_OK;
} }
// static
bool OS::ReleaseRegion(void* address, size_t size) {
return zx_vmar_unmap(zx_vmar_root_self(),
reinterpret_cast<uintptr_t>(address), size) == ZX_OK;
}
// static // static
bool OS::ReleasePartialRegion(void* address, size_t size) { bool OS::ReleasePartialRegion(void* address, size_t size) {
return zx_vmar_unmap(zx_vmar_root_self(), return zx_vmar_unmap(zx_vmar_root_self(),
......
...@@ -230,6 +230,7 @@ void* OS::GetRandomMmapAddr() { ...@@ -230,6 +230,7 @@ void* OS::GetRandomMmapAddr() {
// TODO(bbudge) Move Cygwin and Fuschia stuff into platform-specific files. // TODO(bbudge) Move Cygwin and Fuschia stuff into platform-specific files.
#if !V8_OS_CYGWIN && !V8_OS_FUCHSIA #if !V8_OS_CYGWIN && !V8_OS_FUCHSIA
// static
void* OS::Allocate(void* address, size_t size, size_t alignment, void* OS::Allocate(void* address, size_t size, size_t alignment,
MemoryPermission access) { MemoryPermission access) {
size_t page_size = AllocatePageSize(); size_t page_size = AllocatePageSize();
...@@ -261,16 +262,12 @@ void* OS::Allocate(void* address, size_t size, size_t alignment, ...@@ -261,16 +262,12 @@ void* OS::Allocate(void* address, size_t size, size_t alignment,
DCHECK_EQ(size, request_size); DCHECK_EQ(size, request_size);
return static_cast<void*>(aligned_base); return static_cast<void*>(aligned_base);
} }
#endif // !V8_OS_CYGWIN && !V8_OS_FUCHSIA
#if !V8_OS_CYGWIN // static
void OS::Free(void* address, const size_t size) { bool OS::Free(void* address, const size_t size) {
// TODO(1240712): munmap has a return value which is ignored here. return munmap(address, size) == 0;
int result = munmap(address, size);
USE(result);
DCHECK_EQ(0, result);
} }
#endif // !V8_OS_CYGWIN #endif // !V8_OS_CYGWIN && !V8_OS_FUCHSIA
void OS::SetReadAndExecutable(void* address, const size_t size) { void OS::SetReadAndExecutable(void* address, const size_t size) {
#if V8_OS_CYGWIN #if V8_OS_CYGWIN
...@@ -348,11 +345,6 @@ bool OS::UncommitRegion(void* address, size_t size) { ...@@ -348,11 +345,6 @@ bool OS::UncommitRegion(void* address, size_t size) {
#endif // V8_OS_AIX #endif // V8_OS_AIX
} }
// static
bool OS::ReleaseRegion(void* address, size_t size) {
return munmap(address, size) == 0;
}
// static // static
bool OS::ReleasePartialRegion(void* address, size_t size) { bool OS::ReleasePartialRegion(void* address, size_t size) {
return munmap(address, size) == 0; return munmap(address, size) == 0;
......
...@@ -732,7 +732,7 @@ void* OS::GetRandomMmapAddr() { ...@@ -732,7 +732,7 @@ void* OS::GetRandomMmapAddr() {
namespace { namespace {
int GetProtectionFromMemoryPermission(OS::MemoryPermission access) { DWORD GetProtectionFromMemoryPermission(OS::MemoryPermission access) {
switch (access) { switch (access) {
case OS::MemoryPermission::kNoAccess: case OS::MemoryPermission::kNoAccess:
return PAGE_NOACCESS; return PAGE_NOACCESS;
...@@ -744,8 +744,8 @@ int GetProtectionFromMemoryPermission(OS::MemoryPermission access) { ...@@ -744,8 +744,8 @@ int GetProtectionFromMemoryPermission(OS::MemoryPermission access) {
UNREACHABLE(); UNREACHABLE();
} }
static void* RandomizedVirtualAlloc(size_t size, int action, int protection, void* RandomizedVirtualAlloc(size_t size, DWORD flags, DWORD protect,
void* hint) { void* hint) {
LPVOID base = NULL; LPVOID base = NULL;
static BOOL use_aslr = -1; static BOOL use_aslr = -1;
#ifdef V8_HOST_ARCH_32_BIT #ifdef V8_HOST_ARCH_32_BIT
...@@ -758,19 +758,20 @@ static void* RandomizedVirtualAlloc(size_t size, int action, int protection, ...@@ -758,19 +758,20 @@ static void* RandomizedVirtualAlloc(size_t size, int action, int protection,
#endif #endif
if (use_aslr && if (use_aslr &&
(protection == PAGE_EXECUTE_READWRITE || protection == PAGE_NOACCESS)) { (protect == PAGE_EXECUTE_READWRITE || protect == PAGE_NOACCESS)) {
// For executable or reserved pages try to randomize the allocation address. // For executable or reserved pages try to randomize the allocation address.
base = VirtualAlloc(hint, size, action, protection); base = VirtualAlloc(hint, size, flags, protect);
} }
// On failure, let the OS find an address to use. // On failure, let the OS find an address to use.
if (base == NULL) base = VirtualAlloc(nullptr, size, action, protection); if (base == NULL) base = VirtualAlloc(nullptr, size, flags, protect);
return base; return base;
} }
} // namespace } // namespace
// static
void* OS::Allocate(void* address, size_t size, size_t alignment, void* OS::Allocate(void* address, size_t size, size_t alignment,
MemoryPermission access) { MemoryPermission access) {
size_t page_size = AllocatePageSize(); size_t page_size = AllocatePageSize();
...@@ -783,9 +784,9 @@ void* OS::Allocate(void* address, size_t size, size_t alignment, ...@@ -783,9 +784,9 @@ void* OS::Allocate(void* address, size_t size, size_t alignment,
int flags = (access == OS::MemoryPermission::kNoAccess) int flags = (access == OS::MemoryPermission::kNoAccess)
? MEM_RESERVE ? MEM_RESERVE
: MEM_RESERVE | MEM_COMMIT; : MEM_RESERVE | MEM_COMMIT;
int prot = GetProtectionFromMemoryPermission(access); int protect = GetProtectionFromMemoryPermission(access);
void* base = RandomizedVirtualAlloc(request_size, flags, prot, address); void* base = RandomizedVirtualAlloc(request_size, flags, protect, address);
if (base == nullptr) return nullptr; if (base == nullptr) return nullptr;
uint8_t* aligned_base = RoundUp(static_cast<uint8_t*>(base), alignment); uint8_t* aligned_base = RoundUp(static_cast<uint8_t*>(base), alignment);
...@@ -796,7 +797,7 @@ void* OS::Allocate(void* address, size_t size, size_t alignment, ...@@ -796,7 +797,7 @@ void* OS::Allocate(void* address, size_t size, size_t alignment,
// base. Retry logic is needed since we may lose the memory due to a race. // base. Retry logic is needed since we may lose the memory due to a race.
Free(base, request_size); Free(base, request_size);
if (resize_attempts == kMaxResizeAttempts) return nullptr; if (resize_attempts == kMaxResizeAttempts) return nullptr;
base = RandomizedVirtualAlloc(size, flags, prot, aligned_base); base = RandomizedVirtualAlloc(size, flags, protect, aligned_base);
if (base == nullptr) return nullptr; if (base == nullptr) return nullptr;
aligned_base = RoundUp(static_cast<uint8_t*>(base), alignment); aligned_base = RoundUp(static_cast<uint8_t*>(base), alignment);
resize_attempts++; resize_attempts++;
...@@ -805,10 +806,9 @@ void* OS::Allocate(void* address, size_t size, size_t alignment, ...@@ -805,10 +806,9 @@ void* OS::Allocate(void* address, size_t size, size_t alignment,
return static_cast<void*>(aligned_base); return static_cast<void*>(aligned_base);
} }
void OS::Free(void* address, const size_t size) { // static
// TODO(1240712): VirtualFree has a return value which is ignored here. bool OS::Free(void* address, const size_t size) {
VirtualFree(address, 0, MEM_RELEASE); return VirtualFree(address, 0, MEM_RELEASE) != 0;
USE(size);
} }
void OS::SetReadAndExecutable(void* address, const size_t size) { void OS::SetReadAndExecutable(void* address, const size_t size) {
...@@ -840,11 +840,8 @@ void OS::SetReadWriteAndExecutable(void* address, const size_t size) { ...@@ -840,11 +840,8 @@ void OS::SetReadWriteAndExecutable(void* address, const size_t size) {
// static // static
bool OS::CommitRegion(void* address, size_t size, bool is_executable) { bool OS::CommitRegion(void* address, size_t size, bool is_executable) {
int prot = is_executable ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE; DWORD protect = is_executable ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE;
if (NULL == VirtualAlloc(address, size, MEM_COMMIT, prot)) { return VirtualAlloc(address, size, MEM_COMMIT, protect) != nullptr;
return false;
}
return true;
} }
// static // static
...@@ -852,11 +849,6 @@ bool OS::UncommitRegion(void* address, size_t size) { ...@@ -852,11 +849,6 @@ bool OS::UncommitRegion(void* address, size_t size) {
return VirtualFree(address, size, MEM_DECOMMIT) != 0; return VirtualFree(address, size, MEM_DECOMMIT) != 0;
} }
// static
bool OS::ReleaseRegion(void* address, size_t size) {
return VirtualFree(address, 0, MEM_RELEASE) != 0;
}
// static // static
bool OS::ReleasePartialRegion(void* address, size_t size) { bool OS::ReleasePartialRegion(void* address, size_t size) {
return VirtualFree(address, size, MEM_DECOMMIT) != 0; return VirtualFree(address, size, MEM_DECOMMIT) != 0;
......
...@@ -179,7 +179,7 @@ class V8_BASE_EXPORT OS { ...@@ -179,7 +179,7 @@ class V8_BASE_EXPORT OS {
MemoryPermission access); MemoryPermission access);
// Frees memory allocated by a call to Allocate. // Frees memory allocated by a call to Allocate.
static void Free(void* address, const size_t size); static bool Free(void* address, const size_t size);
// Mark a region of memory executable and readable but not writable. // Mark a region of memory executable and readable but not writable.
static void SetReadAndExecutable(void* address, const size_t size); static void SetReadAndExecutable(void* address, const size_t size);
...@@ -198,8 +198,6 @@ class V8_BASE_EXPORT OS { ...@@ -198,8 +198,6 @@ class V8_BASE_EXPORT OS {
static bool UncommitRegion(void* address, size_t size); static bool UncommitRegion(void* address, size_t size);
static bool ReleaseRegion(void* address, size_t size);
// Release part of a reserved address range. // Release part of a reserved address range.
static bool ReleasePartialRegion(void* address, size_t size); static bool ReleasePartialRegion(void* address, size_t size);
......
...@@ -142,7 +142,9 @@ class ShellArrayBufferAllocator : public ArrayBufferAllocatorBase { ...@@ -142,7 +142,9 @@ class ShellArrayBufferAllocator : public ArrayBufferAllocatorBase {
void Free(void* data, size_t length) override { void Free(void* data, size_t length) override {
#if USE_VM #if USE_VM
if (RoundToPageSize(&length)) { if (RoundToPageSize(&length)) {
base::OS::ReleaseRegion(data, length); bool result = base::OS::Free(data, length);
DCHECK(result);
USE(result);
return; return;
} }
#endif #endif
......
...@@ -443,7 +443,7 @@ void MemoryAllocator::FreeMemory(Address base, size_t size, ...@@ -443,7 +443,7 @@ void MemoryAllocator::FreeMemory(Address base, size_t size,
code_range()->FreeRawMemory(base, size); code_range()->FreeRawMemory(base, size);
} else { } else {
DCHECK(executable == NOT_EXECUTABLE || !code_range()->valid()); DCHECK(executable == NOT_EXECUTABLE || !code_range()->valid());
bool result = base::OS::ReleaseRegion(base, size); bool result = base::OS::Free(base, size);
USE(result); USE(result);
DCHECK(result); DCHECK(result);
} }
......
...@@ -24,7 +24,7 @@ TEST(OSReserveMemory) { ...@@ -24,7 +24,7 @@ TEST(OSReserveMemory) {
int* addr = static_cast<int*>(mem_addr); int* addr = static_cast<int*>(mem_addr);
addr[KB - 1] = 2; addr[KB - 1] = 2;
CHECK(OS::UncommitRegion(mem_addr, commit_size)); CHECK(OS::UncommitRegion(mem_addr, commit_size));
OS::ReleaseRegion(mem_addr, page_size); CHECK(OS::Free(mem_addr, page_size));
} }
#ifdef V8_CC_GNU #ifdef V8_CC_GNU
......
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