[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/783513 Reviewed-by: Michael Lippautz <mlippautz@chromium.org> Commit-Queue: Bill Budge <bbudge@chromium.org> Cr-Commit-Position: refs/heads/master@{#49586}
This commit is contained in:
parent
da0af28545
commit
d59bf4dce1
@ -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,
|
|||||||
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) {
|
|||||||
__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 {
|
|||||||
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) {
|
|||||||
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) {
|
|||||||
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) {
|
|||||||
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) {
|
|||||||
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.
|
||||||
|
@ -275,6 +275,13 @@ bool OS::Free(void* address, const size_t size) {
|
|||||||
return munmap(address, size) == 0;
|
return munmap(address, size) == 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 munmap(address, size) == 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());
|
||||||
@ -283,11 +290,6 @@ bool OS::SetPermissions(void* address, size_t size, MemoryPermission access) {
|
|||||||
return mprotect(address, size, prot) == 0;
|
return mprotect(address, size, prot) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
|
||||||
bool OS::ReleasePartialRegion(void* address, size_t size) {
|
|
||||||
return munmap(address, size) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
bool OS::HasLazyCommits() {
|
bool OS::HasLazyCommits() {
|
||||||
#if V8_OS_AIX || V8_OS_LINUX || V8_OS_MACOSX
|
#if V8_OS_AIX || V8_OS_LINUX || V8_OS_MACOSX
|
||||||
|
@ -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) {
|
|||||||
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 {
|
|||||||
// 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() {
|
|||||||
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,
|
|||||||
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(
|
|||||||
}
|
}
|
||||||
|
|
||||||
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,
|
|||||||
// 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 {
|
|||||||
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() {
|
|||||||
|
|
||||||
|
|
||||||
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) {
|
|||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user