Chromium Code Reviews| Index: base/allocator/malloc_zone_functions_mac.cc |
| diff --git a/base/allocator/malloc_zone_functions_mac.cc b/base/allocator/malloc_zone_functions_mac.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..4277ee8a571e2e116e4793fef270cb2dc86bee54 |
| --- /dev/null |
| +++ b/base/allocator/malloc_zone_functions_mac.cc |
| @@ -0,0 +1,101 @@ |
| +// Copyright 2017 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "base/allocator/malloc_zone_functions_mac.h" |
| + |
| +#include "base/atomicops.h" |
| +#include "base/synchronization/lock.h" |
| + |
| +namespace base { |
| +namespace allocator { |
| + |
| +MallocZoneFunctions g_malloc_zones[kMaxZoneCount]; |
| +MallocZoneFunctions::MallocZoneFunctions() {} |
| + |
| +void StoreZoneFunctions(ChromeMallocZone* zone, |
| + MallocZoneFunctions* functions) { |
| + functions->malloc = zone->malloc; |
| + functions->calloc = zone->calloc; |
| + functions->valloc = zone->valloc; |
| + functions->free = zone->free; |
| + functions->realloc = zone->realloc; |
| + functions->size = zone->size; |
| + CHECK(functions->malloc && functions->calloc && functions->valloc && |
| + functions->free && functions->realloc && functions->size); |
| + |
| + // These functions might be nullptr. |
| + functions->batch_malloc = zone->batch_malloc; |
| + functions->batch_free = zone->batch_free; |
| + |
| + if (zone->version >= 5) { |
| + // Not all custom malloc zones have a memalign. |
| + functions->memalign = zone->memalign; |
| + } |
| + if (zone->version >= 6) { |
| + // This may be nullptr. |
| + functions->free_definite_size = zone->free_definite_size; |
| + } |
| + |
| + functions->context = zone; |
| +} |
| + |
| +namespace { |
| + |
| +// All modifications to g_malloc_zones are gated behind this lock. |
| +// Dispatch to a malloc zone does not need to acquire this lock. |
| +base::Lock* GetLock() { |
|
Primiano Tucci (use gerrit)
2017/02/23 00:40:18
do you really need all this locking here? Isn't ea
erikchen
2017/02/23 01:43:14
Actually, the new Task Scheduler doesn't guarantee
Primiano Tucci (use gerrit)
2017/02/23 11:19:41
Well depends wheteher you use SingleThreadTaskRunn
erikchen
2017/02/23 20:06:44
There's no way to guarantee things happen on a sin
Primiano Tucci (use gerrit)
2017/02/23 21:06:07
ThreadChecker (and SequenceChecker) have zero cost
|
| + static base::Lock* g_lock = new base::Lock; |
| + return g_lock; |
| +} |
| + |
| +int g_zone_count = 0; |
| +bool g_zeroed = false; |
| + |
| +bool IsMallocZoneAlreadyStoredLockAcquired(ChromeMallocZone* zone) { |
|
Primiano Tucci (use gerrit)
2017/02/23 00:40:18
I think the naming pattern in the rest of the code
erikchen
2017/02/23 01:43:14
Done.
|
| + GetLock()->AssertAcquired(); |
| + for (int i = 0; i < g_zone_count; ++i) { |
| + if (g_malloc_zones[i].context == reinterpret_cast<void*>(zone)) |
| + return true; |
| + } |
| + return false; |
| +} |
| + |
| +} // namespace |
| + |
| +void StoreMallocZone(ChromeMallocZone* zone) { |
| + base::AutoLock l(*GetLock()); |
| + if (!g_zeroed) { |
| + g_zeroed = true; |
| + memset(g_malloc_zones, 0, sizeof(g_malloc_zones)); |
|
Primiano Tucci (use gerrit)
2017/02/23 00:40:18
why you need this? global structs and pods are zer
erikchen
2017/02/23 01:43:14
This isn't pod. Notice that MallocZoneFunctions ha
Primiano Tucci (use gerrit)
2017/02/23 11:19:41
Uhm, this means that g_malloc_zones will likely ca
erikchen
2017/02/23 20:06:44
1. Our custom clang module forces us to make a def
Primiano Tucci (use gerrit)
2017/02/23 21:06:07
Alright I see, there seems to be a problem in our
|
| + } |
| + if (IsMallocZoneAlreadyStoredLockAcquired(zone)) |
| + return; |
| + |
| + if (g_zone_count == kMaxZoneCount) |
| + return; |
| + |
| + StoreZoneFunctions(zone, &g_malloc_zones[g_zone_count]); |
| + ++g_zone_count; |
| + base::subtle::MemoryBarrier(); |
|
Primiano Tucci (use gerrit)
2017/02/23 00:40:18
This memory barrier is not enough in theory and is
erikchen
2017/02/23 01:43:14
Sorry, but I disagree on both points. Comments in
Primiano Tucci (use gerrit)
2017/02/23 11:19:41
No need to be sorry :)
Primiano Tucci (use gerrit)
2017/02/23 17:47:16
Erik and I had a chat offline, summarizing here.
T
|
| +} |
| + |
| +bool IsMallocZoneAlreadyStored(ChromeMallocZone* zone) { |
| + base::AutoLock l(*GetLock()); |
| + return IsMallocZoneAlreadyStoredLockAcquired(zone); |
| +} |
| + |
| +int GetMallocZoneCountForTesting() { |
| + base::AutoLock l(*GetLock()); |
| + return g_zone_count; |
| +} |
| + |
| +void ClearAllMallocZonesForTesting() { |
| + base::AutoLock l(*GetLock()); |
| + memset(g_malloc_zones, 0, sizeof(g_malloc_zones)); |
| + g_zone_count = 0; |
| + g_zeroed = false; |
|
Primiano Tucci (use gerrit)
2017/02/23 00:40:18
as per the comment above I don't think you need th
erikchen
2017/02/23 01:43:14
removed.
|
| +} |
| + |
| +} // namespace allocator |
| +} // namespace base |