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

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

Issue 2718523003: Fixed issue in MallocHooks where a MallocHookScope was accidentally removed during a merge, causing… (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
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/lockers.h" 17 #include "vm/lockers.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
54 static intptr_t allocation_count() { return allocation_count_; }
55
56 static intptr_t heap_allocated_memory_in_bytes() {
57 return heap_allocated_memory_in_bytes_;
58 }
59
60 static void IncrementHeapAllocatedMemoryInBytes(intptr_t size) {
61 ASSERT(malloc_hook_mutex()->IsOwnedByCurrentThread());
62 ASSERT(size >= 0);
63 heap_allocated_memory_in_bytes_ += size;
64 ++allocation_count_;
65 }
66
67 static void DecrementHeapAllocatedMemoryInBytes(intptr_t size) {
68 ASSERT(malloc_hook_mutex()->IsOwnedByCurrentThread());
69 ASSERT(size >= 0);
70 ASSERT(heap_allocated_memory_in_bytes_ >= size);
71 heap_allocated_memory_in_bytes_ -= size;
72 --allocation_count_;
73 ASSERT(allocation_count_ >= 0);
74 }
75
76 static AddressMap* address_map() { return address_map_; }
77
78 static void ResetStats();
79 static void TearDown();
80
81 private:
82 static Mutex* malloc_hook_mutex_;
83
84 // Variables protected by malloc_hook_mutex_.
85 static bool active_;
86 static bool stack_trace_collection_enabled_;
87 static intptr_t allocation_count_;
88 static intptr_t heap_allocated_memory_in_bytes_;
89 static AddressMap* address_map_;
90 // End protected variables.
91
92 static intptr_t original_pid_;
93 static const intptr_t kInvalidPid = -1;
94 };
95
20 // A locker-type class to automatically grab and release the 96 // A locker-type class to automatically grab and release the
21 // in_malloc_hook_flag_. 97 // in_malloc_hook_flag_.
22 class MallocHookScope { 98 class MallocHookScope {
23 public: 99 public:
24 static void InitMallocHookFlag() { 100 static void InitMallocHookFlag() {
25 MutexLocker ml(malloc_hook_scope_mutex_); 101 MutexLocker ml(malloc_hook_scope_mutex_);
26 ASSERT(in_malloc_hook_flag_ == kUnsetThreadLocalKey); 102 ASSERT(in_malloc_hook_flag_ == kUnsetThreadLocalKey);
27 in_malloc_hook_flag_ = OSThread::CreateThreadLocal(); 103 in_malloc_hook_flag_ = OSThread::CreateThreadLocal();
28 OSThread::SetThreadLocal(in_malloc_hook_flag_, 0); 104 OSThread::SetThreadLocal(in_malloc_hook_flag_, 0);
29 } 105 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
62 } 138 }
63 139
64 private: 140 private:
65 static Mutex* malloc_hook_scope_mutex_; 141 static Mutex* malloc_hook_scope_mutex_;
66 static ThreadLocalKey in_malloc_hook_flag_; 142 static ThreadLocalKey in_malloc_hook_flag_;
67 143
68 DISALLOW_ALLOCATION(); 144 DISALLOW_ALLOCATION();
69 DISALLOW_COPY_AND_ASSIGN(MallocHookScope); 145 DISALLOW_COPY_AND_ASSIGN(MallocHookScope);
70 }; 146 };
71 147
148 // AllocationInfo contains all information related to a given allocation
149 // including:
150 // -Allocation size in bytes
151 // -Stack trace corresponding to the location of allocation, if applicable
152 class AllocationInfo {
153 public:
154 explicit AllocationInfo(intptr_t allocation_size)
155 : sample_(NULL), allocation_size_(allocation_size) {
156 // Stack trace collection is disabled when we are in the process of creating
157 // the first OSThread in order to prevent deadlocks.
158 if (MallocHooksState::ProfilingEnabled() &&
159 MallocHooksState::stack_trace_collection_enabled()) {
160 sample_ = Profiler::SampleNativeAllocation(kSkipCount);
161 }
162 }
163
164 Sample* sample() const { return sample_; }
165 intptr_t allocation_size() const { return allocation_size_; }
166
167 private:
168 Sample* sample_;
169 intptr_t allocation_size_;
170
171 // The number of frames that are generated by the malloc hooks and collection
172 // of the stack trace. These frames are ignored when collecting the stack
173 // trace for a memory allocation. If this number is incorrect, some tests in
174 // malloc_hook_tests.cc might fail, particularily
175 // StackTraceMallocHookLengthTest. If this value is updated, please make sure
176 // that the MallocHooks test cases pass on all platforms.
177 static const intptr_t kSkipCount = 5;
178 };
179
72 180
73 // Custom key/value trait specifically for address/size pairs. Unlike 181 // Custom key/value trait specifically for address/size pairs. Unlike
74 // RawPointerKeyValueTrait, the default value is -1 as 0 can be a valid entry. 182 // RawPointerKeyValueTrait, the default value is -1 as 0 can be a valid entry.
75 class AddressKeyValueTrait { 183 class AddressKeyValueTrait : public AllStatic {
76 public: 184 public:
77 typedef const void* Key; 185 typedef const void* Key;
78 typedef intptr_t Value; 186 typedef AllocationInfo* Value;
79 187
80 struct Pair { 188 struct Pair {
81 Key key; 189 Key key;
82 Value value; 190 Value value;
83 Pair() : key(NULL), value(-1) {} 191 Pair() : key(NULL), value(NULL) {}
84 Pair(const Key key, const Value& value) : key(key), value(value) {} 192 Pair(const Key key, const Value& value) : key(key), value(value) {}
85 Pair(const Pair& other) : key(other.key), value(other.value) {} 193 Pair(const Pair& other) : key(other.key), value(other.value) {}
86 }; 194 };
87 195
88 static Key KeyOf(Pair kv) { return kv.key; } 196 static Key KeyOf(Pair kv) { return kv.key; }
89 static Value ValueOf(Pair kv) { return kv.value; } 197 static Value ValueOf(Pair kv) { return kv.value; }
90 static intptr_t Hashcode(Key key) { return reinterpret_cast<intptr_t>(key); } 198 static intptr_t Hashcode(Key key) { return reinterpret_cast<intptr_t>(key); }
91 static bool IsKeyEqual(Pair kv, Key key) { return kv.key == key; } 199 static bool IsKeyEqual(Pair kv, Key key) { return kv.key == key; }
92 }; 200 };
93 201
94 202
95 // Map class that will be used to store mappings between ptr -> allocation size. 203 // Map class that will be used to store mappings between ptr -> allocation size.
96 class AddressMap : public MallocDirectChainedHashMap<AddressKeyValueTrait> { 204 class AddressMap : public MallocDirectChainedHashMap<AddressKeyValueTrait> {
97 public: 205 public:
98 typedef AddressKeyValueTrait::Key Key; 206 typedef AddressKeyValueTrait::Key Key;
99 typedef AddressKeyValueTrait::Value Value; 207 typedef AddressKeyValueTrait::Value Value;
100 typedef AddressKeyValueTrait::Pair Pair; 208 typedef AddressKeyValueTrait::Pair Pair;
101 209
102 inline void Insert(const Key& key, const Value& value) { 210 virtual ~AddressMap() { Clear(); }
211
212 void Insert(const Key& key, const Value& value) {
103 Pair pair(key, value); 213 Pair pair(key, value);
104 MallocDirectChainedHashMap<AddressKeyValueTrait>::Insert(pair); 214 MallocDirectChainedHashMap<AddressKeyValueTrait>::Insert(pair);
105 } 215 }
106 216
107 inline bool Lookup(const Key& key, Value* value) { 217 bool Lookup(const Key& key, Value* value) {
108 ASSERT(value != NULL); 218 ASSERT(value != NULL);
109 Pair* pair = MallocDirectChainedHashMap<AddressKeyValueTrait>::Lookup(key); 219 Pair* pair = MallocDirectChainedHashMap<AddressKeyValueTrait>::Lookup(key);
110 if (pair == NULL) { 220 if (pair == NULL) {
111 return false; 221 return false;
112 } else { 222 } else {
113 *value = pair->value; 223 *value = pair->value;
114 return true; 224 return true;
115 } 225 }
116 } 226 }
227
228 void Clear() {
229 Iterator iter = GetIterator();
230 Pair* result = iter.Next();
231 while (result != NULL) {
232 delete result->value;
233 result->value = NULL;
234 result = iter.Next();
235 }
236 MallocDirectChainedHashMap<AddressKeyValueTrait>::Clear();
237 }
117 }; 238 };
118 239
119 240
120 class MallocHooksState : public AllStatic {
121 public:
122 static void RecordAllocHook(const void* ptr, size_t size);
123 static void RecordFreeHook(const void* ptr);
124
125 static bool Active() { return active_; }
126 static void Init() {
127 address_map_ = new AddressMap();
128 active_ = true;
129 original_pid_ = OS::ProcessId();
130 }
131
132 static bool IsOriginalProcess() {
133 ASSERT(original_pid_ != kInvalidPid);
134 return original_pid_ == OS::ProcessId();
135 }
136
137 static Mutex* malloc_hook_mutex() { return malloc_hook_mutex_; }
138
139 static intptr_t allocation_count() { return allocation_count_; }
140
141 static intptr_t heap_allocated_memory_in_bytes() {
142 return heap_allocated_memory_in_bytes_;
143 }
144
145 static void IncrementHeapAllocatedMemoryInBytes(intptr_t size) {
146 ASSERT(malloc_hook_mutex()->IsOwnedByCurrentThread());
147 ASSERT(size >= 0);
148 heap_allocated_memory_in_bytes_ += size;
149 ++allocation_count_;
150 }
151
152 static void DecrementHeapAllocatedMemoryInBytes(intptr_t size) {
153 ASSERT(malloc_hook_mutex()->IsOwnedByCurrentThread());
154 ASSERT(size >= 0);
155 ASSERT(heap_allocated_memory_in_bytes_ >= size);
156 heap_allocated_memory_in_bytes_ -= size;
157 --allocation_count_;
158 ASSERT(allocation_count_ >= 0);
159 }
160
161 static AddressMap* address_map() { return address_map_; }
162
163 static void ResetStats() {
164 ASSERT(malloc_hook_mutex()->IsOwnedByCurrentThread());
165 allocation_count_ = 0;
166 heap_allocated_memory_in_bytes_ = 0;
167 address_map_->Clear();
168 }
169
170 static void TearDown() {
171 ASSERT(malloc_hook_mutex()->IsOwnedByCurrentThread());
172 active_ = false;
173 original_pid_ = kInvalidPid;
174 ResetStats();
175 delete address_map_;
176 }
177
178 private:
179 static bool active_;
180 static intptr_t original_pid_;
181 static Mutex* malloc_hook_mutex_;
182 static intptr_t allocation_count_;
183 static intptr_t heap_allocated_memory_in_bytes_;
184 static AddressMap* address_map_;
185
186 static const intptr_t kInvalidPid = -1;
187 };
188
189
190 // MallocHookScope state. 241 // MallocHookScope state.
191 Mutex* MallocHookScope::malloc_hook_scope_mutex_ = new Mutex(); 242 Mutex* MallocHookScope::malloc_hook_scope_mutex_ = new Mutex();
192 ThreadLocalKey MallocHookScope::in_malloc_hook_flag_ = kUnsetThreadLocalKey; 243 ThreadLocalKey MallocHookScope::in_malloc_hook_flag_ = kUnsetThreadLocalKey;
193 244
194 // MallocHooks state / locks. 245 // MallocHooks state / locks.
195 bool MallocHooksState::active_ = false; 246 bool MallocHooksState::active_ = false;
247 bool MallocHooksState::stack_trace_collection_enabled_ = false;
196 intptr_t MallocHooksState::original_pid_ = MallocHooksState::kInvalidPid; 248 intptr_t MallocHooksState::original_pid_ = MallocHooksState::kInvalidPid;
197 Mutex* MallocHooksState::malloc_hook_mutex_ = new Mutex(); 249 Mutex* MallocHooksState::malloc_hook_mutex_ = new Mutex();
198 250
199 // Memory allocation state information. 251 // Memory allocation state information.
200 intptr_t MallocHooksState::allocation_count_ = 0; 252 intptr_t MallocHooksState::allocation_count_ = 0;
201 intptr_t MallocHooksState::heap_allocated_memory_in_bytes_ = 0; 253 intptr_t MallocHooksState::heap_allocated_memory_in_bytes_ = 0;
202 AddressMap* MallocHooksState::address_map_ = NULL; 254 AddressMap* MallocHooksState::address_map_ = NULL;
203 255
204 256
257 void MallocHooksState::Init() {
258 address_map_ = new AddressMap();
259 active_ = true;
260 #if defined(DEBUG)
261 stack_trace_collection_enabled_ = true;
262 #else
263 stack_trace_collection_enabled_ = false;
264 #endif // defined(DEBUG)
265 original_pid_ = OS::ProcessId();
266 }
267
268
269 void MallocHooksState::ResetStats() {
270 ASSERT(malloc_hook_mutex()->IsOwnedByCurrentThread());
271 allocation_count_ = 0;
272 heap_allocated_memory_in_bytes_ = 0;
273 address_map_->Clear();
274 }
275
276
277 void MallocHooksState::TearDown() {
278 ASSERT(malloc_hook_mutex()->IsOwnedByCurrentThread());
279 active_ = false;
280 original_pid_ = kInvalidPid;
281 ResetStats();
282 delete address_map_;
283 address_map_ = NULL;
284 }
285
286
205 void MallocHooks::InitOnce() { 287 void MallocHooks::InitOnce() {
206 if (!FLAG_enable_malloc_hooks) { 288 if (!FLAG_enable_malloc_hooks) {
207 return; 289 return;
208 } 290 }
209 MutexLocker ml(MallocHooksState::malloc_hook_mutex()); 291 MutexLocker ml(MallocHooksState::malloc_hook_mutex());
210 ASSERT(!MallocHooksState::Active()); 292 ASSERT(!MallocHooksState::Active());
211 293
212 MallocHookScope::InitMallocHookFlag(); 294 MallocHookScope::InitMallocHookFlag();
213 MallocHooksState::Init(); 295 MallocHooksState::Init();
214 296
(...skipping 18 matching lines...) Expand all
233 success = MallocHook::RemoveNewHook(&MallocHooksState::RecordAllocHook); 315 success = MallocHook::RemoveNewHook(&MallocHooksState::RecordAllocHook);
234 ASSERT(success); 316 ASSERT(success);
235 success = MallocHook::RemoveDeleteHook(&MallocHooksState::RecordFreeHook); 317 success = MallocHook::RemoveDeleteHook(&MallocHooksState::RecordFreeHook);
236 ASSERT(success); 318 ASSERT(success);
237 319
238 MallocHooksState::TearDown(); 320 MallocHooksState::TearDown();
239 MallocHookScope::DestroyMallocHookFlag(); 321 MallocHookScope::DestroyMallocHookFlag();
240 } 322 }
241 323
242 324
325 bool MallocHooks::ProfilingEnabled() {
326 return MallocHooksState::ProfilingEnabled();
327 }
328
329
330 bool MallocHooks::stack_trace_collection_enabled() {
331 MutexLocker ml(MallocHooksState::malloc_hook_mutex());
332 return MallocHooksState::stack_trace_collection_enabled();
333 }
334
335
336 void MallocHooks::set_stack_trace_collection_enabled(bool enabled) {
337 MutexLocker ml(MallocHooksState::malloc_hook_mutex());
338 MallocHooksState::set_stack_trace_collection_enabled(enabled);
339 }
340
341
243 void MallocHooks::ResetStats() { 342 void MallocHooks::ResetStats() {
244 if (!FLAG_enable_malloc_hooks) { 343 if (!FLAG_enable_malloc_hooks) {
245 return; 344 return;
246 } 345 }
346 // Set the malloc hook flag before completing the reset since ResetStats()
347 // frees memory.
348 MallocHookScope mhs;
247 MutexLocker ml(MallocHooksState::malloc_hook_mutex()); 349 MutexLocker ml(MallocHooksState::malloc_hook_mutex());
248 if (MallocHooksState::Active()) { 350 if (MallocHooksState::Active()) {
249 MallocHooksState::ResetStats(); 351 MallocHooksState::ResetStats();
250 } 352 }
251 } 353 }
252 354
253 355
254 bool MallocHooks::Active() { 356 bool MallocHooks::Active() {
255 if (!FLAG_enable_malloc_hooks) { 357 if (!FLAG_enable_malloc_hooks) {
256 return false; 358 return false;
257 } 359 }
258 ASSERT(MallocHooksState::malloc_hook_mutex()->IsOwnedByCurrentThread()); 360 MutexLocker ml(MallocHooksState::malloc_hook_mutex());
259 return MallocHooksState::Active(); 361 return MallocHooksState::Active();
260 } 362 }
261 363
262 364
263 void MallocHooks::PrintToJSONObject(JSONObject* jsobj) { 365 void MallocHooks::PrintToJSONObject(JSONObject* jsobj) {
264 if (!FLAG_enable_malloc_hooks) { 366 if (!FLAG_enable_malloc_hooks) {
265 return; 367 return;
266 } 368 }
267 intptr_t allocated_memory = 0; 369 intptr_t allocated_memory = 0;
268 intptr_t allocation_count = 0; 370 intptr_t allocation_count = 0;
269 bool add_usage = false; 371 bool add_usage = false;
270 // AddProperty may call malloc which would result in an attempt 372 // AddProperty may call malloc which would result in an attempt
271 // to acquire the lock recursively so we extract the values first 373 // to acquire the lock recursively so we extract the values first
272 // and then add the JSON properties. 374 // and then add the JSON properties.
273 { 375 {
274 MutexLocker ml(MallocHooksState::malloc_hook_mutex()); 376 MutexLocker ml(MallocHooksState::malloc_hook_mutex());
275 if (Active()) { 377 if (MallocHooksState::Active()) {
276 allocated_memory = MallocHooksState::heap_allocated_memory_in_bytes(); 378 allocated_memory = MallocHooksState::heap_allocated_memory_in_bytes();
277 allocation_count = MallocHooksState::allocation_count(); 379 allocation_count = MallocHooksState::allocation_count();
278 add_usage = true; 380 add_usage = true;
279 } 381 }
280 } 382 }
281 if (add_usage) { 383 if (add_usage) {
282 jsobj->AddProperty("_heapAllocatedMemoryUsage", allocated_memory); 384 jsobj->AddProperty("_heapAllocatedMemoryUsage", allocated_memory);
283 jsobj->AddProperty("_heapAllocationCount", allocation_count); 385 jsobj->AddProperty("_heapAllocationCount", allocation_count);
284 } 386 }
285 } 387 }
(...skipping 10 matching lines...) Expand all
296 398
297 intptr_t MallocHooks::heap_allocated_memory_in_bytes() { 399 intptr_t MallocHooks::heap_allocated_memory_in_bytes() {
298 if (!FLAG_enable_malloc_hooks) { 400 if (!FLAG_enable_malloc_hooks) {
299 return 0; 401 return 0;
300 } 402 }
301 MutexLocker ml(MallocHooksState::malloc_hook_mutex()); 403 MutexLocker ml(MallocHooksState::malloc_hook_mutex());
302 return MallocHooksState::heap_allocated_memory_in_bytes(); 404 return MallocHooksState::heap_allocated_memory_in_bytes();
303 } 405 }
304 406
305 407
408 Sample* MallocHooks::GetSample(const void* ptr) {
409 MutexLocker ml(MallocHooksState::malloc_hook_mutex());
410 ASSERT(MallocHooksState::Active());
411
412 if (ptr != NULL) {
413 AllocationInfo* allocation_info = NULL;
414 if (MallocHooksState::address_map()->Lookup(ptr, &allocation_info)) {
415 ASSERT(allocation_info != NULL);
416 return allocation_info->sample();
417 }
418 }
419 return NULL;
420 }
421
422
306 void MallocHooksState::RecordAllocHook(const void* ptr, size_t size) { 423 void MallocHooksState::RecordAllocHook(const void* ptr, size_t size) {
307 if (MallocHookScope::IsInHook() || !MallocHooksState::IsOriginalProcess()) { 424 if (MallocHookScope::IsInHook() || !MallocHooksState::IsOriginalProcess()) {
308 return; 425 return;
309 } 426 }
310 427
311 MutexLocker ml(MallocHooksState::malloc_hook_mutex()); 428 MutexLocker ml(MallocHooksState::malloc_hook_mutex());
312 // Now that we hold the lock, check to make sure everything is still active. 429 // Now that we hold the lock, check to make sure everything is still active.
313 if ((ptr != NULL) && MallocHooksState::Active()) { 430 if ((ptr != NULL) && MallocHooksState::Active()) {
314 // Set the malloc hook flag to avoid calling hooks again if memory is 431 // Set the malloc hook flag to avoid calling hooks again if memory is
315 // allocated/freed below. 432 // allocated/freed below.
316 MallocHookScope mhs; 433 MallocHookScope mhs;
317 MallocHooksState::IncrementHeapAllocatedMemoryInBytes(size); 434 MallocHooksState::IncrementHeapAllocatedMemoryInBytes(size);
318 MallocHooksState::address_map()->Insert(ptr, size); 435 MallocHooksState::address_map()->Insert(ptr, new AllocationInfo(size));
319 } 436 }
320 } 437 }
321 438
322 439
323 void MallocHooksState::RecordFreeHook(const void* ptr) { 440 void MallocHooksState::RecordFreeHook(const void* ptr) {
324 if (MallocHookScope::IsInHook() || !MallocHooksState::IsOriginalProcess()) { 441 if (MallocHookScope::IsInHook() || !MallocHooksState::IsOriginalProcess()) {
325 return; 442 return;
326 } 443 }
327 444
328 MutexLocker ml(MallocHooksState::malloc_hook_mutex()); 445 MutexLocker ml(MallocHooksState::malloc_hook_mutex());
329 // Now that we hold the lock, check to make sure everything is still active. 446 // Now that we hold the lock, check to make sure everything is still active.
330 if ((ptr != NULL) && MallocHooksState::Active()) { 447 if ((ptr != NULL) && MallocHooksState::Active()) {
331 // Set the malloc hook flag to avoid calling hooks again if memory is 448 AllocationInfo* allocation_info = NULL;
332 // allocated/freed below. 449 if (MallocHooksState::address_map()->Lookup(ptr, &allocation_info)) {
333 MallocHookScope mhs; 450 MallocHookScope mhs;
bkonyi 2017/02/23 21:37:04 Note: This MallocHookScope was accidentally remove
334 intptr_t size = 0; 451 MallocHooksState::DecrementHeapAllocatedMemoryInBytes(
335 if (MallocHooksState::address_map()->Lookup(ptr, &size)) { 452 allocation_info->allocation_size());
336 MallocHooksState::DecrementHeapAllocatedMemoryInBytes(size);
337 MallocHooksState::address_map()->Remove(ptr); 453 MallocHooksState::address_map()->Remove(ptr);
454 delete allocation_info;
338 } 455 }
339 } 456 }
340 } 457 }
341 458
342 } // namespace dart 459 } // namespace dart
343 460
344 #endif // defined(DART_USE_TCMALLOC) && !defined(PRODUCT) 461 #endif // defined(DART_USE_TCMALLOC) && !defined(PRODUCT) &&
462 // !defined(TARGET_ARCH_DBC) && !defined(TARGET_OS_FUCHSIA)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698