| Index: runtime/vm/malloc_hooks.cc
|
| diff --git a/runtime/vm/malloc_hooks.cc b/runtime/vm/malloc_hooks.cc
|
| index 65edca7bff776d8d8c571b97c1e3e95c0e199a2c..0d2c7b4e53ba47b0926a786e7a970334f9e068d1 100644
|
| --- a/runtime/vm/malloc_hooks.cc
|
| +++ b/runtime/vm/malloc_hooks.cc
|
| @@ -6,10 +6,72 @@
|
|
|
| #include "vm/malloc_hooks.h"
|
|
|
| +#include "platform/assert.h"
|
| +
|
| +#include "base/spinlock.h"
|
| +#include "gperftools/malloc_hook.h"
|
| +
|
| namespace dart {
|
|
|
| +// Use a simple spinlock to avoid race conditions while also avoiding use of
|
| +// malloc/new.
|
| +static SpinLock malloc_hooks_spinlock_(base::LINKER_INITIALIZED);
|
| +
|
| +// MallocHooks static member variables.
|
| +bool MallocHooks::initialized_ = false;
|
| +LowLevelAlloc::Arena* MallocHooks::malloc_hooks_memory_ = NULL;
|
| +uintptr_t MallocHooks::heap_allocated_memory_in_bytes_ = 0;
|
| +AddressMap<uintptr_t>* MallocHooks::allocation_map_ = NULL;
|
| +
|
| +
|
| void MallocHooks::Init() {
|
| - // TODO(bkonyi): Implement
|
| + SpinLockHolder l(&malloc_hooks_spinlock_);
|
| +
|
| + if (initialized_) {
|
| + return;
|
| + }
|
| + initialized_ = true;
|
| +
|
| + // Allocate any memory needed for the MallocHooks datastructures
|
| + // before we connect the hooks to avoid dependencies on malloc/free.
|
| + malloc_hooks_memory_ =
|
| + LowLevelAlloc::NewArena(0, LowLevelAlloc::DefaultArena());
|
| + allocation_map_ =
|
| + new AddressMap<uintptr_t>(MallocHooksMalloc, MallocHooksFree);
|
| +
|
| + heap_allocated_memory_in_bytes_ = 0;
|
| +
|
| + // Register malloc hooks.
|
| + ASSERT(MallocHook::AddNewHook(&RecordAllocHook));
|
| + ASSERT(MallocHook::AddDeleteHook(&RecordFreeHook));
|
| +}
|
| +
|
| +
|
| +void MallocHooks::TearDown() {
|
| + SpinLockHolder l(&malloc_hooks_spinlock_);
|
| + ASSERT(MallocHook::RemoveNewHook(&RecordAllocHook));
|
| + ASSERT(MallocHook::RemoveDeleteHook(&RecordFreeHook));
|
| + initialized_ = false;
|
| +}
|
| +
|
| +
|
| +void MallocHooks::RecordAllocHook(const void* ptr, size_t size) {
|
| + SpinLockHolder l(&malloc_hooks_spinlock_);
|
| + if (ptr != NULL) {
|
| + heap_allocated_memory_in_bytes_ += size;
|
| + allocation_map_->Insert(ptr, size);
|
| + }
|
| +}
|
| +
|
| +
|
| +void MallocHooks::RecordFreeHook(const void* ptr) {
|
| + SpinLockHolder l(&malloc_hooks_spinlock_);
|
| + if (ptr != NULL) {
|
| + uintptr_t value = 0;
|
| + ASSERT(allocation_map_->FindAndRemove(ptr, &value));
|
| + ASSERT(heap_allocated_memory_in_bytes_ >= value);
|
| + heap_allocated_memory_in_bytes_ -= value;
|
| + }
|
| }
|
|
|
| } // namespace dart
|
|
|