replaced separate singular malloc hooks with faster HookList
Specifically, we can now check in one place if hooks are set at all, instead of two places. Which makes fast path shorter.
This commit is contained in:
parent
ba0441785b
commit
6a6c49e1f5
|
@ -46,51 +46,6 @@
|
||||||
|
|
||||||
namespace base { namespace internal {
|
namespace base { namespace internal {
|
||||||
|
|
||||||
// The following (implementation) code is DEPRECATED.
|
|
||||||
// A simple atomic pointer class that can be initialized by the linker
|
|
||||||
// when you define a namespace-scope variable as:
|
|
||||||
//
|
|
||||||
// AtomicPtr<Foo*> my_global = { &initial_value };
|
|
||||||
//
|
|
||||||
// This isn't suitable for a general atomic<> class because of the
|
|
||||||
// public access to data_.
|
|
||||||
template<typename PtrT>
|
|
||||||
class AtomicPtr {
|
|
||||||
public:
|
|
||||||
COMPILE_ASSERT(sizeof(PtrT) <= sizeof(AtomicWord),
|
|
||||||
PtrT_should_fit_in_AtomicWord);
|
|
||||||
|
|
||||||
PtrT Get() const {
|
|
||||||
// Depending on the system, Acquire_Load(AtomicWord*) may have
|
|
||||||
// been defined to return an AtomicWord, Atomic32, or Atomic64.
|
|
||||||
// We hide that implementation detail here with an explicit cast.
|
|
||||||
// This prevents MSVC 2005, at least, from complaining (it has to
|
|
||||||
// do with __wp64; AtomicWord is __wp64, but Atomic32/64 aren't).
|
|
||||||
return reinterpret_cast<PtrT>(static_cast<AtomicWord>(
|
|
||||||
base::subtle::NoBarrier_Load(&data_)));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sets the contained value to new_val and returns the old value,
|
|
||||||
// atomically, with acquire and release semantics.
|
|
||||||
// This is a full-barrier instruction.
|
|
||||||
PtrT Exchange(PtrT new_val);
|
|
||||||
|
|
||||||
// Not private so that the class is an aggregate and can be
|
|
||||||
// initialized by the linker. Don't access this directly.
|
|
||||||
AtomicWord data_;
|
|
||||||
};
|
|
||||||
|
|
||||||
// These are initialized in malloc_hook.cc
|
|
||||||
extern AtomicPtr<MallocHook::NewHook> new_hook_;
|
|
||||||
extern AtomicPtr<MallocHook::DeleteHook> delete_hook_;
|
|
||||||
extern AtomicPtr<MallocHook::PreMmapHook> premmap_hook_;
|
|
||||||
extern AtomicPtr<MallocHook::MmapHook> mmap_hook_;
|
|
||||||
extern AtomicPtr<MallocHook::MunmapHook> munmap_hook_;
|
|
||||||
extern AtomicPtr<MallocHook::MremapHook> mremap_hook_;
|
|
||||||
extern AtomicPtr<MallocHook::PreSbrkHook> presbrk_hook_;
|
|
||||||
extern AtomicPtr<MallocHook::SbrkHook> sbrk_hook_;
|
|
||||||
// End DEPRECATED code.
|
|
||||||
|
|
||||||
// Capacity of 8 means that HookList is 9 words.
|
// Capacity of 8 means that HookList is 9 words.
|
||||||
static const int kHookListCapacity = 8;
|
static const int kHookListCapacity = 8;
|
||||||
// last entry is reserved for deprecated "singular" hooks. So we have
|
// last entry is reserved for deprecated "singular" hooks. So we have
|
||||||
|
@ -162,37 +117,29 @@ extern HookList<MallocHook::SbrkHook> sbrk_hooks_;
|
||||||
|
|
||||||
// The following method is DEPRECATED
|
// The following method is DEPRECATED
|
||||||
inline MallocHook::NewHook MallocHook::GetNewHook() {
|
inline MallocHook::NewHook MallocHook::GetNewHook() {
|
||||||
return base::internal::new_hook_.Get();
|
return base::internal::new_hooks_.GetSingular();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void MallocHook::InvokeNewHook(const void* p, size_t s) {
|
inline void MallocHook::InvokeNewHook(const void* p, size_t s) {
|
||||||
if (!base::internal::new_hooks_.empty()) {
|
if (!base::internal::new_hooks_.empty()) {
|
||||||
InvokeNewHookSlow(p, s);
|
InvokeNewHookSlow(p, s);
|
||||||
}
|
}
|
||||||
// The following code is DEPRECATED.
|
|
||||||
MallocHook::NewHook hook = MallocHook::GetNewHook();
|
|
||||||
if (hook != NULL) (*hook)(p, s);
|
|
||||||
// End DEPRECATED code.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The following method is DEPRECATED
|
// The following method is DEPRECATED
|
||||||
inline MallocHook::DeleteHook MallocHook::GetDeleteHook() {
|
inline MallocHook::DeleteHook MallocHook::GetDeleteHook() {
|
||||||
return base::internal::delete_hook_.Get();
|
return base::internal::delete_hooks_.GetSingular();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void MallocHook::InvokeDeleteHook(const void* p) {
|
inline void MallocHook::InvokeDeleteHook(const void* p) {
|
||||||
if (!base::internal::delete_hooks_.empty()) {
|
if (!base::internal::delete_hooks_.empty()) {
|
||||||
InvokeDeleteHookSlow(p);
|
InvokeDeleteHookSlow(p);
|
||||||
}
|
}
|
||||||
// The following code is DEPRECATED.
|
|
||||||
MallocHook::DeleteHook hook = MallocHook::GetDeleteHook();
|
|
||||||
if (hook != NULL) (*hook)(p);
|
|
||||||
// End DEPRECATED code.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The following method is DEPRECATED
|
// The following method is DEPRECATED
|
||||||
inline MallocHook::PreMmapHook MallocHook::GetPreMmapHook() {
|
inline MallocHook::PreMmapHook MallocHook::GetPreMmapHook() {
|
||||||
return base::internal::premmap_hook_.Get();
|
return base::internal::premmap_hooks_.GetSingular();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void MallocHook::InvokePreMmapHook(const void* start,
|
inline void MallocHook::InvokePreMmapHook(const void* start,
|
||||||
|
@ -204,17 +151,11 @@ inline void MallocHook::InvokePreMmapHook(const void* start,
|
||||||
if (!base::internal::premmap_hooks_.empty()) {
|
if (!base::internal::premmap_hooks_.empty()) {
|
||||||
InvokePreMmapHookSlow(start, size, protection, flags, fd, offset);
|
InvokePreMmapHookSlow(start, size, protection, flags, fd, offset);
|
||||||
}
|
}
|
||||||
// The following code is DEPRECATED.
|
|
||||||
MallocHook::PreMmapHook hook = MallocHook::GetPreMmapHook();
|
|
||||||
if (hook != NULL) (*hook)(start, size,
|
|
||||||
protection, flags,
|
|
||||||
fd, offset);
|
|
||||||
// End DEPRECATED code.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The following method is DEPRECATED
|
// The following method is DEPRECATED
|
||||||
inline MallocHook::MmapHook MallocHook::GetMmapHook() {
|
inline MallocHook::MmapHook MallocHook::GetMmapHook() {
|
||||||
return base::internal::mmap_hook_.Get();
|
return base::internal::mmap_hooks_.GetSingular();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void MallocHook::InvokeMmapHook(const void* result,
|
inline void MallocHook::InvokeMmapHook(const void* result,
|
||||||
|
@ -227,13 +168,6 @@ inline void MallocHook::InvokeMmapHook(const void* result,
|
||||||
if (!base::internal::mmap_hooks_.empty()) {
|
if (!base::internal::mmap_hooks_.empty()) {
|
||||||
InvokeMmapHookSlow(result, start, size, protection, flags, fd, offset);
|
InvokeMmapHookSlow(result, start, size, protection, flags, fd, offset);
|
||||||
}
|
}
|
||||||
// The following code is DEPRECATED.
|
|
||||||
MallocHook::MmapHook hook = MallocHook::GetMmapHook();
|
|
||||||
if (hook != NULL) (*hook)(result,
|
|
||||||
start, size,
|
|
||||||
protection, flags,
|
|
||||||
fd, offset);
|
|
||||||
// End DEPRECATED code.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool MallocHook::InvokeMmapReplacement(const void* start,
|
inline bool MallocHook::InvokeMmapReplacement(const void* start,
|
||||||
|
@ -254,17 +188,13 @@ inline bool MallocHook::InvokeMmapReplacement(const void* start,
|
||||||
|
|
||||||
// The following method is DEPRECATED
|
// The following method is DEPRECATED
|
||||||
inline MallocHook::MunmapHook MallocHook::GetMunmapHook() {
|
inline MallocHook::MunmapHook MallocHook::GetMunmapHook() {
|
||||||
return base::internal::munmap_hook_.Get();
|
return base::internal::munmap_hooks_.GetSingular();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void MallocHook::InvokeMunmapHook(const void* p, size_t size) {
|
inline void MallocHook::InvokeMunmapHook(const void* p, size_t size) {
|
||||||
if (!base::internal::munmap_hooks_.empty()) {
|
if (!base::internal::munmap_hooks_.empty()) {
|
||||||
InvokeMunmapHookSlow(p, size);
|
InvokeMunmapHookSlow(p, size);
|
||||||
}
|
}
|
||||||
// The following code is DEPRECATED.
|
|
||||||
MallocHook::MunmapHook hook = MallocHook::GetMunmapHook();
|
|
||||||
if (hook != NULL) (*hook)(p, size);
|
|
||||||
// End DEPRECATED code.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool MallocHook::InvokeMunmapReplacement(
|
inline bool MallocHook::InvokeMunmapReplacement(
|
||||||
|
@ -277,7 +207,7 @@ inline bool MallocHook::InvokeMunmapReplacement(
|
||||||
|
|
||||||
// The following method is DEPRECATED
|
// The following method is DEPRECATED
|
||||||
inline MallocHook::MremapHook MallocHook::GetMremapHook() {
|
inline MallocHook::MremapHook MallocHook::GetMremapHook() {
|
||||||
return base::internal::mremap_hook_.Get();
|
return base::internal::mremap_hooks_.GetSingular();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void MallocHook::InvokeMremapHook(const void* result,
|
inline void MallocHook::InvokeMremapHook(const void* result,
|
||||||
|
@ -289,32 +219,22 @@ inline void MallocHook::InvokeMremapHook(const void* result,
|
||||||
if (!base::internal::mremap_hooks_.empty()) {
|
if (!base::internal::mremap_hooks_.empty()) {
|
||||||
InvokeMremapHookSlow(result, old_addr, old_size, new_size, flags, new_addr);
|
InvokeMremapHookSlow(result, old_addr, old_size, new_size, flags, new_addr);
|
||||||
}
|
}
|
||||||
// The following code is DEPRECATED.
|
|
||||||
MallocHook::MremapHook hook = MallocHook::GetMremapHook();
|
|
||||||
if (hook != NULL) (*hook)(result,
|
|
||||||
old_addr, old_size,
|
|
||||||
new_size, flags, new_addr);
|
|
||||||
// End DEPRECATED code.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The following method is DEPRECATED
|
// The following method is DEPRECATED
|
||||||
inline MallocHook::PreSbrkHook MallocHook::GetPreSbrkHook() {
|
inline MallocHook::PreSbrkHook MallocHook::GetPreSbrkHook() {
|
||||||
return base::internal::presbrk_hook_.Get();
|
return base::internal::presbrk_hooks_.GetSingular();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void MallocHook::InvokePreSbrkHook(ptrdiff_t increment) {
|
inline void MallocHook::InvokePreSbrkHook(ptrdiff_t increment) {
|
||||||
if (!base::internal::presbrk_hooks_.empty() && increment != 0) {
|
if (!base::internal::presbrk_hooks_.empty() && increment != 0) {
|
||||||
InvokePreSbrkHookSlow(increment);
|
InvokePreSbrkHookSlow(increment);
|
||||||
}
|
}
|
||||||
// The following code is DEPRECATED.
|
|
||||||
MallocHook::PreSbrkHook hook = MallocHook::GetPreSbrkHook();
|
|
||||||
if (hook != NULL && increment != 0) (*hook)(increment);
|
|
||||||
// End DEPRECATED code.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The following method is DEPRECATED
|
// The following method is DEPRECATED
|
||||||
inline MallocHook::SbrkHook MallocHook::GetSbrkHook() {
|
inline MallocHook::SbrkHook MallocHook::GetSbrkHook() {
|
||||||
return base::internal::sbrk_hook_.Get();
|
return base::internal::sbrk_hooks_.GetSingular();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void MallocHook::InvokeSbrkHook(const void* result,
|
inline void MallocHook::InvokeSbrkHook(const void* result,
|
||||||
|
@ -322,10 +242,6 @@ inline void MallocHook::InvokeSbrkHook(const void* result,
|
||||||
if (!base::internal::sbrk_hooks_.empty() && increment != 0) {
|
if (!base::internal::sbrk_hooks_.empty() && increment != 0) {
|
||||||
InvokeSbrkHookSlow(result, increment);
|
InvokeSbrkHookSlow(result, increment);
|
||||||
}
|
}
|
||||||
// The following code is DEPRECATED.
|
|
||||||
MallocHook::SbrkHook hook = MallocHook::GetSbrkHook();
|
|
||||||
if (hook != NULL && increment != 0) (*hook)(result, increment);
|
|
||||||
// End DEPRECATED code.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* _MALLOC_HOOK_INL_H_ */
|
#endif /* _MALLOC_HOOK_INL_H_ */
|
||||||
|
|
|
@ -158,32 +158,6 @@ extern "C" void MallocHook_InitAtFirstAllocation_HeapLeakChecker() {
|
||||||
|
|
||||||
namespace base { namespace internal {
|
namespace base { namespace internal {
|
||||||
|
|
||||||
// The code below is DEPRECATED.
|
|
||||||
template<typename PtrT>
|
|
||||||
PtrT AtomicPtr<PtrT>::Exchange(PtrT new_val) {
|
|
||||||
base::subtle::MemoryBarrier(); // Release semantics.
|
|
||||||
// Depending on the system, NoBarrier_AtomicExchange(AtomicWord*)
|
|
||||||
// may have been defined to return an AtomicWord, Atomic32, or
|
|
||||||
// Atomic64. We hide that implementation detail here with an
|
|
||||||
// explicit cast. This prevents MSVC 2005, at least, from complaining.
|
|
||||||
PtrT old_val = reinterpret_cast<PtrT>(static_cast<AtomicWord>(
|
|
||||||
base::subtle::NoBarrier_AtomicExchange(
|
|
||||||
&data_,
|
|
||||||
reinterpret_cast<AtomicWord>(new_val))));
|
|
||||||
base::subtle::MemoryBarrier(); // And acquire semantics.
|
|
||||||
return old_val;
|
|
||||||
}
|
|
||||||
|
|
||||||
AtomicPtr<MallocHook::NewHook> new_hook_ = { 0 };
|
|
||||||
AtomicPtr<MallocHook::DeleteHook> delete_hook_ = { 0 };
|
|
||||||
AtomicPtr<MallocHook::PreMmapHook> premmap_hook_ = { 0 };
|
|
||||||
AtomicPtr<MallocHook::MmapHook> mmap_hook_ = { 0 };
|
|
||||||
AtomicPtr<MallocHook::MunmapHook> munmap_hook_ = { 0 };
|
|
||||||
AtomicPtr<MallocHook::MremapHook> mremap_hook_ = { 0 };
|
|
||||||
AtomicPtr<MallocHook::PreSbrkHook> presbrk_hook_ = { 0 };
|
|
||||||
AtomicPtr<MallocHook::SbrkHook> sbrk_hook_ = { 0 };
|
|
||||||
// End of DEPRECATED code section.
|
|
||||||
|
|
||||||
// This lock is shared between all implementations of HookList::Add & Remove.
|
// This lock is shared between all implementations of HookList::Add & Remove.
|
||||||
// The potential for contention is very small. This needs to be a SpinLock and
|
// The potential for contention is very small. This needs to be a SpinLock and
|
||||||
// not a Mutex since it's possible for Mutex locking to allocate memory (e.g.,
|
// not a Mutex since it's possible for Mutex locking to allocate memory (e.g.,
|
||||||
|
@ -304,17 +278,6 @@ HookList<MallocHook::MunmapReplacement> munmap_replacement_ = { 0 };
|
||||||
|
|
||||||
} } // namespace base::internal
|
} } // namespace base::internal
|
||||||
|
|
||||||
// The code below is DEPRECATED.
|
|
||||||
using base::internal::new_hook_;
|
|
||||||
using base::internal::delete_hook_;
|
|
||||||
using base::internal::premmap_hook_;
|
|
||||||
using base::internal::mmap_hook_;
|
|
||||||
using base::internal::munmap_hook_;
|
|
||||||
using base::internal::mremap_hook_;
|
|
||||||
using base::internal::presbrk_hook_;
|
|
||||||
using base::internal::sbrk_hook_;
|
|
||||||
// End of DEPRECATED code section.
|
|
||||||
|
|
||||||
using base::internal::kHookListMaxValues;
|
using base::internal::kHookListMaxValues;
|
||||||
using base::internal::new_hooks_;
|
using base::internal::new_hooks_;
|
||||||
using base::internal::delete_hooks_;
|
using base::internal::delete_hooks_;
|
||||||
|
@ -460,49 +423,49 @@ int MallocHook_RemoveSbrkHook(MallocHook_SbrkHook hook) {
|
||||||
extern "C"
|
extern "C"
|
||||||
MallocHook_NewHook MallocHook_SetNewHook(MallocHook_NewHook hook) {
|
MallocHook_NewHook MallocHook_SetNewHook(MallocHook_NewHook hook) {
|
||||||
RAW_VLOG(10, "SetNewHook(%p)", hook);
|
RAW_VLOG(10, "SetNewHook(%p)", hook);
|
||||||
return new_hook_.Exchange(hook);
|
return new_hooks_.ExchangeSingular(hook);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
MallocHook_DeleteHook MallocHook_SetDeleteHook(MallocHook_DeleteHook hook) {
|
MallocHook_DeleteHook MallocHook_SetDeleteHook(MallocHook_DeleteHook hook) {
|
||||||
RAW_VLOG(10, "SetDeleteHook(%p)", hook);
|
RAW_VLOG(10, "SetDeleteHook(%p)", hook);
|
||||||
return delete_hook_.Exchange(hook);
|
return delete_hooks_.ExchangeSingular(hook);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
MallocHook_PreMmapHook MallocHook_SetPreMmapHook(MallocHook_PreMmapHook hook) {
|
MallocHook_PreMmapHook MallocHook_SetPreMmapHook(MallocHook_PreMmapHook hook) {
|
||||||
RAW_VLOG(10, "SetPreMmapHook(%p)", hook);
|
RAW_VLOG(10, "SetPreMmapHook(%p)", hook);
|
||||||
return premmap_hook_.Exchange(hook);
|
return premmap_hooks_.ExchangeSingular(hook);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
MallocHook_MmapHook MallocHook_SetMmapHook(MallocHook_MmapHook hook) {
|
MallocHook_MmapHook MallocHook_SetMmapHook(MallocHook_MmapHook hook) {
|
||||||
RAW_VLOG(10, "SetMmapHook(%p)", hook);
|
RAW_VLOG(10, "SetMmapHook(%p)", hook);
|
||||||
return mmap_hook_.Exchange(hook);
|
return mmap_hooks_.ExchangeSingular(hook);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
MallocHook_MunmapHook MallocHook_SetMunmapHook(MallocHook_MunmapHook hook) {
|
MallocHook_MunmapHook MallocHook_SetMunmapHook(MallocHook_MunmapHook hook) {
|
||||||
RAW_VLOG(10, "SetMunmapHook(%p)", hook);
|
RAW_VLOG(10, "SetMunmapHook(%p)", hook);
|
||||||
return munmap_hook_.Exchange(hook);
|
return munmap_hooks_.ExchangeSingular(hook);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
MallocHook_MremapHook MallocHook_SetMremapHook(MallocHook_MremapHook hook) {
|
MallocHook_MremapHook MallocHook_SetMremapHook(MallocHook_MremapHook hook) {
|
||||||
RAW_VLOG(10, "SetMremapHook(%p)", hook);
|
RAW_VLOG(10, "SetMremapHook(%p)", hook);
|
||||||
return mremap_hook_.Exchange(hook);
|
return mremap_hooks_.ExchangeSingular(hook);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
MallocHook_PreSbrkHook MallocHook_SetPreSbrkHook(MallocHook_PreSbrkHook hook) {
|
MallocHook_PreSbrkHook MallocHook_SetPreSbrkHook(MallocHook_PreSbrkHook hook) {
|
||||||
RAW_VLOG(10, "SetPreSbrkHook(%p)", hook);
|
RAW_VLOG(10, "SetPreSbrkHook(%p)", hook);
|
||||||
return presbrk_hook_.Exchange(hook);
|
return presbrk_hooks_.ExchangeSingular(hook);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
MallocHook_SbrkHook MallocHook_SetSbrkHook(MallocHook_SbrkHook hook) {
|
MallocHook_SbrkHook MallocHook_SetSbrkHook(MallocHook_SbrkHook hook) {
|
||||||
RAW_VLOG(10, "SetSbrkHook(%p)", hook);
|
RAW_VLOG(10, "SetSbrkHook(%p)", hook);
|
||||||
return sbrk_hook_.Exchange(hook);
|
return sbrk_hooks_.ExchangeSingular(hook);
|
||||||
}
|
}
|
||||||
// End of DEPRECATED code section.
|
// End of DEPRECATED code section.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue