Commit 6211697a authored by Igor Sheludko's avatar Igor Sheludko Committed by Commit Bot

[cleanup] Introduce LsanPageAllocator decorator

... in order to avoid page allocator filtering when notifying leak sanitizer.

This is a reland of 0606bf91

Bug: v8:8015
Change-Id: I314eee7699ce2c8abeeafce4fcf185810ac252a9
Reviewed-on: https://chromium-review.googlesource.com/1226918
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Reviewed-by: 's avatarUlan Degenbaev <ulan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#55952}
parent aaab2907
......@@ -3043,6 +3043,8 @@ v8_component("v8_libbase") {
"src/base/list.h",
"src/base/logging.cc",
"src/base/logging.h",
"src/base/lsan-page-allocator.cc",
"src/base/lsan-page-allocator.h",
"src/base/macros.h",
"src/base/once.cc",
"src/base/once.h",
......
......@@ -8,6 +8,7 @@
#include "src/base/bits.h"
#include "src/base/lazy-instance.h"
#include "src/base/logging.h"
#include "src/base/lsan-page-allocator.h"
#include "src/base/page-allocator.h"
#include "src/base/platform/platform.h"
#include "src/utils.h"
......@@ -17,10 +18,6 @@
#include <malloc.h> // NOLINT
#endif
#if defined(LEAK_SANITIZER)
#include <sanitizer/lsan_interface.h>
#endif
namespace v8 {
namespace internal {
......@@ -51,6 +48,12 @@ struct InitializePageAllocator {
static v8::base::PageAllocator default_allocator;
page_allocator = &default_allocator;
}
#if defined(LEAK_SANITIZER)
{
static v8::base::LsanPageAllocator lsan_allocator(page_allocator);
page_allocator = &lsan_allocator;
}
#endif
*page_allocator_ptr = page_allocator;
}
};
......@@ -160,13 +163,6 @@ void* AllocatePages(v8::PageAllocator* page_allocator, void* address,
size_t request_size = size + alignment - page_allocator->AllocatePageSize();
if (!OnCriticalMemoryPressure(request_size)) break;
}
#if defined(LEAK_SANITIZER)
if (result != nullptr && page_allocator == GetPlatformPageAllocator()) {
// Notify LSAN only about the plaform memory allocations or we will
// "allocate"/"deallocate" certain parts of memory twice.
__lsan_register_root_region(result, size);
}
#endif
return result;
}
......@@ -174,31 +170,14 @@ bool FreePages(v8::PageAllocator* page_allocator, void* address,
const size_t size) {
DCHECK_NOT_NULL(page_allocator);
DCHECK_EQ(0UL, size & (page_allocator->AllocatePageSize() - 1));
bool result = page_allocator->FreePages(address, size);
#if defined(LEAK_SANITIZER)
if (result && page_allocator == GetPlatformPageAllocator()) {
// Notify LSAN only about the plaform memory allocations or we will
// "allocate"/"deallocate" certain parts of memory twice.
__lsan_unregister_root_region(address, size);
}
#endif
return result;
return page_allocator->FreePages(address, size);
}
bool ReleasePages(v8::PageAllocator* page_allocator, void* address, size_t size,
size_t new_size) {
DCHECK_NOT_NULL(page_allocator);
DCHECK_LT(new_size, size);
bool result = page_allocator->ReleasePages(address, size, new_size);
#if defined(LEAK_SANITIZER)
if (result && page_allocator == GetPlatformPageAllocator()) {
// Notify LSAN only about the plaform memory allocations or we will
// "allocate"/"deallocate" certain parts of memory twice.
__lsan_unregister_root_region(address, size);
__lsan_register_root_region(address, new_size);
}
#endif
return result;
return page_allocator->ReleasePages(address, size, new_size);
}
bool SetPermissions(v8::PageAllocator* page_allocator, void* address,
......
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/base/lsan-page-allocator.h"
#include "src/base/logging.h"
#if defined(LEAK_SANITIZER)
#include <sanitizer/lsan_interface.h>
#endif
namespace v8 {
namespace base {
LsanPageAllocator::LsanPageAllocator(v8::PageAllocator* page_allocator)
: page_allocator_(page_allocator),
allocate_page_size_(page_allocator_->AllocatePageSize()),
commit_page_size_(page_allocator_->CommitPageSize()) {
DCHECK_NOT_NULL(page_allocator);
}
void* LsanPageAllocator::AllocatePages(void* address, size_t size,
size_t alignment,
PageAllocator::Permission access) {
void* result =
page_allocator_->AllocatePages(address, size, alignment, access);
#if defined(LEAK_SANITIZER)
if (result != nullptr) {
__lsan_register_root_region(result, size);
}
#endif
return result;
}
bool LsanPageAllocator::FreePages(void* address, size_t size) {
bool result = page_allocator_->FreePages(address, size);
#if defined(LEAK_SANITIZER)
if (result) {
__lsan_unregister_root_region(address, size);
}
#endif
return result;
}
bool LsanPageAllocator::ReleasePages(void* address, size_t size,
size_t new_size) {
bool result = page_allocator_->ReleasePages(address, size, new_size);
#if defined(LEAK_SANITIZER)
if (result) {
__lsan_unregister_root_region(address, size);
__lsan_register_root_region(address, new_size);
}
#endif
return result;
}
} // namespace base
} // namespace v8
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_BASE_LSAN_PAGE_ALLOCATOR_H_
#define V8_BASE_LSAN_PAGE_ALLOCATOR_H_
#include "include/v8-platform.h"
#include "src/base/base-export.h"
#include "src/base/compiler-specific.h"
namespace v8 {
namespace base {
// This is a v8::PageAllocator implementation that decorates provided page
// allocator object with leak sanitizer notifications when LEAK_SANITIZER
// is defined.
class V8_BASE_EXPORT LsanPageAllocator
: public NON_EXPORTED_BASE(::v8::PageAllocator) {
public:
LsanPageAllocator(v8::PageAllocator* page_allocator);
virtual ~LsanPageAllocator() = default;
size_t AllocatePageSize() override { return allocate_page_size_; }
size_t CommitPageSize() override { return commit_page_size_; }
void SetRandomMmapSeed(int64_t seed) override {
return page_allocator_->SetRandomMmapSeed(seed);
}
void* GetRandomMmapAddr() override {
return page_allocator_->GetRandomMmapAddr();
}
void* AllocatePages(void* address, size_t size, size_t alignment,
PageAllocator::Permission access) override;
bool FreePages(void* address, size_t size) override;
bool ReleasePages(void* address, size_t size, size_t new_size) override;
bool SetPermissions(void* address, size_t size,
PageAllocator::Permission access) override {
return page_allocator_->SetPermissions(address, size, access);
}
private:
v8::PageAllocator* const page_allocator_;
const size_t allocate_page_size_;
const size_t commit_page_size_;
};
} // namespace base
} // namespace v8
#endif // V8_BASE_LSAN_PAGE_ALLOCATOR_H_
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