Chromium Code Reviews| Index: runtime/vm/malloc_hooks.cc |
| diff --git a/runtime/vm/malloc_hooks.cc b/runtime/vm/malloc_hooks.cc |
| index 9e5c6587c3065498c8a757de121770e315e1b03d..cc7c34059c040544ad1708ce0ee634e79f9765f8 100644 |
| --- a/runtime/vm/malloc_hooks.cc |
| +++ b/runtime/vm/malloc_hooks.cc |
| @@ -22,33 +22,52 @@ namespace dart { |
| class MallocHookScope { |
| public: |
| static void InitMallocHookFlag() { |
| + MutexLocker ml(malloc_hook_scope_mutex_); |
| ASSERT(in_malloc_hook_flag_ == kUnsetThreadLocalKey); |
| in_malloc_hook_flag_ = OSThread::CreateThreadLocal(); |
| OSThread::SetThreadLocal(in_malloc_hook_flag_, 0); |
| } |
| static void DestroyMallocHookFlag() { |
| + MutexLocker ml(malloc_hook_scope_mutex_); |
| ASSERT(in_malloc_hook_flag_ != kUnsetThreadLocalKey); |
| OSThread::DeleteThreadLocal(in_malloc_hook_flag_); |
| in_malloc_hook_flag_ = kUnsetThreadLocalKey; |
| } |
| MallocHookScope() { |
| + MutexLocker ml(malloc_hook_scope_mutex_); |
| ASSERT(in_malloc_hook_flag_ != kUnsetThreadLocalKey); |
| OSThread::SetThreadLocal(in_malloc_hook_flag_, 1); |
| } |
| ~MallocHookScope() { |
| + MutexLocker ml(malloc_hook_scope_mutex_); |
| ASSERT(in_malloc_hook_flag_ != kUnsetThreadLocalKey); |
| OSThread::SetThreadLocal(in_malloc_hook_flag_, 0); |
| } |
| static bool IsInHook() { |
| - ASSERT(in_malloc_hook_flag_ != kUnsetThreadLocalKey); |
| + MutexLocker ml(malloc_hook_scope_mutex_); |
|
bkonyi
2017/02/17 21:15:11
I added a mutex to the MallocHookScope class so th
|
| + if (in_malloc_hook_flag_ == kUnsetThreadLocalKey) { |
| + // Bail out if the malloc hook flag is invalid. This means that |
| + // MallocHookState::TearDown() has been called and MallocHookScope is no |
| + // longer intitialized. Don't worry if MallocHookState::TearDown() is |
| + // called before the hooks grab the mutex, since |
| + // MallocHookScope::Active() is checked after the lock is taken before |
| + // proceeding to act on the allocation/free. |
| + return false; |
| + } |
| return OSThread::GetThreadLocal(in_malloc_hook_flag_); |
| } |
| + static bool Active() { |
|
zra
2017/02/17 21:42:26
rm
|
| + MutexLocker ml(malloc_hook_scope_mutex_); |
| + return in_malloc_hook_flag_ != kUnsetThreadLocalKey; |
|
bkonyi
2017/02/17 21:15:11
I'm guessing this needs parens around the boolean
|
| + } |
| + |
| private: |
| + static Mutex* malloc_hook_scope_mutex_; |
| static ThreadLocalKey in_malloc_hook_flag_; |
| DISALLOW_ALLOCATION(); |
| @@ -173,8 +192,11 @@ class MallocHooksState : public AllStatic { |
| }; |
| -// MallocHooks state / locks. |
| +// MallocHookScope state. |
| +Mutex* MallocHookScope::malloc_hook_scope_mutex_ = new Mutex(); |
| ThreadLocalKey MallocHookScope::in_malloc_hook_flag_ = kUnsetThreadLocalKey; |
| + |
| +// MallocHooks state / locks. |
| bool MallocHooksState::active_ = false; |
| intptr_t MallocHooksState::original_pid_ = MallocHooksState::kInvalidPid; |
| Mutex* MallocHooksState::malloc_hook_mutex_ = new Mutex(); |
| @@ -270,11 +292,13 @@ void MallocHooksState::RecordAllocHook(const void* ptr, size_t size) { |
| return; |
| } |
| - // Set the malloc hook flag before grabbing the mutex to avoid calling hooks |
| - // again. |
| - MallocHookScope mhs; |
| MutexLocker ml(MallocHooksState::malloc_hook_mutex()); |
| - if ((ptr != NULL) && MallocHooksState::Active()) { |
| + // Now that we hold the lock, check to make sure everything is still active. |
| + if ((ptr != NULL) && MallocHooksState::Active() && |
| + MallocHookScope::Active()) { |
|
bkonyi
2017/02/17 21:15:11
This extra condition, MallocHookScope::Active(), i
zra
2017/02/17 21:29:53
I don't think it's possible that we could have Mal
|
| + // Set the malloc hook flag to avoid calling hooks again if memory is |
| + // allocated/freed below. |
| + MallocHookScope mhs; |
| MallocHooksState::IncrementHeapAllocatedMemoryInBytes(size); |
| MallocHooksState::address_map()->Insert(ptr, size); |
| } |
| @@ -286,11 +310,13 @@ void MallocHooksState::RecordFreeHook(const void* ptr) { |
| return; |
| } |
| - // Set the malloc hook flag before grabbing the mutex to avoid calling hooks |
| - // again. |
| - MallocHookScope mhs; |
| MutexLocker ml(MallocHooksState::malloc_hook_mutex()); |
| - if ((ptr != NULL) && MallocHooksState::Active()) { |
| + // Now that we hold the lock, check to make sure everything is still active. |
| + if ((ptr != NULL) && MallocHooksState::Active() && |
| + MallocHookScope::Active()) { |
|
zra
2017/02/17 21:29:53
ditto
|
| + // Set the malloc hook flag to avoid calling hooks again if memory is |
| + // allocated/freed below. |
| + MallocHookScope mhs; |
| intptr_t size = 0; |
| if (MallocHooksState::address_map()->Lookup(ptr, &size)) { |
| MallocHooksState::DecrementHeapAllocatedMemoryInBytes(size); |