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

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

Issue 2711353003: Fixed tests not having MallocHooks initialized for tests in release mode. (Closed)
Patch Set: Created 3 years, 9 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)
8 9
9 #include "vm/malloc_hooks.h" 10 #include "vm/malloc_hooks.h"
10 11
11 #include "gperftools/malloc_hook.h" 12 #include "gperftools/malloc_hook.h"
12 13
13 #include "platform/assert.h" 14 #include "platform/assert.h"
14 #include "vm/hash_map.h" 15 #include "vm/hash_map.h"
15 #include "vm/json_stream.h" 16 #include "vm/json_stream.h"
16 #include "vm/os_thread.h" 17 #include "vm/os_thread.h"
18 #include "vm/profiler.h"
17 19
18 namespace dart { 20 namespace dart {
19 21
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
20 // A locker-type class similar to MutexLocker which tracks which thread 103 // A locker-type class similar to MutexLocker which tracks which thread
21 // currently holds the lock. We use this instead of MutexLocker and 104 // currently holds the lock. We use this instead of MutexLocker and
22 // mutex->IsOwnedByCurrentThread() since IsOwnedByCurrentThread() is only 105 // mutex->IsOwnedByCurrentThread() since IsOwnedByCurrentThread() is only
23 // enabled for debug mode. 106 // enabled for debug mode.
24 class MallocLocker : public ValueObject { 107 class MallocLocker : public ValueObject {
25 public: 108 public:
26 explicit MallocLocker(Mutex* mutex, ThreadId* owner) 109 explicit MallocLocker(Mutex* mutex, ThreadId* owner)
27 : mutex_(mutex), owner_(owner) { 110 : mutex_(mutex), owner_(owner) {
28 ASSERT(owner != NULL); 111 ASSERT(owner != NULL);
29 mutex_->Lock(); 112 mutex_->Lock();
30 ASSERT(*owner_ == OSThread::kInvalidThreadId); 113 ASSERT(*owner_ == OSThread::kInvalidThreadId);
31 *owner_ = OSThread::GetCurrentThreadId(); 114 *owner_ = OSThread::GetCurrentThreadId();
32 } 115 }
33 116
34 virtual ~MallocLocker() { 117 virtual ~MallocLocker() {
35 ASSERT(*owner_ == OSThread::GetCurrentThreadId()); 118 ASSERT(*owner_ == OSThread::GetCurrentThreadId());
36 *owner_ = OSThread::kInvalidThreadId; 119 *owner_ = OSThread::kInvalidThreadId;
37 mutex_->Unlock(); 120 mutex_->Unlock();
38 } 121 }
39 122
40 private: 123 private:
41 Mutex* mutex_; 124 Mutex* mutex_;
42 ThreadId* owner_; 125 ThreadId* owner_;
43 }; 126 };
44 127
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
45 160
46 // Custom key/value trait specifically for address/size pairs. Unlike 161 // Custom key/value trait specifically for address/size pairs. Unlike
47 // RawPointerKeyValueTrait, the default value is -1 as 0 can be a valid entry. 162 // RawPointerKeyValueTrait, the default value is -1 as 0 can be a valid entry.
48 class AddressKeyValueTrait { 163 class AddressKeyValueTrait : public AllStatic {
49 public: 164 public:
50 typedef const void* Key; 165 typedef const void* Key;
51 typedef intptr_t Value; 166 typedef AllocationInfo* Value;
52 167
53 struct Pair { 168 struct Pair {
54 Key key; 169 Key key;
55 Value value; 170 Value value;
56 Pair() : key(NULL), value(-1) {} 171 Pair() : key(NULL), value(NULL) {}
57 Pair(const Key key, const Value& value) : key(key), value(value) {} 172 Pair(const Key key, const Value& value) : key(key), value(value) {}
58 Pair(const Pair& other) : key(other.key), value(other.value) {} 173 Pair(const Pair& other) : key(other.key), value(other.value) {}
59 }; 174 };
60 175
61 static Key KeyOf(Pair kv) { return kv.key; } 176 static Key KeyOf(Pair kv) { return kv.key; }
62 static Value ValueOf(Pair kv) { return kv.value; } 177 static Value ValueOf(Pair kv) { return kv.value; }
63 static intptr_t Hashcode(Key key) { return reinterpret_cast<intptr_t>(key); } 178 static intptr_t Hashcode(Key key) { return reinterpret_cast<intptr_t>(key); }
64 static bool IsKeyEqual(Pair kv, Key key) { return kv.key == key; } 179 static bool IsKeyEqual(Pair kv, Key key) { return kv.key == key; }
65 }; 180 };
66 181
67 182
68 // Map class that will be used to store mappings between ptr -> allocation size. 183 // Map class that will be used to store mappings between ptr -> allocation size.
69 class AddressMap : public MallocDirectChainedHashMap<AddressKeyValueTrait> { 184 class AddressMap : public MallocDirectChainedHashMap<AddressKeyValueTrait> {
70 public: 185 public:
71 typedef AddressKeyValueTrait::Key Key; 186 typedef AddressKeyValueTrait::Key Key;
72 typedef AddressKeyValueTrait::Value Value; 187 typedef AddressKeyValueTrait::Value Value;
73 typedef AddressKeyValueTrait::Pair Pair; 188 typedef AddressKeyValueTrait::Pair Pair;
74 189
75 inline void Insert(const Key& key, const Value& value) { 190 virtual ~AddressMap() { Clear(); }
191
192 void Insert(const Key& key, const Value& value) {
76 Pair pair(key, value); 193 Pair pair(key, value);
77 MallocDirectChainedHashMap<AddressKeyValueTrait>::Insert(pair); 194 MallocDirectChainedHashMap<AddressKeyValueTrait>::Insert(pair);
78 } 195 }
79 196
80 inline bool Lookup(const Key& key, Value* value) { 197 bool Lookup(const Key& key, Value* value) {
81 ASSERT(value != NULL); 198 ASSERT(value != NULL);
82 Pair* pair = MallocDirectChainedHashMap<AddressKeyValueTrait>::Lookup(key); 199 Pair* pair = MallocDirectChainedHashMap<AddressKeyValueTrait>::Lookup(key);
83 if (pair == NULL) { 200 if (pair == NULL) {
84 return false; 201 return false;
85 } else { 202 } else {
86 *value = pair->value; 203 *value = pair->value;
87 return true; 204 return true;
88 } 205 }
89 } 206 }
90 };
91 207
92 208 void Clear() {
93 class MallocHooksState : public AllStatic { 209 Iterator iter = GetIterator();
94 public: 210 Pair* result = iter.Next();
95 static void RecordAllocHook(const void* ptr, size_t size); 211 while (result != NULL) {
96 static void RecordFreeHook(const void* ptr); 212 delete result->value;
97 213 result->value = NULL;
98 static bool Active() { return active_; } 214 result = iter.Next();
99 static void Init() { 215 }
100 address_map_ = new AddressMap(); 216 MallocDirectChainedHashMap<AddressKeyValueTrait>::Clear();
101 active_ = true;
102 original_pid_ = OS::ProcessId();
103 } 217 }
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;
167 }; 218 };
168 219
169 220
170 // MallocHooks state / locks. 221 // MallocHooks state / locks.
171 bool MallocHooksState::active_ = false; 222 bool MallocHooksState::active_ = false;
223 bool MallocHooksState::stack_trace_collection_enabled_ = false;
172 intptr_t MallocHooksState::original_pid_ = MallocHooksState::kInvalidPid; 224 intptr_t MallocHooksState::original_pid_ = MallocHooksState::kInvalidPid;
173 Mutex* MallocHooksState::malloc_hook_mutex_ = new Mutex(); 225 Mutex* MallocHooksState::malloc_hook_mutex_ = new Mutex();
174 ThreadId MallocHooksState::malloc_hook_mutex_owner_ = 226 ThreadId MallocHooksState::malloc_hook_mutex_owner_ =
175 OSThread::kInvalidThreadId; 227 OSThread::kInvalidThreadId;
176 228
177 // Memory allocation state information. 229 // Memory allocation state information.
178 intptr_t MallocHooksState::allocation_count_ = 0; 230 intptr_t MallocHooksState::allocation_count_ = 0;
179 intptr_t MallocHooksState::heap_allocated_memory_in_bytes_ = 0; 231 intptr_t MallocHooksState::heap_allocated_memory_in_bytes_ = 0;
180 AddressMap* MallocHooksState::address_map_ = NULL; 232 AddressMap* MallocHooksState::address_map_ = NULL;
181 233
182 234
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
183 void MallocHooks::InitOnce() { 265 void MallocHooks::InitOnce() {
184 if (!FLAG_enable_malloc_hooks) { 266 if (!FLAG_enable_malloc_hooks) {
185 return; 267 return;
186 } 268 }
187 MallocLocker ml(MallocHooksState::malloc_hook_mutex(), 269 MallocLocker ml(MallocHooksState::malloc_hook_mutex(),
188 MallocHooksState::malloc_hook_mutex_owner()); 270 MallocHooksState::malloc_hook_mutex_owner());
189 ASSERT(!MallocHooksState::Active()); 271 ASSERT(!MallocHooksState::Active());
190 272
191 MallocHooksState::Init(); 273 MallocHooksState::Init();
192 274
(...skipping 18 matching lines...) Expand all
211 bool success = false; 293 bool success = false;
212 success = MallocHook::RemoveNewHook(&MallocHooksState::RecordAllocHook); 294 success = MallocHook::RemoveNewHook(&MallocHooksState::RecordAllocHook);
213 ASSERT(success); 295 ASSERT(success);
214 success = MallocHook::RemoveDeleteHook(&MallocHooksState::RecordFreeHook); 296 success = MallocHook::RemoveDeleteHook(&MallocHooksState::RecordFreeHook);
215 ASSERT(success); 297 ASSERT(success);
216 298
217 MallocHooksState::TearDown(); 299 MallocHooksState::TearDown();
218 } 300 }
219 301
220 302
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
221 void MallocHooks::ResetStats() { 322 void MallocHooks::ResetStats() {
222 if (!FLAG_enable_malloc_hooks) { 323 if (!FLAG_enable_malloc_hooks) {
223 return; 324 return;
224 } 325 }
225 MallocLocker ml(MallocHooksState::malloc_hook_mutex(), 326 MallocLocker ml(MallocHooksState::malloc_hook_mutex(),
226 MallocHooksState::malloc_hook_mutex_owner()); 327 MallocHooksState::malloc_hook_mutex_owner());
227 if (MallocHooksState::Active()) { 328 if (MallocHooksState::Active()) {
228 MallocHooksState::ResetStats(); 329 MallocHooksState::ResetStats();
229 } 330 }
230 } 331 }
231 332
232 333
233 bool MallocHooks::Active() { 334 bool MallocHooks::Active() {
234 if (!FLAG_enable_malloc_hooks) { 335 if (!FLAG_enable_malloc_hooks) {
235 return false; 336 return false;
236 } 337 }
237 ASSERT(MallocHooksState::malloc_hook_mutex()->IsOwnedByCurrentThread()); 338 MallocLocker ml(MallocHooksState::malloc_hook_mutex(),
339 MallocHooksState::malloc_hook_mutex_owner());
340
238 return MallocHooksState::Active(); 341 return MallocHooksState::Active();
239 } 342 }
240 343
241 344
242 void MallocHooks::PrintToJSONObject(JSONObject* jsobj) { 345 void MallocHooks::PrintToJSONObject(JSONObject* jsobj) {
243 if (!FLAG_enable_malloc_hooks) { 346 if (!FLAG_enable_malloc_hooks) {
244 return; 347 return;
245 } 348 }
246 intptr_t allocated_memory = 0; 349 intptr_t allocated_memory = 0;
247 intptr_t allocation_count = 0; 350 intptr_t allocation_count = 0;
248 bool add_usage = false; 351 bool add_usage = false;
249 // AddProperty may call malloc which would result in an attempt 352 // AddProperty may call malloc which would result in an attempt
250 // to acquire the lock recursively so we extract the values first 353 // to acquire the lock recursively so we extract the values first
251 // and then add the JSON properties. 354 // and then add the JSON properties.
252 { 355 {
253 MallocLocker ml(MallocHooksState::malloc_hook_mutex(), 356 MallocLocker ml(MallocHooksState::malloc_hook_mutex(),
254 MallocHooksState::malloc_hook_mutex_owner()); 357 MallocHooksState::malloc_hook_mutex_owner());
255 if (Active()) { 358 if (MallocHooksState::Active()) {
256 allocated_memory = MallocHooksState::heap_allocated_memory_in_bytes(); 359 allocated_memory = MallocHooksState::heap_allocated_memory_in_bytes();
257 allocation_count = MallocHooksState::allocation_count(); 360 allocation_count = MallocHooksState::allocation_count();
258 add_usage = true; 361 add_usage = true;
259 } 362 }
260 } 363 }
261 if (add_usage) { 364 if (add_usage) {
262 jsobj->AddProperty("_heapAllocatedMemoryUsage", allocated_memory); 365 jsobj->AddProperty("_heapAllocatedMemoryUsage", allocated_memory);
263 jsobj->AddProperty("_heapAllocationCount", allocation_count); 366 jsobj->AddProperty("_heapAllocationCount", allocation_count);
264 } 367 }
265 } 368 }
(...skipping 12 matching lines...) Expand all
278 intptr_t MallocHooks::heap_allocated_memory_in_bytes() { 381 intptr_t MallocHooks::heap_allocated_memory_in_bytes() {
279 if (!FLAG_enable_malloc_hooks) { 382 if (!FLAG_enable_malloc_hooks) {
280 return 0; 383 return 0;
281 } 384 }
282 MallocLocker ml(MallocHooksState::malloc_hook_mutex(), 385 MallocLocker ml(MallocHooksState::malloc_hook_mutex(),
283 MallocHooksState::malloc_hook_mutex_owner()); 386 MallocHooksState::malloc_hook_mutex_owner());
284 return MallocHooksState::heap_allocated_memory_in_bytes(); 387 return MallocHooksState::heap_allocated_memory_in_bytes();
285 } 388 }
286 389
287 390
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
288 void MallocHooksState::RecordAllocHook(const void* ptr, size_t size) { 408 void MallocHooksState::RecordAllocHook(const void* ptr, size_t size) {
289 if (MallocHooksState::IsLockHeldByCurrentThread() || 409 if (MallocHooksState::IsLockHeldByCurrentThread() ||
290 !MallocHooksState::IsOriginalProcess()) { 410 !MallocHooksState::IsOriginalProcess()) {
291 return; 411 return;
292 } 412 }
293 413
294 MallocLocker ml(MallocHooksState::malloc_hook_mutex(), 414 MallocLocker ml(MallocHooksState::malloc_hook_mutex(),
295 MallocHooksState::malloc_hook_mutex_owner()); 415 MallocHooksState::malloc_hook_mutex_owner());
296 // Now that we hold the lock, check to make sure everything is still active. 416 // Now that we hold the lock, check to make sure everything is still active.
297 if ((ptr != NULL) && MallocHooksState::Active()) { 417 if ((ptr != NULL) && MallocHooksState::Active()) {
298 MallocHooksState::IncrementHeapAllocatedMemoryInBytes(size); 418 MallocHooksState::IncrementHeapAllocatedMemoryInBytes(size);
299 MallocHooksState::address_map()->Insert(ptr, size); 419 MallocHooksState::address_map()->Insert(ptr, new AllocationInfo(size));
300 } 420 }
301 } 421 }
302 422
303 423
304 void MallocHooksState::RecordFreeHook(const void* ptr) { 424 void MallocHooksState::RecordFreeHook(const void* ptr) {
305 if (MallocHooksState::IsLockHeldByCurrentThread() || 425 if (MallocHooksState::IsLockHeldByCurrentThread() ||
306 !MallocHooksState::IsOriginalProcess()) { 426 !MallocHooksState::IsOriginalProcess()) {
307 return; 427 return;
308 } 428 }
309 429
310 MallocLocker ml(MallocHooksState::malloc_hook_mutex(), 430 MallocLocker ml(MallocHooksState::malloc_hook_mutex(),
311 MallocHooksState::malloc_hook_mutex_owner()); 431 MallocHooksState::malloc_hook_mutex_owner());
312 // Now that we hold the lock, check to make sure everything is still active. 432 // Now that we hold the lock, check to make sure everything is still active.
313 if ((ptr != NULL) && MallocHooksState::Active()) { 433 if ((ptr != NULL) && MallocHooksState::Active()) {
314 intptr_t size = 0; 434 AllocationInfo* allocation_info = NULL;
315 if (MallocHooksState::address_map()->Lookup(ptr, &size)) { 435 if (MallocHooksState::address_map()->Lookup(ptr, &allocation_info)) {
316 MallocHooksState::DecrementHeapAllocatedMemoryInBytes(size); 436 MallocHooksState::DecrementHeapAllocatedMemoryInBytes(
437 allocation_info->allocation_size());
317 MallocHooksState::address_map()->Remove(ptr); 438 MallocHooksState::address_map()->Remove(ptr);
439 delete allocation_info;
318 } 440 }
319 } 441 }
320 } 442 }
321 443
322 } // namespace dart 444 } // namespace dart
323 445
324 #endif // defined(DART_USE_TCMALLOC) && !defined(PRODUCT) 446 #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