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

Side by Side Diff: runtime/vm/malloc_hooks.cc

Issue 2714083002: Revert "Fixed issue in MallocHooks where a MallocHookScope was accidentally removed during a merge,… (Closed)
Patch Set: 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 unified diff | Download patch
« no previous file with comments | « runtime/vm/malloc_hooks.h ('k') | runtime/vm/malloc_hooks_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "platform/globals.h" 5 #include "platform/globals.h"
6 6
7 #if defined(DART_USE_TCMALLOC) && !defined(PRODUCT) && \ 7 #if defined(DART_USE_TCMALLOC) && !defined(PRODUCT)
8 !defined(TARGET_ARCH_DBC) && !defined(TARGET_OS_FUCHSIA)
9 8
10 #include "vm/malloc_hooks.h" 9 #include "vm/malloc_hooks.h"
11 10
12 #include "gperftools/malloc_hook.h" 11 #include "gperftools/malloc_hook.h"
13 12
14 #include "platform/assert.h" 13 #include "platform/assert.h"
15 #include "vm/hash_map.h" 14 #include "vm/hash_map.h"
16 #include "vm/json_stream.h" 15 #include "vm/json_stream.h"
17 #include "vm/os_thread.h" 16 #include "vm/os_thread.h"
18 #include "vm/profiler.h"
19 17
20 namespace dart { 18 namespace dart {
21 19
22 class AddressMap;
23
24 // MallocHooksState contains all of the state related to the configuration of
25 // the malloc hooks, allocation information, and locks.
26 class MallocHooksState : public AllStatic {
27 public:
28 static void RecordAllocHook(const void* ptr, size_t size);
29 static void RecordFreeHook(const void* ptr);
30
31 static bool Active() {
32 ASSERT(malloc_hook_mutex()->IsOwnedByCurrentThread());
33 return active_;
34 }
35 static void Init();
36
37 static bool ProfilingEnabled() { return (OSThread::TryCurrent() != NULL); }
38
39 static bool stack_trace_collection_enabled() {
40 return stack_trace_collection_enabled_;
41 }
42
43 static void set_stack_trace_collection_enabled(bool enabled) {
44 stack_trace_collection_enabled_ = enabled;
45 }
46
47 static bool IsOriginalProcess() {
48 ASSERT(original_pid_ != kInvalidPid);
49 return original_pid_ == OS::ProcessId();
50 }
51
52 static Mutex* malloc_hook_mutex() { return malloc_hook_mutex_; }
53 static ThreadId* malloc_hook_mutex_owner() {
54 return &malloc_hook_mutex_owner_;
55 }
56 static bool IsLockHeldByCurrentThread() {
57 return (malloc_hook_mutex_owner_ == OSThread::GetCurrentThreadId());
58 }
59
60 static intptr_t allocation_count() { return allocation_count_; }
61
62 static intptr_t heap_allocated_memory_in_bytes() {
63 return heap_allocated_memory_in_bytes_;
64 }
65
66 static void IncrementHeapAllocatedMemoryInBytes(intptr_t size) {
67 ASSERT(malloc_hook_mutex()->IsOwnedByCurrentThread());
68 ASSERT(size >= 0);
69 heap_allocated_memory_in_bytes_ += size;
70 ++allocation_count_;
71 }
72
73 static void DecrementHeapAllocatedMemoryInBytes(intptr_t size) {
74 ASSERT(malloc_hook_mutex()->IsOwnedByCurrentThread());
75 ASSERT(size >= 0);
76 ASSERT(heap_allocated_memory_in_bytes_ >= size);
77 heap_allocated_memory_in_bytes_ -= size;
78 --allocation_count_;
79 ASSERT(allocation_count_ >= 0);
80 }
81
82 static AddressMap* address_map() { return address_map_; }
83
84 static void ResetStats();
85 static void TearDown();
86
87 private:
88 static Mutex* malloc_hook_mutex_;
89 static ThreadId malloc_hook_mutex_owner_;
90
91 // Variables protected by malloc_hook_mutex_.
92 static bool active_;
93 static bool stack_trace_collection_enabled_;
94 static intptr_t allocation_count_;
95 static intptr_t heap_allocated_memory_in_bytes_;
96 static AddressMap* address_map_;
97 // End protected variables.
98
99 static intptr_t original_pid_;
100 static const intptr_t kInvalidPid = -1;
101 };
102
103 // A locker-type class similar to MutexLocker which tracks which thread 20 // A locker-type class similar to MutexLocker which tracks which thread
104 // currently holds the lock. We use this instead of MutexLocker and 21 // currently holds the lock. We use this instead of MutexLocker and
105 // mutex->IsOwnedByCurrentThread() since IsOwnedByCurrentThread() is only 22 // mutex->IsOwnedByCurrentThread() since IsOwnedByCurrentThread() is only
106 // enabled for debug mode. 23 // enabled for debug mode.
107 class MallocLocker : public ValueObject { 24 class MallocLocker : public ValueObject {
108 public: 25 public:
109 explicit MallocLocker(Mutex* mutex, ThreadId* owner) 26 explicit MallocLocker(Mutex* mutex, ThreadId* owner)
110 : mutex_(mutex), owner_(owner) { 27 : mutex_(mutex), owner_(owner) {
111 ASSERT(owner != NULL); 28 ASSERT(owner != NULL);
112 mutex_->Lock(); 29 mutex_->Lock();
113 ASSERT(*owner_ == OSThread::kInvalidThreadId); 30 ASSERT(*owner_ == OSThread::kInvalidThreadId);
114 *owner_ = OSThread::GetCurrentThreadId(); 31 *owner_ = OSThread::GetCurrentThreadId();
115 } 32 }
116 33
117 virtual ~MallocLocker() { 34 virtual ~MallocLocker() {
118 ASSERT(*owner_ == OSThread::GetCurrentThreadId()); 35 ASSERT(*owner_ == OSThread::GetCurrentThreadId());
119 *owner_ = OSThread::kInvalidThreadId; 36 *owner_ = OSThread::kInvalidThreadId;
120 mutex_->Unlock(); 37 mutex_->Unlock();
121 } 38 }
122 39
123 private: 40 private:
124 Mutex* mutex_; 41 Mutex* mutex_;
125 ThreadId* owner_; 42 ThreadId* owner_;
126 }; 43 };
127 44
128 // AllocationInfo contains all information related to a given allocation
129 // including:
130 // -Allocation size in bytes
131 // -Stack trace corresponding to the location of allocation, if applicable
132 class AllocationInfo {
133 public:
134 explicit AllocationInfo(intptr_t allocation_size)
135 : sample_(NULL), allocation_size_(allocation_size) {
136 // Stack trace collection is disabled when we are in the process of creating
137 // the first OSThread in order to prevent deadlocks.
138 if (MallocHooksState::ProfilingEnabled() &&
139 MallocHooksState::stack_trace_collection_enabled()) {
140 sample_ = Profiler::SampleNativeAllocation(kSkipCount);
141 }
142 }
143
144 Sample* sample() const { return sample_; }
145 intptr_t allocation_size() const { return allocation_size_; }
146
147 private:
148 Sample* sample_;
149 intptr_t allocation_size_;
150
151 // The number of frames that are generated by the malloc hooks and collection
152 // of the stack trace. These frames are ignored when collecting the stack
153 // trace for a memory allocation. If this number is incorrect, some tests in
154 // malloc_hook_tests.cc might fail, particularily
155 // StackTraceMallocHookLengthTest. If this value is updated, please make sure
156 // that the MallocHooks test cases pass on all platforms.
157 static const intptr_t kSkipCount = 5;
158 };
159
160 45
161 // Custom key/value trait specifically for address/size pairs. Unlike 46 // Custom key/value trait specifically for address/size pairs. Unlike
162 // RawPointerKeyValueTrait, the default value is -1 as 0 can be a valid entry. 47 // RawPointerKeyValueTrait, the default value is -1 as 0 can be a valid entry.
163 class AddressKeyValueTrait : public AllStatic { 48 class AddressKeyValueTrait {
164 public: 49 public:
165 typedef const void* Key; 50 typedef const void* Key;
166 typedef AllocationInfo* Value; 51 typedef intptr_t Value;
167 52
168 struct Pair { 53 struct Pair {
169 Key key; 54 Key key;
170 Value value; 55 Value value;
171 Pair() : key(NULL), value(NULL) {} 56 Pair() : key(NULL), value(-1) {}
172 Pair(const Key key, const Value& value) : key(key), value(value) {} 57 Pair(const Key key, const Value& value) : key(key), value(value) {}
173 Pair(const Pair& other) : key(other.key), value(other.value) {} 58 Pair(const Pair& other) : key(other.key), value(other.value) {}
174 }; 59 };
175 60
176 static Key KeyOf(Pair kv) { return kv.key; } 61 static Key KeyOf(Pair kv) { return kv.key; }
177 static Value ValueOf(Pair kv) { return kv.value; } 62 static Value ValueOf(Pair kv) { return kv.value; }
178 static intptr_t Hashcode(Key key) { return reinterpret_cast<intptr_t>(key); } 63 static intptr_t Hashcode(Key key) { return reinterpret_cast<intptr_t>(key); }
179 static bool IsKeyEqual(Pair kv, Key key) { return kv.key == key; } 64 static bool IsKeyEqual(Pair kv, Key key) { return kv.key == key; }
180 }; 65 };
181 66
182 67
183 // Map class that will be used to store mappings between ptr -> allocation size. 68 // Map class that will be used to store mappings between ptr -> allocation size.
184 class AddressMap : public MallocDirectChainedHashMap<AddressKeyValueTrait> { 69 class AddressMap : public MallocDirectChainedHashMap<AddressKeyValueTrait> {
185 public: 70 public:
186 typedef AddressKeyValueTrait::Key Key; 71 typedef AddressKeyValueTrait::Key Key;
187 typedef AddressKeyValueTrait::Value Value; 72 typedef AddressKeyValueTrait::Value Value;
188 typedef AddressKeyValueTrait::Pair Pair; 73 typedef AddressKeyValueTrait::Pair Pair;
189 74
190 virtual ~AddressMap() { Clear(); } 75 inline void Insert(const Key& key, const Value& value) {
191
192 void Insert(const Key& key, const Value& value) {
193 Pair pair(key, value); 76 Pair pair(key, value);
194 MallocDirectChainedHashMap<AddressKeyValueTrait>::Insert(pair); 77 MallocDirectChainedHashMap<AddressKeyValueTrait>::Insert(pair);
195 } 78 }
196 79
197 bool Lookup(const Key& key, Value* value) { 80 inline bool Lookup(const Key& key, Value* value) {
198 ASSERT(value != NULL); 81 ASSERT(value != NULL);
199 Pair* pair = MallocDirectChainedHashMap<AddressKeyValueTrait>::Lookup(key); 82 Pair* pair = MallocDirectChainedHashMap<AddressKeyValueTrait>::Lookup(key);
200 if (pair == NULL) { 83 if (pair == NULL) {
201 return false; 84 return false;
202 } else { 85 } else {
203 *value = pair->value; 86 *value = pair->value;
204 return true; 87 return true;
205 } 88 }
206 } 89 }
90 };
207 91
208 void Clear() { 92
209 Iterator iter = GetIterator(); 93 class MallocHooksState : public AllStatic {
210 Pair* result = iter.Next(); 94 public:
211 while (result != NULL) { 95 static void RecordAllocHook(const void* ptr, size_t size);
212 delete result->value; 96 static void RecordFreeHook(const void* ptr);
213 result->value = NULL; 97
214 result = iter.Next(); 98 static bool Active() { return active_; }
215 } 99 static void Init() {
216 MallocDirectChainedHashMap<AddressKeyValueTrait>::Clear(); 100 address_map_ = new AddressMap();
101 active_ = true;
102 original_pid_ = OS::ProcessId();
217 } 103 }
104
105 static bool IsOriginalProcess() {
106 ASSERT(original_pid_ != kInvalidPid);
107 return original_pid_ == OS::ProcessId();
108 }
109
110 static Mutex* malloc_hook_mutex() { return malloc_hook_mutex_; }
111 static ThreadId* malloc_hook_mutex_owner() {
112 return &malloc_hook_mutex_owner_;
113 }
114 static bool IsLockHeldByCurrentThread() {
115 return (malloc_hook_mutex_owner_ == OSThread::GetCurrentThreadId());
116 }
117
118 static intptr_t allocation_count() { return allocation_count_; }
119
120 static intptr_t heap_allocated_memory_in_bytes() {
121 return heap_allocated_memory_in_bytes_;
122 }
123
124 static void IncrementHeapAllocatedMemoryInBytes(intptr_t size) {
125 ASSERT(malloc_hook_mutex()->IsOwnedByCurrentThread());
126 ASSERT(size >= 0);
127 heap_allocated_memory_in_bytes_ += size;
128 ++allocation_count_;
129 }
130
131 static void DecrementHeapAllocatedMemoryInBytes(intptr_t size) {
132 ASSERT(malloc_hook_mutex()->IsOwnedByCurrentThread());
133 ASSERT(size >= 0);
134 ASSERT(heap_allocated_memory_in_bytes_ >= size);
135 heap_allocated_memory_in_bytes_ -= size;
136 --allocation_count_;
137 ASSERT(allocation_count_ >= 0);
138 }
139
140 static AddressMap* address_map() { return address_map_; }
141
142 static void ResetStats() {
143 ASSERT(malloc_hook_mutex()->IsOwnedByCurrentThread());
144 allocation_count_ = 0;
145 heap_allocated_memory_in_bytes_ = 0;
146 address_map_->Clear();
147 }
148
149 static void TearDown() {
150 ASSERT(malloc_hook_mutex()->IsOwnedByCurrentThread());
151 active_ = false;
152 original_pid_ = kInvalidPid;
153 ResetStats();
154 delete address_map_;
155 }
156
157 private:
158 static bool active_;
159 static intptr_t original_pid_;
160 static Mutex* malloc_hook_mutex_;
161 static ThreadId malloc_hook_mutex_owner_;
162 static intptr_t allocation_count_;
163 static intptr_t heap_allocated_memory_in_bytes_;
164 static AddressMap* address_map_;
165
166 static const intptr_t kInvalidPid = -1;
218 }; 167 };
219 168
220 169
221 // MallocHooks state / locks. 170 // MallocHooks state / locks.
222 bool MallocHooksState::active_ = false; 171 bool MallocHooksState::active_ = false;
223 bool MallocHooksState::stack_trace_collection_enabled_ = false;
224 intptr_t MallocHooksState::original_pid_ = MallocHooksState::kInvalidPid; 172 intptr_t MallocHooksState::original_pid_ = MallocHooksState::kInvalidPid;
225 Mutex* MallocHooksState::malloc_hook_mutex_ = new Mutex(); 173 Mutex* MallocHooksState::malloc_hook_mutex_ = new Mutex();
226 ThreadId MallocHooksState::malloc_hook_mutex_owner_ = 174 ThreadId MallocHooksState::malloc_hook_mutex_owner_ =
227 OSThread::kInvalidThreadId; 175 OSThread::kInvalidThreadId;
228 176
229 // Memory allocation state information. 177 // Memory allocation state information.
230 intptr_t MallocHooksState::allocation_count_ = 0; 178 intptr_t MallocHooksState::allocation_count_ = 0;
231 intptr_t MallocHooksState::heap_allocated_memory_in_bytes_ = 0; 179 intptr_t MallocHooksState::heap_allocated_memory_in_bytes_ = 0;
232 AddressMap* MallocHooksState::address_map_ = NULL; 180 AddressMap* MallocHooksState::address_map_ = NULL;
233 181
234 182
235 void MallocHooksState::Init() {
236 address_map_ = new AddressMap();
237 active_ = true;
238 #if defined(DEBUG)
239 stack_trace_collection_enabled_ = true;
240 #else
241 stack_trace_collection_enabled_ = false;
242 #endif // defined(DEBUG)
243 original_pid_ = OS::ProcessId();
244 }
245
246
247 void MallocHooksState::ResetStats() {
248 ASSERT(malloc_hook_mutex()->IsOwnedByCurrentThread());
249 allocation_count_ = 0;
250 heap_allocated_memory_in_bytes_ = 0;
251 address_map_->Clear();
252 }
253
254
255 void MallocHooksState::TearDown() {
256 ASSERT(malloc_hook_mutex()->IsOwnedByCurrentThread());
257 active_ = false;
258 original_pid_ = kInvalidPid;
259 ResetStats();
260 delete address_map_;
261 address_map_ = NULL;
262 }
263
264
265 void MallocHooks::InitOnce() { 183 void MallocHooks::InitOnce() {
266 if (!FLAG_enable_malloc_hooks) { 184 if (!FLAG_enable_malloc_hooks) {
267 return; 185 return;
268 } 186 }
269 MallocLocker ml(MallocHooksState::malloc_hook_mutex(), 187 MallocLocker ml(MallocHooksState::malloc_hook_mutex(),
270 MallocHooksState::malloc_hook_mutex_owner()); 188 MallocHooksState::malloc_hook_mutex_owner());
271 ASSERT(!MallocHooksState::Active()); 189 ASSERT(!MallocHooksState::Active());
272 190
273 MallocHooksState::Init(); 191 MallocHooksState::Init();
274 192
(...skipping 18 matching lines...) Expand all
293 bool success = false; 211 bool success = false;
294 success = MallocHook::RemoveNewHook(&MallocHooksState::RecordAllocHook); 212 success = MallocHook::RemoveNewHook(&MallocHooksState::RecordAllocHook);
295 ASSERT(success); 213 ASSERT(success);
296 success = MallocHook::RemoveDeleteHook(&MallocHooksState::RecordFreeHook); 214 success = MallocHook::RemoveDeleteHook(&MallocHooksState::RecordFreeHook);
297 ASSERT(success); 215 ASSERT(success);
298 216
299 MallocHooksState::TearDown(); 217 MallocHooksState::TearDown();
300 } 218 }
301 219
302 220
303 bool MallocHooks::ProfilingEnabled() {
304 return MallocHooksState::ProfilingEnabled();
305 }
306
307
308 bool MallocHooks::stack_trace_collection_enabled() {
309 MallocLocker ml(MallocHooksState::malloc_hook_mutex(),
310 MallocHooksState::malloc_hook_mutex_owner());
311 return MallocHooksState::stack_trace_collection_enabled();
312 }
313
314
315 void MallocHooks::set_stack_trace_collection_enabled(bool enabled) {
316 MallocLocker ml(MallocHooksState::malloc_hook_mutex(),
317 MallocHooksState::malloc_hook_mutex_owner());
318 MallocHooksState::set_stack_trace_collection_enabled(enabled);
319 }
320
321
322 void MallocHooks::ResetStats() { 221 void MallocHooks::ResetStats() {
323 if (!FLAG_enable_malloc_hooks) { 222 if (!FLAG_enable_malloc_hooks) {
324 return; 223 return;
325 } 224 }
326 MallocLocker ml(MallocHooksState::malloc_hook_mutex(), 225 MallocLocker ml(MallocHooksState::malloc_hook_mutex(),
327 MallocHooksState::malloc_hook_mutex_owner()); 226 MallocHooksState::malloc_hook_mutex_owner());
328 if (MallocHooksState::Active()) { 227 if (MallocHooksState::Active()) {
329 MallocHooksState::ResetStats(); 228 MallocHooksState::ResetStats();
330 } 229 }
331 } 230 }
332 231
333 232
334 bool MallocHooks::Active() { 233 bool MallocHooks::Active() {
335 if (!FLAG_enable_malloc_hooks) { 234 if (!FLAG_enable_malloc_hooks) {
336 return false; 235 return false;
337 } 236 }
338 MallocLocker ml(MallocHooksState::malloc_hook_mutex(), 237 ASSERT(MallocHooksState::malloc_hook_mutex()->IsOwnedByCurrentThread());
339 MallocHooksState::malloc_hook_mutex_owner());
340
341 return MallocHooksState::Active(); 238 return MallocHooksState::Active();
342 } 239 }
343 240
344 241
345 void MallocHooks::PrintToJSONObject(JSONObject* jsobj) { 242 void MallocHooks::PrintToJSONObject(JSONObject* jsobj) {
346 if (!FLAG_enable_malloc_hooks) { 243 if (!FLAG_enable_malloc_hooks) {
347 return; 244 return;
348 } 245 }
349 intptr_t allocated_memory = 0; 246 intptr_t allocated_memory = 0;
350 intptr_t allocation_count = 0; 247 intptr_t allocation_count = 0;
351 bool add_usage = false; 248 bool add_usage = false;
352 // AddProperty may call malloc which would result in an attempt 249 // AddProperty may call malloc which would result in an attempt
353 // to acquire the lock recursively so we extract the values first 250 // to acquire the lock recursively so we extract the values first
354 // and then add the JSON properties. 251 // and then add the JSON properties.
355 { 252 {
356 MallocLocker ml(MallocHooksState::malloc_hook_mutex(), 253 MallocLocker ml(MallocHooksState::malloc_hook_mutex(),
357 MallocHooksState::malloc_hook_mutex_owner()); 254 MallocHooksState::malloc_hook_mutex_owner());
358 if (MallocHooksState::Active()) { 255 if (Active()) {
359 allocated_memory = MallocHooksState::heap_allocated_memory_in_bytes(); 256 allocated_memory = MallocHooksState::heap_allocated_memory_in_bytes();
360 allocation_count = MallocHooksState::allocation_count(); 257 allocation_count = MallocHooksState::allocation_count();
361 add_usage = true; 258 add_usage = true;
362 } 259 }
363 } 260 }
364 if (add_usage) { 261 if (add_usage) {
365 jsobj->AddProperty("_heapAllocatedMemoryUsage", allocated_memory); 262 jsobj->AddProperty("_heapAllocatedMemoryUsage", allocated_memory);
366 jsobj->AddProperty("_heapAllocationCount", allocation_count); 263 jsobj->AddProperty("_heapAllocationCount", allocation_count);
367 } 264 }
368 } 265 }
(...skipping 12 matching lines...) Expand all
381 intptr_t MallocHooks::heap_allocated_memory_in_bytes() { 278 intptr_t MallocHooks::heap_allocated_memory_in_bytes() {
382 if (!FLAG_enable_malloc_hooks) { 279 if (!FLAG_enable_malloc_hooks) {
383 return 0; 280 return 0;
384 } 281 }
385 MallocLocker ml(MallocHooksState::malloc_hook_mutex(), 282 MallocLocker ml(MallocHooksState::malloc_hook_mutex(),
386 MallocHooksState::malloc_hook_mutex_owner()); 283 MallocHooksState::malloc_hook_mutex_owner());
387 return MallocHooksState::heap_allocated_memory_in_bytes(); 284 return MallocHooksState::heap_allocated_memory_in_bytes();
388 } 285 }
389 286
390 287
391 Sample* MallocHooks::GetSample(const void* ptr) {
392 MallocLocker ml(MallocHooksState::malloc_hook_mutex(),
393 MallocHooksState::malloc_hook_mutex_owner());
394
395 ASSERT(MallocHooksState::Active());
396
397 if (ptr != NULL) {
398 AllocationInfo* allocation_info = NULL;
399 if (MallocHooksState::address_map()->Lookup(ptr, &allocation_info)) {
400 ASSERT(allocation_info != NULL);
401 return allocation_info->sample();
402 }
403 }
404 return NULL;
405 }
406
407
408 void MallocHooksState::RecordAllocHook(const void* ptr, size_t size) { 288 void MallocHooksState::RecordAllocHook(const void* ptr, size_t size) {
409 if (MallocHooksState::IsLockHeldByCurrentThread() || 289 if (MallocHooksState::IsLockHeldByCurrentThread() ||
410 !MallocHooksState::IsOriginalProcess()) { 290 !MallocHooksState::IsOriginalProcess()) {
411 return; 291 return;
412 } 292 }
413 293
414 MallocLocker ml(MallocHooksState::malloc_hook_mutex(), 294 MallocLocker ml(MallocHooksState::malloc_hook_mutex(),
415 MallocHooksState::malloc_hook_mutex_owner()); 295 MallocHooksState::malloc_hook_mutex_owner());
416 // Now that we hold the lock, check to make sure everything is still active. 296 // Now that we hold the lock, check to make sure everything is still active.
417 if ((ptr != NULL) && MallocHooksState::Active()) { 297 if ((ptr != NULL) && MallocHooksState::Active()) {
418 MallocHooksState::IncrementHeapAllocatedMemoryInBytes(size); 298 MallocHooksState::IncrementHeapAllocatedMemoryInBytes(size);
419 MallocHooksState::address_map()->Insert(ptr, new AllocationInfo(size)); 299 MallocHooksState::address_map()->Insert(ptr, size);
420 } 300 }
421 } 301 }
422 302
423 303
424 void MallocHooksState::RecordFreeHook(const void* ptr) { 304 void MallocHooksState::RecordFreeHook(const void* ptr) {
425 if (MallocHooksState::IsLockHeldByCurrentThread() || 305 if (MallocHooksState::IsLockHeldByCurrentThread() ||
426 !MallocHooksState::IsOriginalProcess()) { 306 !MallocHooksState::IsOriginalProcess()) {
427 return; 307 return;
428 } 308 }
429 309
430 MallocLocker ml(MallocHooksState::malloc_hook_mutex(), 310 MallocLocker ml(MallocHooksState::malloc_hook_mutex(),
431 MallocHooksState::malloc_hook_mutex_owner()); 311 MallocHooksState::malloc_hook_mutex_owner());
432 // Now that we hold the lock, check to make sure everything is still active. 312 // Now that we hold the lock, check to make sure everything is still active.
433 if ((ptr != NULL) && MallocHooksState::Active()) { 313 if ((ptr != NULL) && MallocHooksState::Active()) {
434 AllocationInfo* allocation_info = NULL; 314 intptr_t size = 0;
435 if (MallocHooksState::address_map()->Lookup(ptr, &allocation_info)) { 315 if (MallocHooksState::address_map()->Lookup(ptr, &size)) {
436 MallocHooksState::DecrementHeapAllocatedMemoryInBytes( 316 MallocHooksState::DecrementHeapAllocatedMemoryInBytes(size);
437 allocation_info->allocation_size());
438 MallocHooksState::address_map()->Remove(ptr); 317 MallocHooksState::address_map()->Remove(ptr);
439 delete allocation_info;
440 } 318 }
441 } 319 }
442 } 320 }
443 321
444 } // namespace dart 322 } // namespace dart
445 323
446 #endif // defined(DART_USE_TCMALLOC) && !defined(PRODUCT) && 324 #endif // defined(DART_USE_TCMALLOC) && !defined(PRODUCT)
447 // !defined(TARGET_ARCH_DBC) && !defined(TARGET_OS_FUCHSIA)
OLDNEW
« no previous file with comments | « runtime/vm/malloc_hooks.h ('k') | runtime/vm/malloc_hooks_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698