Index: lib/sanitizer_common/sanitizer_allocator_primary32.h =================================================================== --- lib/sanitizer_common/sanitizer_allocator_primary32.h +++ lib/sanitizer_common/sanitizer_allocator_primary32.h @@ -106,6 +106,7 @@ void Init(s32 release_to_os_interval_ms) { possible_regions.TestOnlyInit(); internal_memset(size_class_info_array, 0, sizeof(size_class_info_array)); + num_stashed_regions = 0; } s32 ReleaseToOSIntervalMs() const { @@ -277,10 +278,41 @@ uptr AllocateRegion(AllocatorStats *stat, uptr class_id) { CHECK_LT(class_id, kNumClasses); - uptr res = reinterpret_cast(MmapAlignedOrDie(kRegionSize, kRegionSize, - "SizeClassAllocator32")); - MapUnmapCallback().OnMap(res, kRegionSize); - stat->Add(AllocatorStatMapped, kRegionSize); + uptr res = 0; + { + SpinMutexLock l(®ion_stash_mutex); + if (num_stashed_regions > 0) + res = regions_stash[--num_stashed_regions]; + } + if (!res) { + uptr map_size = 2 * kRegionSize; + uptr map_res = (uptr)MmapOrDie(map_size, "SizeClassAllocator32"); + uptr map_end = map_res + map_size; + res = map_res; + bool extra_region = false; + // If the result of the allocation is aligned, split it in two, and + // attempt to store the second part into the stash. If it's full, just + // unmap it. + if (IsAligned(res, kRegionSize)) { + SpinMutexLock l(®ion_stash_mutex); + if (num_stashed_regions < kMaxStashedRegions) { + regions_stash[num_stashed_regions++] = res + kRegionSize; + extra_region = true; + } + } else { + // We are not aligned, trim the memory in front of us. + res = (map_res + kRegionSize) & ~(kRegionSize - 1); + UnmapOrDie((void*)map_res, res - map_res); + } + if (!extra_region) { + // We have extra memory behind us, trim it. + uptr end = res + kRegionSize; + UnmapOrDie((void*)end, map_end - end); + map_size -= kRegionSize; + } + MapUnmapCallback().OnMap(res, map_size); + stat->Add(AllocatorStatMapped, map_size); + } CHECK_EQ(0U, (res & (kRegionSize - 1))); possible_regions.set(ComputeRegionId(res), static_cast(class_id)); return res; @@ -316,8 +348,11 @@ } } + static const uptr kMaxStashedRegions = 8; + SpinMutex region_stash_mutex; + uptr num_stashed_regions; + uptr regions_stash[kMaxStashedRegions]; + ByteMap possible_regions; SizeClassInfo size_class_info_array[kNumClasses]; }; - -