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 @@
#include <malloc.h> // NOLINT
#endif
#if defined(LEAK_SANITIZER)
#include <sanitizer/lsan_interface.h>
#endif
namespace v8 {
namespace internal {
......@@ -105,11 +109,18 @@ void AlignedFree(void *ptr) {
VirtualMemory::VirtualMemory() : address_(nullptr), size_(0) {}
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)
: address_(nullptr), size_(0) {
address_ = base::OS::ReserveAlignedRegion(size, alignment, hint, &size_);
#if defined(LEAK_SANITIZER)
__lsan_register_root_region(address_, size_);
#endif
}
VirtualMemory::~VirtualMemory() {
......@@ -145,18 +156,21 @@ size_t VirtualMemory::ReleasePartial(void* free_start) {
DCHECK(IsReserved());
// Notice: Order is important here. The VirtualMemory object might live
// inside the allocated region.
const size_t size = size_ - (reinterpret_cast<size_t>(free_start) -
reinterpret_cast<size_t>(address_));
CHECK(InVM(free_start, size));
const size_t free_size = size_ - (reinterpret_cast<size_t>(free_start) -
reinterpret_cast<size_t>(address_));
CHECK(InVM(free_start, free_size));
DCHECK_LT(address_, free_start);
DCHECK_LT(free_start, reinterpret_cast<void*>(
reinterpret_cast<size_t>(address_) + size_));
const bool result =
base::OS::ReleasePartialRegion(address_, size_, free_start, size);
#if defined(LEAK_SANITIZER)
__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);
DCHECK(result);
size_ -= size;
return size;
size_ -= free_size;
return free_size;
}
void VirtualMemory::Release() {
......
......@@ -8,6 +8,9 @@
#ifdef V8_USE_ADDRESS_SANITIZER
#include <sanitizer/asan_interface.h>
#endif // V8_USE_ADDRESS_SANITIZER
#if defined(LEAK_SANITIZER)
#include <sanitizer/lsan_interface.h>
#endif // defined(LEAK_SANITIZER)
#include <cmath> // For isnan.
#include <limits>
#include <vector>
......@@ -486,7 +489,11 @@ class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
virtual void Free(void* data, size_t) { free(data); }
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,
......
......@@ -148,13 +148,12 @@ bool OS::UncommitRegion(void* address, size_t size) {
}
// static
bool OS::ReleasePartialRegion(void* address, size_t size, void* free_start,
size_t free_size) {
return munmap(free_start, free_size) == 0;
bool OS::ReleaseRegion(void* address, size_t size) {
return munmap(address, size) == 0;
}
// static
bool OS::ReleaseRegion(void* address, size_t size) {
bool OS::ReleasePartialRegion(void* address, size_t size) {
return munmap(address, size) == 0;
}
......
......@@ -144,14 +144,13 @@ bool OS::UncommitRegion(void* address, size_t size) {
}
// static
bool OS::ReleasePartialRegion(void* address, size_t size, void* free_start,
size_t free_size) {
return VirtualFree(free_start, free_size, MEM_DECOMMIT) != 0;
bool OS::ReleaseRegion(void* address, size_t size) {
return VirtualFree(address, 0, MEM_RELEASE) != 0;
}
// static
bool OS::ReleaseRegion(void* address, size_t size) {
return VirtualFree(address, 0, MEM_RELEASE) != 0;
bool OS::ReleasePartialRegion(void* address, size_t size) {
return VirtualFree(address, size, MEM_DECOMMIT) != 0;
}
// static
......
......@@ -123,13 +123,12 @@ bool OS::UncommitRegion(void* address, size_t size) {
}
// static
bool OS::ReleasePartialRegion(void* address, size_t size, void* free_start,
size_t free_size) {
return munmap(free_start, free_size) == 0;
bool OS::ReleaseRegion(void* address, size_t size) {
return munmap(address, size) == 0;
}
// static
bool OS::ReleaseRegion(void* address, size_t size) {
bool OS::ReleasePartialRegion(void* address, size_t size) {
return munmap(address, size) == 0;
}
......
......@@ -116,15 +116,13 @@ bool OS::UncommitRegion(void* address, size_t size) {
}
// static
bool OS::ReleasePartialRegion(void* address, size_t size, void* free_start,
size_t free_size) {
bool OS::ReleaseRegion(void* address, size_t size) {
return zx_vmar_unmap(zx_vmar_root_self(),
reinterpret_cast<uintptr_t>(free_start),
free_size) == ZX_OK;
reinterpret_cast<uintptr_t>(address), size) == ZX_OK;
}
// 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(),
reinterpret_cast<uintptr_t>(address), size) == ZX_OK;
}
......
......@@ -35,10 +35,6 @@
#include <asm/sigcontext.h> // NOLINT
#endif
#if defined(LEAK_SANITIZER)
#include <sanitizer/lsan_interface.h>
#endif
#include <cmath>
#undef MAP_TYPE
......@@ -107,7 +103,7 @@ void* OS::Allocate(const size_t requested, size_t* allocated,
int prot = GetProtectionFromMemoryPermission(access);
void* mbase = mmap(hint, msize, prot, MAP_PRIVATE | MAP_ANONYMOUS, kMmapFd,
kMmapFdOffset);
if (mbase == MAP_FAILED) return NULL;
if (mbase == MAP_FAILED) return nullptr;
*allocated = msize;
return mbase;
}
......@@ -118,11 +114,7 @@ void* OS::ReserveRegion(size_t size, void* hint) {
mmap(hint, size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE,
kMmapFd, kMmapFdOffset);
if (result == MAP_FAILED) return NULL;
#if defined(LEAK_SANITIZER)
__lsan_register_root_region(result, size);
#endif
if (result == MAP_FAILED) return nullptr;
return result;
}
......@@ -133,15 +125,13 @@ void* OS::ReserveAlignedRegion(size_t size, size_t alignment, void* hint,
hint = AlignedAddress(hint, alignment);
size_t request_size =
RoundUp(size + alignment, static_cast<intptr_t>(OS::AllocateAlignment()));
void* reservation =
mmap(hint, request_size, PROT_NONE,
MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, kMmapFd, kMmapFdOffset);
if (reservation == MAP_FAILED) {
void* result = ReserveRegion(request_size, hint);
if (result == nullptr) {
*allocated = 0;
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);
DCHECK_LE(base, aligned_base);
......@@ -163,10 +153,6 @@ void* OS::ReserveAlignedRegion(size_t size, size_t alignment, void* hint,
DCHECK(aligned_size == request_size);
#if defined(LEAK_SANITIZER)
__lsan_register_root_region(static_cast<void*>(aligned_base), aligned_size);
#endif
*allocated = aligned_size;
return static_cast<void*>(aligned_base);
}
......@@ -191,20 +177,12 @@ bool OS::UncommitRegion(void* address, size_t size) {
}
// static
bool OS::ReleasePartialRegion(void* address, size_t size, void* free_start,
size_t free_size) {
#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;
bool OS::ReleaseRegion(void* address, size_t size) {
return munmap(address, size) == 0;
}
// static
bool OS::ReleaseRegion(void* address, size_t size) {
#if defined(LEAK_SANITIZER)
__lsan_unregister_root_region(address, size);
#endif
bool OS::ReleasePartialRegion(void* address, size_t size) {
return munmap(address, size) == 0;
}
......
......@@ -138,13 +138,12 @@ bool OS::UncommitRegion(void* address, size_t size) {
}
// static
bool OS::ReleasePartialRegion(void* address, size_t size, void* free_start,
size_t free_size) {
return munmap(free_start, free_size) == 0;
bool OS::ReleaseRegion(void* address, size_t size) {
return munmap(address, size) == 0;
}
// static
bool OS::ReleaseRegion(void* address, size_t size) {
bool OS::ReleasePartialRegion(void* address, size_t size) {
return munmap(address, size) == 0;
}
......
......@@ -122,13 +122,12 @@ bool OS::UncommitRegion(void* address, size_t size) {
}
// static
bool OS::ReleasePartialRegion(void* address, size_t size, void* free_start,
size_t free_size) {
return munmap(free_start, free_size) == 0;
bool OS::ReleaseRegion(void* address, size_t size) {
return munmap(address, size) == 0;
}
// static
bool OS::ReleaseRegion(void* address, size_t size) {
bool OS::ReleasePartialRegion(void* address, size_t size) {
return munmap(address, size) == 0;
}
......
......@@ -174,13 +174,12 @@ bool OS::UncommitRegion(void* address, size_t size) {
}
// static
bool OS::ReleasePartialRegion(void* address, size_t size, void* free_start,
size_t free_size) {
return munmap(free_start, free_size) == 0;
bool OS::ReleaseRegion(void* address, size_t size) {
return munmap(address, size) == 0;
}
// static
bool OS::ReleaseRegion(void* address, size_t size) {
bool OS::ReleasePartialRegion(void* address, size_t size) {
return munmap(address, size) == 0;
}
......
......@@ -143,13 +143,12 @@ bool OS::UncommitRegion(void* address, size_t size) {
}
// static
bool OS::ReleasePartialRegion(void* address, size_t size, void* free_start,
size_t free_size) {
return munmap(free_start, free_size) == 0;
bool OS::ReleaseRegion(void* address, size_t size) {
return munmap(address, size) == 0;
}
// static
bool OS::ReleaseRegion(void* address, size_t size) {
bool OS::ReleasePartialRegion(void* address, size_t size) {
return munmap(address, size) == 0;
}
......
......@@ -798,7 +798,6 @@ void OS::Unprotect(void* address, const size_t size) {
USE(result);
}
// static
// static
void* OS::ReserveRegion(size_t size, void* hint) {
return RandomizedVirtualAlloc(size, MEM_RESERVE, PAGE_NOACCESS, hint);
......@@ -852,14 +851,13 @@ bool OS::UncommitRegion(void* address, size_t size) {
}
// static
bool OS::ReleasePartialRegion(void* address, size_t size, void* free_start,
size_t free_size) {
return VirtualFree(free_start, free_size, MEM_DECOMMIT) != 0;
bool OS::ReleaseRegion(void* address, size_t size) {
return VirtualFree(address, 0, MEM_RELEASE) != 0;
}
// static
bool OS::ReleaseRegion(void* address, size_t size) {
return VirtualFree(address, 0, MEM_RELEASE) != 0;
bool OS::ReleasePartialRegion(void* address, size_t size) {
return VirtualFree(address, size, MEM_DECOMMIT) != 0;
}
// static
......
......@@ -200,11 +200,11 @@ class V8_BASE_EXPORT OS {
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);
// Release part of a reserved address range.
static bool ReleasePartialRegion(void* address, size_t size);
static bool HasLazyCommits();
// Sleep for a specified time interval.
......
......@@ -41,6 +41,10 @@
#include "src/utils.h"
#include "src/v8.h"
#if defined(LEAK_SANITIZER)
#include <sanitizer/lsan_interface.h>
#endif
#if !defined(_WIN32) && !defined(_WIN64)
#include <unistd.h> // NOLINT
#else
......@@ -161,6 +165,9 @@ class ShellArrayBufferAllocator : public ArrayBufferAllocatorBase {
base::OS::ReleaseRegion(data, length);
return nullptr;
}
#if defined(LEAK_SANITIZER)
__lsan_register_root_region(data, length);
#endif
MSAN_MEMORY_IS_INITIALIZED(data, length);
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