Chromium Code Reviews| Index: base/allocator/allocator_interception_mac.mm |
| diff --git a/base/allocator/allocator_interception_mac.mm b/base/allocator/allocator_interception_mac.mm |
| index e945a293beb58fbe36e9e4f2c17f1525293b28cc..f9c0dd676863362efaa3fc77e744acfb27c8b994 100644 |
| --- a/base/allocator/allocator_interception_mac.mm |
| +++ b/base/allocator/allocator_interception_mac.mm |
| @@ -28,6 +28,7 @@ |
| #include <new> |
| #include "base/allocator/allocator_shim.h" |
| +#include "base/allocator/allocator_shim_default_dispatch_to_mac_zoned_malloc.h" |
|
Primiano Tucci (use gerrit)
2017/02/22 12:25:39
What is this for? We shouldn't have cyclic logical
erikchen
2017/02/22 21:03:09
whoops, unnecessary include.
|
| #include "base/allocator/features.h" |
| #include "base/logging.h" |
| #include "base/mac/mac_util.h" |
| @@ -42,8 +43,6 @@ namespace allocator { |
| bool g_replaced_default_zone = false; |
| -MallocZoneFunctions::MallocZoneFunctions() {} |
| - |
| namespace { |
| bool g_oom_killer_enabled; |
| @@ -295,31 +294,6 @@ bool UncheckedCallocMac(size_t num_items, size_t size, void** result) { |
| return *result != NULL; |
| } |
| -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) { |
| - functions->memalign = zone->memalign; |
| - CHECK(functions->memalign); |
| - } |
| - if (zone->version >= 6) { |
| - // This may be nullptr. |
| - functions->free_definite_size = zone->free_definite_size; |
| - } |
| -} |
| - |
| void ReplaceZoneFunctions(ChromeMallocZone* zone, |
| const MallocZoneFunctions* functions) { |
| // Remove protection. |
| @@ -358,21 +332,45 @@ void ReplaceZoneFunctions(ChromeMallocZone* zone, |
| } |
| } |
| -void StoreFunctionsForDefaultZone(MallocZoneFunctions* functions) { |
| +void StoreFunctionsForDefaultZone(MallocZoneAggregator* aggregator) { |
| ChromeMallocZone* default_zone = reinterpret_cast<ChromeMallocZone*>( |
| malloc_default_zone()); |
| - StoreZoneFunctions(default_zone, functions); |
| + aggregator->StoreZone(default_zone); |
| +} |
| + |
| +void StoreFunctionsForAllZones(MallocZoneAggregator* aggregator) { |
| + // This ensures that the default zone is always at the front of the |
| + // aggregator, which is important for performance. |
| + StoreFunctionsForDefaultZone(aggregator); |
| + |
| + vm_address_t* zones; |
| + unsigned int count; |
| + kern_return_t kr = malloc_get_all_zones(mach_task_self(), 0, &zones, &count); |
| + if (kr != KERN_SUCCESS) |
| + return; |
| + for (unsigned int i = 0; i < count; ++i) { |
| + ChromeMallocZone* zone = reinterpret_cast<ChromeMallocZone*>(zones[i]); |
| + aggregator->StoreZone(zone); |
| + } |
| } |
| -void ReplaceFunctionsForDefaultZone(const MallocZoneFunctions* functions) { |
| - CHECK(!g_replaced_default_zone); |
| +void ReplaceFunctionsForStoredZones(const MallocZoneFunctions* functions) { |
| + vm_address_t* zones; |
| + unsigned int count; |
| + kern_return_t kr = malloc_get_all_zones(mach_task_self(), 0, &zones, &count); |
| + if (kr != KERN_SUCCESS) |
| + return; |
| + for (unsigned int i = 0; i < count; ++i) { |
| + ChromeMallocZone* zone = reinterpret_cast<ChromeMallocZone*>(zones[i]); |
| + if (!MallocZoneAggregator::GetMallocZoneAggregator()->IsZoneAlreadyStored( |
| + zone)) { |
| + continue; |
| + } |
| + if (zone->malloc == functions->malloc) |
| + continue; |
| + ReplaceZoneFunctions(zone, functions); |
| + } |
| g_replaced_default_zone = true; |
| -#if !defined(ADDRESS_SANITIZER) |
| - StoreFunctionsForDefaultZone(&g_old_zone); |
| -#endif |
| - ChromeMallocZone* default_zone = reinterpret_cast<ChromeMallocZone*>( |
| - malloc_default_zone()); |
| - ReplaceZoneFunctions(default_zone, functions); |
| } |
| void InterceptAllocationsMac() { |
| @@ -393,8 +391,11 @@ void InterceptAllocationsMac() { |
| #if !defined(ADDRESS_SANITIZER) |
| // Don't do anything special on OOM for the malloc zones replaced by |
| // AddressSanitizer, as modifying or protecting them may not work correctly. |
| - if (!g_replaced_default_zone) { |
| - StoreFunctionsForDefaultZone(&g_old_zone); |
| + ChromeMallocZone* default_zone = |
| + reinterpret_cast<ChromeMallocZone*>(malloc_default_zone()); |
| + if (!MallocZoneAggregator::GetMallocZoneAggregator()->IsZoneAlreadyStored( |
| + default_zone)) { |
| + StoreZoneFunctions(default_zone, &g_old_zone); |
| MallocZoneFunctions new_functions; |
| new_functions.malloc = oom_killer_malloc; |
| new_functions.calloc = oom_killer_calloc; |
| @@ -402,12 +403,16 @@ void InterceptAllocationsMac() { |
| new_functions.free = oom_killer_free; |
| new_functions.realloc = oom_killer_realloc; |
| new_functions.memalign = oom_killer_memalign; |
| - ReplaceFunctionsForDefaultZone(&new_functions); |
| + |
| + ReplaceZoneFunctions(default_zone, &new_functions); |
| + g_replaced_default_zone = true; |
| } |
| ChromeMallocZone* purgeable_zone = |
| reinterpret_cast<ChromeMallocZone*>(malloc_default_purgeable_zone()); |
| - if (purgeable_zone) { |
| + if (purgeable_zone && |
| + !MallocZoneAggregator::GetMallocZoneAggregator()->IsZoneAlreadyStored( |
| + purgeable_zone)) { |
| StoreZoneFunctions(purgeable_zone, &g_old_purgeable_zone); |
| MallocZoneFunctions new_functions; |
| new_functions.malloc = oom_killer_malloc_purgeable; |