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") { ...@@ -3043,6 +3043,8 @@ v8_component("v8_libbase") {
"src/base/list.h", "src/base/list.h",
"src/base/logging.cc", "src/base/logging.cc",
"src/base/logging.h", "src/base/logging.h",
"src/base/lsan-page-allocator.cc",
"src/base/lsan-page-allocator.h",
"src/base/macros.h", "src/base/macros.h",
"src/base/once.cc", "src/base/once.cc",
"src/base/once.h", "src/base/once.h",
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "src/base/bits.h" #include "src/base/bits.h"
#include "src/base/lazy-instance.h" #include "src/base/lazy-instance.h"
#include "src/base/logging.h" #include "src/base/logging.h"
#include "src/base/lsan-page-allocator.h"
#include "src/base/page-allocator.h" #include "src/base/page-allocator.h"
#include "src/base/platform/platform.h" #include "src/base/platform/platform.h"
#include "src/utils.h" #include "src/utils.h"
...@@ -17,10 +18,6 @@ ...@@ -17,10 +18,6 @@
#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 {
...@@ -51,6 +48,12 @@ struct InitializePageAllocator { ...@@ -51,6 +48,12 @@ struct InitializePageAllocator {
static v8::base::PageAllocator default_allocator; static v8::base::PageAllocator default_allocator;
page_allocator = &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; *page_allocator_ptr = page_allocator;
} }
}; };
...@@ -160,13 +163,6 @@ void* AllocatePages(v8::PageAllocator* page_allocator, void* address, ...@@ -160,13 +163,6 @@ void* AllocatePages(v8::PageAllocator* page_allocator, void* address,
size_t request_size = size + alignment - page_allocator->AllocatePageSize(); size_t request_size = size + alignment - page_allocator->AllocatePageSize();
if (!OnCriticalMemoryPressure(request_size)) break; 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; return result;
} }
...@@ -174,31 +170,14 @@ bool FreePages(v8::PageAllocator* page_allocator, void* address, ...@@ -174,31 +170,14 @@ bool FreePages(v8::PageAllocator* page_allocator, void* address,
const size_t size) { const size_t size) {
DCHECK_NOT_NULL(page_allocator); DCHECK_NOT_NULL(page_allocator);
DCHECK_EQ(0UL, size & (page_allocator->AllocatePageSize() - 1)); DCHECK_EQ(0UL, size & (page_allocator->AllocatePageSize() - 1));
bool result = page_allocator->FreePages(address, size); return 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;
} }
bool ReleasePages(v8::PageAllocator* page_allocator, void* address, size_t size, bool ReleasePages(v8::PageAllocator* page_allocator, void* address, size_t size,
size_t new_size) { size_t new_size) {
DCHECK_NOT_NULL(page_allocator); DCHECK_NOT_NULL(page_allocator);
DCHECK_LT(new_size, size); DCHECK_LT(new_size, size);
bool result = page_allocator->ReleasePages(address, size, new_size); return 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;
} }
bool SetPermissions(v8::PageAllocator* page_allocator, void* address, 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