Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1298)

Unified Diff: runtime/vm/malloc_hooks.cc

Issue 2715493005: Removed MallocHookScope and replaced it with MallocLocker, which behaves like MutexLocker but also … (Closed)
Patch Set: Pulled static member out of MallocLocker and into MallocHooksState. Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | runtime/vm/os_thread.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/malloc_hooks.cc
diff --git a/runtime/vm/malloc_hooks.cc b/runtime/vm/malloc_hooks.cc
index 4f7de9e20d70b8b4c0326e5d47d996f0496ea5dc..a85d22e85f306300ee3b7f499290bd4a7f3f7846 100644
--- a/runtime/vm/malloc_hooks.cc
+++ b/runtime/vm/malloc_hooks.cc
@@ -13,60 +13,33 @@
#include "platform/assert.h"
#include "vm/hash_map.h"
#include "vm/json_stream.h"
-#include "vm/lockers.h"
+#include "vm/os_thread.h"
namespace dart {
-// A locker-type class to automatically grab and release the
-// in_malloc_hook_flag_.
-class MallocHookScope {
+// A locker-type class similar to MutexLocker which tracks which thread
+// currently holds the lock. We use this instead of MutexLocker and
+// mutex->IsOwnedByCurrentThread() since IsOwnedByCurrentThread() is only
+// enabled for debug mode.
+class MallocLocker : public ValueObject {
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);
+ explicit MallocLocker(Mutex* mutex, ThreadId* owner)
+ : mutex_(mutex), owner_(owner) {
+ ASSERT(owner != NULL);
+ mutex_->Lock();
+ ASSERT(*owner_ == OSThread::kInvalidThreadId);
+ *owner_ = OSThread::GetCurrentThreadId();
}
- 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() {
- MutexLocker ml(malloc_hook_scope_mutex_);
- 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
- // MallocHooksState::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_);
+ virtual ~MallocLocker() {
+ ASSERT(*owner_ == OSThread::GetCurrentThreadId());
+ *owner_ = OSThread::kInvalidThreadId;
+ mutex_->Unlock();
}
private:
- static Mutex* malloc_hook_scope_mutex_;
- static ThreadLocalKey in_malloc_hook_flag_;
-
- DISALLOW_ALLOCATION();
- DISALLOW_COPY_AND_ASSIGN(MallocHookScope);
+ Mutex* mutex_;
+ ThreadId* owner_;
};
@@ -135,6 +108,12 @@ class MallocHooksState : public AllStatic {
}
static Mutex* malloc_hook_mutex() { return malloc_hook_mutex_; }
+ static ThreadId* malloc_hook_mutex_owner() {
+ return &malloc_hook_mutex_owner_;
+ }
+ static bool IsLockHeldByCurrentThread() {
+ return (malloc_hook_mutex_owner_ == OSThread::GetCurrentThreadId());
+ }
static intptr_t allocation_count() { return allocation_count_; }
@@ -179,6 +158,7 @@ class MallocHooksState : public AllStatic {
static bool active_;
static intptr_t original_pid_;
static Mutex* malloc_hook_mutex_;
+ static ThreadId malloc_hook_mutex_owner_;
static intptr_t allocation_count_;
static intptr_t heap_allocated_memory_in_bytes_;
static AddressMap* address_map_;
@@ -187,14 +167,12 @@ class MallocHooksState : public AllStatic {
};
-// 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();
+ThreadId MallocHooksState::malloc_hook_mutex_owner_ =
+ OSThread::kInvalidThreadId;
// Memory allocation state information.
intptr_t MallocHooksState::allocation_count_ = 0;
@@ -206,10 +184,10 @@ void MallocHooks::InitOnce() {
if (!FLAG_enable_malloc_hooks) {
return;
}
- MutexLocker ml(MallocHooksState::malloc_hook_mutex());
+ MallocLocker ml(MallocHooksState::malloc_hook_mutex(),
+ MallocHooksState::malloc_hook_mutex_owner());
ASSERT(!MallocHooksState::Active());
- MallocHookScope::InitMallocHookFlag();
MallocHooksState::Init();
// Register malloc hooks.
@@ -225,7 +203,8 @@ void MallocHooks::TearDown() {
if (!FLAG_enable_malloc_hooks) {
return;
}
- MutexLocker ml(MallocHooksState::malloc_hook_mutex());
+ MallocLocker ml(MallocHooksState::malloc_hook_mutex(),
+ MallocHooksState::malloc_hook_mutex_owner());
ASSERT(MallocHooksState::Active());
// Remove malloc hooks.
@@ -236,7 +215,6 @@ void MallocHooks::TearDown() {
ASSERT(success);
MallocHooksState::TearDown();
- MallocHookScope::DestroyMallocHookFlag();
}
@@ -244,7 +222,8 @@ void MallocHooks::ResetStats() {
if (!FLAG_enable_malloc_hooks) {
return;
}
- MutexLocker ml(MallocHooksState::malloc_hook_mutex());
+ MallocLocker ml(MallocHooksState::malloc_hook_mutex(),
+ MallocHooksState::malloc_hook_mutex_owner());
if (MallocHooksState::Active()) {
MallocHooksState::ResetStats();
}
@@ -271,7 +250,8 @@ void MallocHooks::PrintToJSONObject(JSONObject* jsobj) {
// to acquire the lock recursively so we extract the values first
// and then add the JSON properties.
{
- MutexLocker ml(MallocHooksState::malloc_hook_mutex());
+ MallocLocker ml(MallocHooksState::malloc_hook_mutex(),
+ MallocHooksState::malloc_hook_mutex_owner());
if (Active()) {
allocated_memory = MallocHooksState::heap_allocated_memory_in_bytes();
allocation_count = MallocHooksState::allocation_count();
@@ -289,7 +269,8 @@ intptr_t MallocHooks::allocation_count() {
if (!FLAG_enable_malloc_hooks) {
return 0;
}
- MutexLocker ml(MallocHooksState::malloc_hook_mutex());
+ MallocLocker ml(MallocHooksState::malloc_hook_mutex(),
+ MallocHooksState::malloc_hook_mutex_owner());
return MallocHooksState::allocation_count();
}
@@ -298,22 +279,22 @@ intptr_t MallocHooks::heap_allocated_memory_in_bytes() {
if (!FLAG_enable_malloc_hooks) {
return 0;
}
- MutexLocker ml(MallocHooksState::malloc_hook_mutex());
+ MallocLocker ml(MallocHooksState::malloc_hook_mutex(),
+ MallocHooksState::malloc_hook_mutex_owner());
return MallocHooksState::heap_allocated_memory_in_bytes();
}
void MallocHooksState::RecordAllocHook(const void* ptr, size_t size) {
- if (MallocHookScope::IsInHook() || !MallocHooksState::IsOriginalProcess()) {
+ if (MallocHooksState::IsLockHeldByCurrentThread() ||
+ !MallocHooksState::IsOriginalProcess()) {
return;
}
- MutexLocker ml(MallocHooksState::malloc_hook_mutex());
+ MallocLocker ml(MallocHooksState::malloc_hook_mutex(),
+ MallocHooksState::malloc_hook_mutex_owner());
// Now that we hold the lock, check to make sure everything is still active.
if ((ptr != NULL) && MallocHooksState::Active()) {
- // 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);
}
@@ -321,16 +302,15 @@ void MallocHooksState::RecordAllocHook(const void* ptr, size_t size) {
void MallocHooksState::RecordFreeHook(const void* ptr) {
- if (MallocHookScope::IsInHook() || !MallocHooksState::IsOriginalProcess()) {
+ if (MallocHooksState::IsLockHeldByCurrentThread() ||
+ !MallocHooksState::IsOriginalProcess()) {
return;
}
- MutexLocker ml(MallocHooksState::malloc_hook_mutex());
+ MallocLocker ml(MallocHooksState::malloc_hook_mutex(),
+ MallocHooksState::malloc_hook_mutex_owner());
// Now that we hold the lock, check to make sure everything is still active.
if ((ptr != NULL) && MallocHooksState::Active()) {
- // 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);
« no previous file with comments | « no previous file | runtime/vm/os_thread.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698