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

[Memory] Rename OS::ReleasePartialRegion to OS::Release.

- Change VirtualMemory to match OS memory concepts. Rename Release
  Free, ReleasePartial to Release.
- Adds comments to make the semantics clear. Right now V8 munmaps
  on POSIX, making address space available, while on Windows it is
  only possible to decommit.

Bug: chromium:756050
Change-Id: I6ba04d857ab9e1ca1f273e9e766e0825e67210cc
Reviewed-on: https://chromium-review.googlesource.com/783513Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Commit-Queue: Bill Budge <bbudge@chromium.org>
Cr-Commit-Position: refs/heads/master@{#49586}
parent da0af285
...@@ -129,7 +129,7 @@ VirtualMemory::VirtualMemory(size_t size, void* hint, size_t alignment) ...@@ -129,7 +129,7 @@ VirtualMemory::VirtualMemory(size_t size, void* hint, size_t alignment)
VirtualMemory::~VirtualMemory() { VirtualMemory::~VirtualMemory() {
if (IsReserved()) { if (IsReserved()) {
Release(); Free();
} }
} }
...@@ -147,8 +147,10 @@ bool VirtualMemory::SetPermissions(void* address, size_t size, ...@@ -147,8 +147,10 @@ bool VirtualMemory::SetPermissions(void* address, size_t size,
return result; return result;
} }
size_t VirtualMemory::ReleasePartial(void* free_start) { size_t VirtualMemory::Release(void* free_start) {
DCHECK(IsReserved()); DCHECK(IsReserved());
DCHECK(IsAddressAligned(static_cast<Address>(free_start),
base::OS::CommitPageSize()));
// Notice: Order is important here. The VirtualMemory object might live // Notice: Order is important here. The VirtualMemory object might live
// inside the allocated region. // inside the allocated region.
const size_t free_size = size_ - (reinterpret_cast<size_t>(free_start) - const size_t free_size = size_ - (reinterpret_cast<size_t>(free_start) -
...@@ -161,14 +163,12 @@ size_t VirtualMemory::ReleasePartial(void* free_start) { ...@@ -161,14 +163,12 @@ size_t VirtualMemory::ReleasePartial(void* free_start) {
__lsan_unregister_root_region(address_, size_); __lsan_unregister_root_region(address_, size_);
__lsan_register_root_region(address_, size_ - free_size); __lsan_register_root_region(address_, size_ - free_size);
#endif #endif
const bool result = base::OS::ReleasePartialRegion(free_start, free_size); CHECK(base::OS::Release(free_start, free_size));
USE(result);
DCHECK(result);
size_ -= free_size; size_ -= free_size;
return free_size; return free_size;
} }
void VirtualMemory::Release() { void VirtualMemory::Free() {
DCHECK(IsReserved()); DCHECK(IsReserved());
// Notice: Order is important here. The VirtualMemory object might live // Notice: Order is important here. The VirtualMemory object might live
// inside the allocated region. // inside the allocated region.
......
...@@ -133,10 +133,11 @@ class V8_EXPORT_PRIVATE VirtualMemory { ...@@ -133,10 +133,11 @@ class V8_EXPORT_PRIVATE VirtualMemory {
bool SetPermissions(void* address, size_t size, bool SetPermissions(void* address, size_t size,
base::OS::MemoryPermission access); base::OS::MemoryPermission access);
// Releases the memory after |free_start|. Returns the bytes released. // Releases memory after |free_start|. Returns the number of bytes released.
size_t ReleasePartial(void* free_start); size_t Release(void* free_start);
void Release(); // Frees all memory.
void Free();
// Assign control of the reserved region to a different VirtualMemory object. // Assign control of the reserved region to a different VirtualMemory object.
// The old object is no longer functional (IsReserved() returns false). // The old object is no longer functional (IsReserved() returns false).
......
...@@ -141,6 +141,13 @@ bool OS::Free(void* address, const size_t size) { ...@@ -141,6 +141,13 @@ bool OS::Free(void* address, const size_t size) {
return VirtualFree(address, 0, MEM_RELEASE) != 0; return VirtualFree(address, 0, MEM_RELEASE) != 0;
} }
// static
bool OS::Release(void* address, size_t size) {
DCHECK_EQ(0, reinterpret_cast<uintptr_t>(address) % CommitPageSize());
DCHECK_EQ(0, size % CommitPageSize());
return VirtualFree(address, size, MEM_DECOMMIT) != 0;
}
// static // static
bool OS::SetPermissions(void* address, size_t size, MemoryPermission access) { bool OS::SetPermissions(void* address, size_t size, MemoryPermission access) {
DCHECK_EQ(0, reinterpret_cast<uintptr_t>(address) % CommitPageSize()); DCHECK_EQ(0, reinterpret_cast<uintptr_t>(address) % CommitPageSize());
...@@ -152,11 +159,6 @@ bool OS::SetPermissions(void* address, size_t size, MemoryPermission access) { ...@@ -152,11 +159,6 @@ bool OS::SetPermissions(void* address, size_t size, MemoryPermission access) {
return VirtualAlloc(address, size, MEM_COMMIT, protect) != nullptr; return VirtualAlloc(address, size, MEM_COMMIT, protect) != nullptr;
} }
// static
bool OS::ReleasePartialRegion(void* address, size_t size) {
return VirtualFree(address, size, MEM_DECOMMIT) != 0;
}
// static // static
bool OS::HasLazyCommits() { bool OS::HasLazyCommits() {
// TODO(alph): implement for the platform. // TODO(alph): implement for the platform.
......
...@@ -99,6 +99,14 @@ bool OS::Free(void* address, const size_t size) { ...@@ -99,6 +99,14 @@ bool OS::Free(void* address, const size_t size) {
reinterpret_cast<uintptr_t>(address), size) == ZX_OK; reinterpret_cast<uintptr_t>(address), size) == ZX_OK;
} }
// static
bool OS::Release(void* address, size_t size) {
DCHECK_EQ(0, reinterpret_cast<uintptr_t>(address) % CommitPageSize());
DCHECK_EQ(0, size % CommitPageSize());
return zx_vmar_unmap(zx_vmar_root_self(),
reinterpret_cast<uintptr_t>(address), size) == ZX_OK;
}
// static // static
bool OS::SetPermissions(void* address, size_t size, MemoryPermission access) { bool OS::SetPermissions(void* address, size_t size, MemoryPermission access) {
DCHECK_EQ(0, reinterpret_cast<uintptr_t>(address) % CommitPageSize()); DCHECK_EQ(0, reinterpret_cast<uintptr_t>(address) % CommitPageSize());
...@@ -109,12 +117,6 @@ bool OS::SetPermissions(void* address, size_t size, MemoryPermission access) { ...@@ -109,12 +117,6 @@ bool OS::SetPermissions(void* address, size_t size, MemoryPermission access) {
prot) == ZX_OK; prot) == ZX_OK;
} }
// static
bool OS::ReleasePartialRegion(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::HasLazyCommits() { bool OS::HasLazyCommits() {
// TODO(scottmg): Port, https://crbug.com/731217. // TODO(scottmg): Port, https://crbug.com/731217.
......
...@@ -276,16 +276,18 @@ bool OS::Free(void* address, const size_t size) { ...@@ -276,16 +276,18 @@ bool OS::Free(void* address, const size_t size) {
} }
// static // static
bool OS::SetPermissions(void* address, size_t size, MemoryPermission access) { bool OS::Release(void* address, size_t size) {
DCHECK_EQ(0, reinterpret_cast<uintptr_t>(address) % CommitPageSize()); DCHECK_EQ(0, reinterpret_cast<uintptr_t>(address) % CommitPageSize());
DCHECK_EQ(0, size % CommitPageSize()); DCHECK_EQ(0, size % CommitPageSize());
int prot = GetProtectionFromMemoryPermission(access); return munmap(address, size) == 0;
return mprotect(address, size, prot) == 0;
} }
// static // static
bool OS::ReleasePartialRegion(void* address, size_t size) { bool OS::SetPermissions(void* address, size_t size, MemoryPermission access) {
return munmap(address, size) == 0; DCHECK_EQ(0, reinterpret_cast<uintptr_t>(address) % CommitPageSize());
DCHECK_EQ(0, size % CommitPageSize());
int prot = GetProtectionFromMemoryPermission(access);
return mprotect(address, size, prot) == 0;
} }
// static // static
......
...@@ -823,6 +823,13 @@ bool OS::Free(void* address, const size_t size) { ...@@ -823,6 +823,13 @@ bool OS::Free(void* address, const size_t size) {
return VirtualFree(address, 0, MEM_RELEASE) != 0; return VirtualFree(address, 0, MEM_RELEASE) != 0;
} }
// static
bool OS::Release(void* address, size_t size) {
DCHECK_EQ(0, reinterpret_cast<uintptr_t>(address) % CommitPageSize());
DCHECK_EQ(0, size % CommitPageSize());
return VirtualFree(address, size, MEM_DECOMMIT) != 0;
}
// static // static
bool OS::SetPermissions(void* address, size_t size, MemoryPermission access) { bool OS::SetPermissions(void* address, size_t size, MemoryPermission access) {
DCHECK_EQ(0, reinterpret_cast<uintptr_t>(address) % CommitPageSize()); DCHECK_EQ(0, reinterpret_cast<uintptr_t>(address) % CommitPageSize());
...@@ -834,11 +841,6 @@ bool OS::SetPermissions(void* address, size_t size, MemoryPermission access) { ...@@ -834,11 +841,6 @@ bool OS::SetPermissions(void* address, size_t size, MemoryPermission access) {
return VirtualAlloc(address, size, MEM_COMMIT, protect) != nullptr; return VirtualAlloc(address, size, MEM_COMMIT, protect) != nullptr;
} }
// static
bool OS::ReleasePartialRegion(void* address, size_t size) {
return VirtualFree(address, size, MEM_DECOMMIT) != 0;
}
// static // static
bool OS::HasLazyCommits() { bool OS::HasLazyCommits() {
// TODO(alph): implement for the platform. // TODO(alph): implement for the platform.
......
...@@ -187,15 +187,17 @@ class V8_BASE_EXPORT OS { ...@@ -187,15 +187,17 @@ class V8_BASE_EXPORT OS {
// multiples of AllocatePageSize(). Returns true on success, otherwise false. // multiples of AllocatePageSize(). Returns true on success, otherwise false.
V8_WARN_UNUSED_RESULT static bool Free(void* address, const size_t size); V8_WARN_UNUSED_RESULT static bool Free(void* address, const size_t size);
// Releases memory that is no longer needed. The range specified by address
// and size must be part of an allocated memory region, and must be multiples
// of CommitPageSize(). Released memory is left in an undefined state, so it
// should not be accessed. Returns true on success, otherwise false.
V8_WARN_UNUSED_RESULT static bool Release(void* address, size_t size);
// Sets permissions according to the access argument. address and size must be // Sets permissions according to the access argument. address and size must be
// multiples of CommitPageSize(). Returns true on success, otherwise false. // multiples of CommitPageSize(). Returns true on success, otherwise false.
V8_WARN_UNUSED_RESULT static bool SetPermissions(void* address, size_t size, V8_WARN_UNUSED_RESULT static bool SetPermissions(void* address, size_t size,
MemoryPermission access); MemoryPermission access);
// Release part of a reserved address range.
V8_WARN_UNUSED_RESULT static bool ReleasePartialRegion(void* address,
size_t size);
static bool HasLazyCommits(); static bool HasLazyCommits();
// Sleep for a specified time interval. // Sleep for a specified time interval.
......
...@@ -305,7 +305,7 @@ void MemoryAllocator::TearDown() { ...@@ -305,7 +305,7 @@ void MemoryAllocator::TearDown() {
capacity_ = 0; capacity_ = 0;
if (last_chunk_.IsReserved()) { if (last_chunk_.IsReserved()) {
last_chunk_.Release(); last_chunk_.Free();
} }
delete code_range_; delete code_range_;
...@@ -434,7 +434,7 @@ void MemoryAllocator::FreeMemory(VirtualMemory* reservation, ...@@ -434,7 +434,7 @@ void MemoryAllocator::FreeMemory(VirtualMemory* reservation,
DCHECK(executable == NOT_EXECUTABLE || !code_range()->valid() || DCHECK(executable == NOT_EXECUTABLE || !code_range()->valid() ||
reservation->size() <= Page::kPageSize); reservation->size() <= Page::kPageSize);
reservation->Release(); reservation->Free();
} }
...@@ -488,9 +488,9 @@ Address MemoryAllocator::AllocateAlignedMemory( ...@@ -488,9 +488,9 @@ Address MemoryAllocator::AllocateAlignedMemory(
} }
if (base == nullptr) { if (base == nullptr) {
// Failed to commit the body. Release the mapping and any partially // Failed to commit the body. Free the mapping and any partially committed
// committed regions inside it. // regions inside it.
reservation.Release(); reservation.Free();
size_.Decrement(reserve_size); size_.Decrement(reserve_size);
return nullptr; return nullptr;
} }
...@@ -981,7 +981,7 @@ void MemoryAllocator::PartialFreeMemory(MemoryChunk* chunk, Address start_free, ...@@ -981,7 +981,7 @@ void MemoryAllocator::PartialFreeMemory(MemoryChunk* chunk, Address start_free,
// On e.g. Windows, a reservation may be larger than a page and releasing // On e.g. Windows, a reservation may be larger than a page and releasing
// partially starting at |start_free| will also release the potentially // partially starting at |start_free| will also release the potentially
// unused part behind the current page. // unused part behind the current page.
const size_t released_bytes = reservation->ReleasePartial(start_free); const size_t released_bytes = reservation->Release(start_free);
DCHECK_GE(size_.Value(), released_bytes); DCHECK_GE(size_.Value(), released_bytes);
size_.Decrement(released_bytes); size_.Decrement(released_bytes);
isolate_->counters()->memory_allocated()->Decrement( isolate_->counters()->memory_allocated()->Decrement(
......
...@@ -1032,7 +1032,7 @@ class CodeRange { ...@@ -1032,7 +1032,7 @@ class CodeRange {
public: public:
explicit CodeRange(Isolate* isolate); explicit CodeRange(Isolate* isolate);
~CodeRange() { ~CodeRange() {
if (virtual_memory_.IsReserved()) virtual_memory_.Release(); if (virtual_memory_.IsReserved()) virtual_memory_.Free();
} }
// Reserves a range of virtual memory, but does not commit any of it. // Reserves a range of virtual memory, but does not commit any of it.
......
...@@ -68,7 +68,7 @@ void StoreBuffer::SetUp() { ...@@ -68,7 +68,7 @@ void StoreBuffer::SetUp() {
void StoreBuffer::TearDown() { void StoreBuffer::TearDown() {
if (virtual_memory_.IsReserved()) virtual_memory_.Release(); if (virtual_memory_.IsReserved()) virtual_memory_.Free();
top_ = nullptr; top_ = nullptr;
for (int i = 0; i < kStoreBuffers; i++) { for (int i = 0; i < kStoreBuffers; i++) {
start_[i] = nullptr; start_[i] = nullptr;
......
...@@ -872,7 +872,7 @@ void WasmCodeManager::Free(VirtualMemory* mem) { ...@@ -872,7 +872,7 @@ void WasmCodeManager::Free(VirtualMemory* mem) {
void* start = mem->address(); void* start = mem->address();
void* end = mem->end(); void* end = mem->end();
size_t size = mem->size(); size_t size = mem->size();
mem->Release(); mem->Free();
TRACE_HEAP("VMem Release: %p:%p (%zu)\n", start, end, size); TRACE_HEAP("VMem Release: %p:%p (%zu)\n", start, end, size);
} }
......
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