Commit 10d07f33 authored by Bill Budge's avatar Bill Budge Committed by Commit Bot

[Memory] Make OS Memory functions more generic.

- Moves leak sanitizer code to callers of OS:: Memory functions.
- Changes signature of OS::ReleasePartialRegion to be more generic,
  removing the parameters that only make sense as part of VirtualMemory.

Bug: chromium:756050
Cq-Include-Trybots: master.tryserver.chromium.linux:linux_chromium_rel_ng
Change-Id: I2f1401c9b0856b2eaf36b80b5f141e935ef63e1c
Reviewed-on: https://chromium-review.googlesource.com/685741Reviewed-by: 's avatarUlan Degenbaev <ulan@chromium.org>
Commit-Queue: Bill Budge <bbudge@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48250}
parent a8eed5e5
...@@ -18,6 +18,10 @@ ...@@ -18,6 +18,10 @@
#include <malloc.h> // NOLINT #include <malloc.h> // NOLINT
#endif #endif
#if defined(LEAK_SANITIZER)
#include <sanitizer/lsan_interface.h>
#endif
namespace v8 { namespace v8 {
namespace internal { namespace internal {
...@@ -105,11 +109,18 @@ void AlignedFree(void *ptr) { ...@@ -105,11 +109,18 @@ void AlignedFree(void *ptr) {
VirtualMemory::VirtualMemory() : address_(nullptr), size_(0) {} VirtualMemory::VirtualMemory() : address_(nullptr), size_(0) {}
VirtualMemory::VirtualMemory(size_t size, void* hint) VirtualMemory::VirtualMemory(size_t size, void* hint)
: address_(base::OS::ReserveRegion(size, hint)), size_(size) {} : address_(base::OS::ReserveRegion(size, hint)), size_(size) {
#if defined(LEAK_SANITIZER)
__lsan_register_root_region(address_, size_);
#endif
}
VirtualMemory::VirtualMemory(size_t size, size_t alignment, void* hint) VirtualMemory::VirtualMemory(size_t size, size_t alignment, void* hint)
: address_(nullptr), size_(0) { : address_(nullptr), size_(0) {
address_ = base::OS::ReserveAlignedRegion(size, alignment, hint, &size_); address_ = base::OS::ReserveAlignedRegion(size, alignment, hint, &size_);
#if defined(LEAK_SANITIZER)
__lsan_register_root_region(address_, size_);
#endif
} }
VirtualMemory::~VirtualMemory() { VirtualMemory::~VirtualMemory() {
...@@ -145,18 +156,21 @@ size_t VirtualMemory::ReleasePartial(void* free_start) { ...@@ -145,18 +156,21 @@ size_t VirtualMemory::ReleasePartial(void* free_start) {
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.
const size_t size = size_ - (reinterpret_cast<size_t>(free_start) - const size_t free_size = size_ - (reinterpret_cast<size_t>(free_start) -
reinterpret_cast<size_t>(address_)); reinterpret_cast<size_t>(address_));
CHECK(InVM(free_start, size)); CHECK(InVM(free_start, free_size));
DCHECK_LT(address_, free_start); DCHECK_LT(address_, free_start);
DCHECK_LT(free_start, reinterpret_cast<void*>( DCHECK_LT(free_start, reinterpret_cast<void*>(
reinterpret_cast<size_t>(address_) + size_)); reinterpret_cast<size_t>(address_) + size_));
const bool result = #if defined(LEAK_SANITIZER)
base::OS::ReleasePartialRegion(address_, size_, free_start, size); __lsan_unregister_root_region(address_, size_);
__lsan_register_root_region(address_, size_ - free_size);
#endif
const bool result = base::OS::ReleasePartialRegion(free_start, free_size);
USE(result); USE(result);
DCHECK(result); DCHECK(result);
size_ -= size; size_ -= free_size;
return size; return free_size;
} }
void VirtualMemory::Release() { void VirtualMemory::Release() {
......
...@@ -8,6 +8,9 @@ ...@@ -8,6 +8,9 @@
#ifdef V8_USE_ADDRESS_SANITIZER #ifdef V8_USE_ADDRESS_SANITIZER
#include <sanitizer/asan_interface.h> #include <sanitizer/asan_interface.h>
#endif // V8_USE_ADDRESS_SANITIZER #endif // V8_USE_ADDRESS_SANITIZER
#if defined(LEAK_SANITIZER)
#include <sanitizer/lsan_interface.h>
#endif // defined(LEAK_SANITIZER)
#include <cmath> // For isnan. #include <cmath> // For isnan.
#include <limits> #include <limits>
#include <vector> #include <vector>
...@@ -486,7 +489,11 @@ class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator { ...@@ -486,7 +489,11 @@ class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
virtual void Free(void* data, size_t) { free(data); } virtual void Free(void* data, size_t) { free(data); }
virtual void* Reserve(size_t length) { virtual void* Reserve(size_t length) {
return base::OS::ReserveRegion(length, i::GetRandomMmapAddr()); void* address = base::OS::ReserveRegion(length, i::GetRandomMmapAddr());
#if defined(LEAK_SANITIZER)
__lsan_register_root_region(address, length);
#endif
return address;
} }
virtual void Free(void* data, size_t length, virtual void Free(void* data, size_t length,
......
...@@ -148,13 +148,12 @@ bool OS::UncommitRegion(void* address, size_t size) { ...@@ -148,13 +148,12 @@ bool OS::UncommitRegion(void* address, size_t size) {
} }
// static // static
bool OS::ReleasePartialRegion(void* address, size_t size, void* free_start, bool OS::ReleaseRegion(void* address, size_t size) {
size_t free_size) { return munmap(address, size) == 0;
return munmap(free_start, free_size) == 0;
} }
// static // static
bool OS::ReleaseRegion(void* address, size_t size) { bool OS::ReleasePartialRegion(void* address, size_t size) {
return munmap(address, size) == 0; return munmap(address, size) == 0;
} }
......
...@@ -144,14 +144,13 @@ bool OS::UncommitRegion(void* address, size_t size) { ...@@ -144,14 +144,13 @@ bool OS::UncommitRegion(void* address, size_t size) {
} }
// static // static
bool OS::ReleasePartialRegion(void* address, size_t size, void* free_start, bool OS::ReleaseRegion(void* address, size_t size) {
size_t free_size) { return VirtualFree(address, 0, MEM_RELEASE) != 0;
return VirtualFree(free_start, free_size, MEM_DECOMMIT) != 0;
} }
// static // static
bool OS::ReleaseRegion(void* address, size_t size) { bool OS::ReleasePartialRegion(void* address, size_t size) {
return VirtualFree(address, 0, MEM_RELEASE) != 0; return VirtualFree(address, size, MEM_DECOMMIT) != 0;
} }
// static // static
......
...@@ -123,13 +123,12 @@ bool OS::UncommitRegion(void* address, size_t size) { ...@@ -123,13 +123,12 @@ bool OS::UncommitRegion(void* address, size_t size) {
} }
// static // static
bool OS::ReleasePartialRegion(void* address, size_t size, void* free_start, bool OS::ReleaseRegion(void* address, size_t size) {
size_t free_size) { return munmap(address, size) == 0;
return munmap(free_start, free_size) == 0;
} }
// static // static
bool OS::ReleaseRegion(void* address, size_t size) { bool OS::ReleasePartialRegion(void* address, size_t size) {
return munmap(address, size) == 0; return munmap(address, size) == 0;
} }
......
...@@ -116,15 +116,13 @@ bool OS::UncommitRegion(void* address, size_t size) { ...@@ -116,15 +116,13 @@ bool OS::UncommitRegion(void* address, size_t size) {
} }
// static // static
bool OS::ReleasePartialRegion(void* address, size_t size, void* free_start, bool OS::ReleaseRegion(void* address, size_t size) {
size_t free_size) {
return zx_vmar_unmap(zx_vmar_root_self(), return zx_vmar_unmap(zx_vmar_root_self(),
reinterpret_cast<uintptr_t>(free_start), reinterpret_cast<uintptr_t>(address), size) == ZX_OK;
free_size) == ZX_OK;
} }
// static // static
bool OS::ReleaseRegion(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(),
reinterpret_cast<uintptr_t>(address), size) == ZX_OK; reinterpret_cast<uintptr_t>(address), size) == ZX_OK;
} }
......
...@@ -35,10 +35,6 @@ ...@@ -35,10 +35,6 @@
#include <asm/sigcontext.h> // NOLINT #include <asm/sigcontext.h> // NOLINT
#endif #endif
#if defined(LEAK_SANITIZER)
#include <sanitizer/lsan_interface.h>
#endif
#include <cmath> #include <cmath>
#undef MAP_TYPE #undef MAP_TYPE
...@@ -107,7 +103,7 @@ void* OS::Allocate(const size_t requested, size_t* allocated, ...@@ -107,7 +103,7 @@ void* OS::Allocate(const size_t requested, size_t* allocated,
int prot = GetProtectionFromMemoryPermission(access); int prot = GetProtectionFromMemoryPermission(access);
void* mbase = mmap(hint, msize, prot, MAP_PRIVATE | MAP_ANONYMOUS, kMmapFd, void* mbase = mmap(hint, msize, prot, MAP_PRIVATE | MAP_ANONYMOUS, kMmapFd,
kMmapFdOffset); kMmapFdOffset);
if (mbase == MAP_FAILED) return NULL; if (mbase == MAP_FAILED) return nullptr;
*allocated = msize; *allocated = msize;
return mbase; return mbase;
} }
...@@ -118,11 +114,7 @@ void* OS::ReserveRegion(size_t size, void* hint) { ...@@ -118,11 +114,7 @@ void* OS::ReserveRegion(size_t size, void* hint) {
mmap(hint, size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, mmap(hint, size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE,
kMmapFd, kMmapFdOffset); kMmapFd, kMmapFdOffset);
if (result == MAP_FAILED) return NULL; if (result == MAP_FAILED) return nullptr;
#if defined(LEAK_SANITIZER)
__lsan_register_root_region(result, size);
#endif
return result; return result;
} }
...@@ -133,15 +125,13 @@ void* OS::ReserveAlignedRegion(size_t size, size_t alignment, void* hint, ...@@ -133,15 +125,13 @@ void* OS::ReserveAlignedRegion(size_t size, size_t alignment, void* hint,
hint = AlignedAddress(hint, alignment); hint = AlignedAddress(hint, alignment);
size_t request_size = size_t request_size =
RoundUp(size + alignment, static_cast<intptr_t>(OS::AllocateAlignment())); RoundUp(size + alignment, static_cast<intptr_t>(OS::AllocateAlignment()));
void* reservation = void* result = ReserveRegion(request_size, hint);
mmap(hint, request_size, PROT_NONE, if (result == nullptr) {
MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, kMmapFd, kMmapFdOffset);
if (reservation == MAP_FAILED) {
*allocated = 0; *allocated = 0;
return nullptr; return nullptr;
} }
uint8_t* base = static_cast<uint8_t*>(reservation); uint8_t* base = static_cast<uint8_t*>(result);
uint8_t* aligned_base = RoundUp(base, alignment); uint8_t* aligned_base = RoundUp(base, alignment);
DCHECK_LE(base, aligned_base); DCHECK_LE(base, aligned_base);
...@@ -163,10 +153,6 @@ void* OS::ReserveAlignedRegion(size_t size, size_t alignment, void* hint, ...@@ -163,10 +153,6 @@ void* OS::ReserveAlignedRegion(size_t size, size_t alignment, void* hint,
DCHECK(aligned_size == request_size); DCHECK(aligned_size == request_size);
#if defined(LEAK_SANITIZER)
__lsan_register_root_region(static_cast<void*>(aligned_base), aligned_size);
#endif
*allocated = aligned_size; *allocated = aligned_size;
return static_cast<void*>(aligned_base); return static_cast<void*>(aligned_base);
} }
...@@ -191,20 +177,12 @@ bool OS::UncommitRegion(void* address, size_t size) { ...@@ -191,20 +177,12 @@ bool OS::UncommitRegion(void* address, size_t size) {
} }
// static // static
bool OS::ReleasePartialRegion(void* address, size_t size, void* free_start, bool OS::ReleaseRegion(void* address, size_t size) {
size_t free_size) { return munmap(address, size) == 0;
#if defined(LEAK_SANITIZER)
__lsan_unregister_root_region(address, size);
__lsan_register_root_region(address, size - free_size);
#endif
return munmap(free_start, free_size) == 0;
} }
// static // static
bool OS::ReleaseRegion(void* address, size_t size) { bool OS::ReleasePartialRegion(void* address, size_t size) {
#if defined(LEAK_SANITIZER)
__lsan_unregister_root_region(address, size);
#endif
return munmap(address, size) == 0; return munmap(address, size) == 0;
} }
......
...@@ -138,13 +138,12 @@ bool OS::UncommitRegion(void* address, size_t size) { ...@@ -138,13 +138,12 @@ bool OS::UncommitRegion(void* address, size_t size) {
} }
// static // static
bool OS::ReleasePartialRegion(void* address, size_t size, void* free_start, bool OS::ReleaseRegion(void* address, size_t size) {
size_t free_size) { return munmap(address, size) == 0;
return munmap(free_start, free_size) == 0;
} }
// static // static
bool OS::ReleaseRegion(void* address, size_t size) { bool OS::ReleasePartialRegion(void* address, size_t size) {
return munmap(address, size) == 0; return munmap(address, size) == 0;
} }
......
...@@ -122,13 +122,12 @@ bool OS::UncommitRegion(void* address, size_t size) { ...@@ -122,13 +122,12 @@ bool OS::UncommitRegion(void* address, size_t size) {
} }
// static // static
bool OS::ReleasePartialRegion(void* address, size_t size, void* free_start, bool OS::ReleaseRegion(void* address, size_t size) {
size_t free_size) { return munmap(address, size) == 0;
return munmap(free_start, free_size) == 0;
} }
// static // static
bool OS::ReleaseRegion(void* address, size_t size) { bool OS::ReleasePartialRegion(void* address, size_t size) {
return munmap(address, size) == 0; return munmap(address, size) == 0;
} }
......
...@@ -174,13 +174,12 @@ bool OS::UncommitRegion(void* address, size_t size) { ...@@ -174,13 +174,12 @@ bool OS::UncommitRegion(void* address, size_t size) {
} }
// static // static
bool OS::ReleasePartialRegion(void* address, size_t size, void* free_start, bool OS::ReleaseRegion(void* address, size_t size) {
size_t free_size) { return munmap(address, size) == 0;
return munmap(free_start, free_size) == 0;
} }
// static // static
bool OS::ReleaseRegion(void* address, size_t size) { bool OS::ReleasePartialRegion(void* address, size_t size) {
return munmap(address, size) == 0; return munmap(address, size) == 0;
} }
......
...@@ -143,13 +143,12 @@ bool OS::UncommitRegion(void* address, size_t size) { ...@@ -143,13 +143,12 @@ bool OS::UncommitRegion(void* address, size_t size) {
} }
// static // static
bool OS::ReleasePartialRegion(void* address, size_t size, void* free_start, bool OS::ReleaseRegion(void* address, size_t size) {
size_t free_size) { return munmap(address, size) == 0;
return munmap(free_start, free_size) == 0;
} }
// static // static
bool OS::ReleaseRegion(void* address, size_t size) { bool OS::ReleasePartialRegion(void* address, size_t size) {
return munmap(address, size) == 0; return munmap(address, size) == 0;
} }
......
...@@ -798,7 +798,6 @@ void OS::Unprotect(void* address, const size_t size) { ...@@ -798,7 +798,6 @@ void OS::Unprotect(void* address, const size_t size) {
USE(result); USE(result);
} }
// static
// static // static
void* OS::ReserveRegion(size_t size, void* hint) { void* OS::ReserveRegion(size_t size, void* hint) {
return RandomizedVirtualAlloc(size, MEM_RESERVE, PAGE_NOACCESS, hint); return RandomizedVirtualAlloc(size, MEM_RESERVE, PAGE_NOACCESS, hint);
...@@ -852,14 +851,13 @@ bool OS::UncommitRegion(void* address, size_t size) { ...@@ -852,14 +851,13 @@ bool OS::UncommitRegion(void* address, size_t size) {
} }
// static // static
bool OS::ReleasePartialRegion(void* address, size_t size, void* free_start, bool OS::ReleaseRegion(void* address, size_t size) {
size_t free_size) { return VirtualFree(address, 0, MEM_RELEASE) != 0;
return VirtualFree(free_start, free_size, MEM_DECOMMIT) != 0;
} }
// static // static
bool OS::ReleaseRegion(void* address, size_t size) { bool OS::ReleasePartialRegion(void* address, size_t size) {
return VirtualFree(address, 0, MEM_RELEASE) != 0; return VirtualFree(address, size, MEM_DECOMMIT) != 0;
} }
// static // static
......
...@@ -200,11 +200,11 @@ class V8_BASE_EXPORT OS { ...@@ -200,11 +200,11 @@ class V8_BASE_EXPORT OS {
static bool UncommitRegion(void* address, size_t size); static bool UncommitRegion(void* address, size_t size);
static bool ReleasePartialRegion(void* base, size_t size, void* free_start,
size_t free_size);
static bool ReleaseRegion(void* address, size_t size); static bool ReleaseRegion(void* address, size_t size);
// Release part of a reserved address range.
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.
......
...@@ -41,6 +41,10 @@ ...@@ -41,6 +41,10 @@
#include "src/utils.h" #include "src/utils.h"
#include "src/v8.h" #include "src/v8.h"
#if defined(LEAK_SANITIZER)
#include <sanitizer/lsan_interface.h>
#endif
#if !defined(_WIN32) && !defined(_WIN64) #if !defined(_WIN32) && !defined(_WIN64)
#include <unistd.h> // NOLINT #include <unistd.h> // NOLINT
#else #else
...@@ -161,6 +165,9 @@ class ShellArrayBufferAllocator : public ArrayBufferAllocatorBase { ...@@ -161,6 +165,9 @@ class ShellArrayBufferAllocator : public ArrayBufferAllocatorBase {
base::OS::ReleaseRegion(data, length); base::OS::ReleaseRegion(data, length);
return nullptr; return nullptr;
} }
#if defined(LEAK_SANITIZER)
__lsan_register_root_region(data, length);
#endif
MSAN_MEMORY_IS_INITIALIZED(data, length); MSAN_MEMORY_IS_INITIALIZED(data, length);
return data; return data;
} }
......
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