diff options
| author | Kostya Serebryany <kcc@google.com> | 2013-03-15 11:39:41 +0000 |
|---|---|---|
| committer | Kostya Serebryany <kcc@google.com> | 2013-03-15 11:39:41 +0000 |
| commit | b941a2fca425eedecf1f0095afed732d68f60057 (patch) | |
| tree | 7ba7c0adde4dedf63bd2ca43924e915608c84551 /compiler-rt/lib/sanitizer_common/sanitizer_allocator.h | |
| parent | cdd46d9ccc646a1847e38dea4722f22dfaa4c535 (diff) | |
| download | bcm5719-llvm-b941a2fca425eedecf1f0095afed732d68f60057.tar.gz bcm5719-llvm-b941a2fca425eedecf1f0095afed732d68f60057.zip | |
[asan] Add ForEachChunk() to sanitizer allocators. Patch by Sergey Matveev
llvm-svn: 177147
Diffstat (limited to 'compiler-rt/lib/sanitizer_common/sanitizer_allocator.h')
| -rw-r--r-- | compiler-rt/lib/sanitizer_common/sanitizer_allocator.h | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_allocator.h b/compiler-rt/lib/sanitizer_common/sanitizer_allocator.h index eb7e45bd40c..45c93da07ef 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_allocator.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_allocator.h @@ -433,6 +433,24 @@ class SizeClassAllocator64 { } } + // Iterate over existing chunks. May include chunks that are not currently + // allocated to the user (e.g. freed). + // The caller is expected to call ForceLock() before calling this function. + template<typename Callable> + void ForEachChunk(const Callable &callback) { + for (uptr class_id = 1; class_id < kNumClasses; class_id++) { + RegionInfo *region = GetRegionInfo(class_id); + uptr chunk_size = SizeClassMap::Size(class_id); + uptr region_beg = kSpaceBeg + class_id * kRegionSize; + for (uptr p = region_beg; + p < region_beg + region->allocated_user; + p += chunk_size) { + // Too slow: CHECK_EQ((void *)p, GetBlockBegin((void *)p)); + callback((void *)p); + } + } + } + typedef SizeClassMap SizeClassMapT; static const uptr kNumClasses = SizeClassMap::kNumClasses; static const uptr kNumClassesRounded = SizeClassMap::kNumClassesRounded; @@ -681,6 +699,25 @@ class SizeClassAllocator32 { } } + // Iterate over existing chunks. May include chunks that are not currently + // allocated to the user (e.g. freed). + // The caller is expected to call ForceLock() before calling this function. + template<typename Callable> + void ForEachChunk(const Callable &callback) { + for (uptr region = 0; region < kNumPossibleRegions; region++) + if (state_->possible_regions[region]) { + uptr chunk_size = SizeClassMap::Size(state_->possible_regions[region]); + uptr max_chunks_in_region = kRegionSize / (chunk_size + kMetadataSize); + uptr region_beg = region * kRegionSize; + for (uptr p = region_beg; + p < region_beg + max_chunks_in_region * chunk_size; + p += chunk_size) { + // Too slow: CHECK_EQ((void *)p, GetBlockBegin((void *)p)); + callback((void *)p); + } + } + } + void PrintStats() { } @@ -1005,6 +1042,15 @@ class LargeMmapAllocator { mutex_.Unlock(); } + // Iterate over existing chunks. May include chunks that are not currently + // allocated to the user (e.g. freed). + // The caller is expected to call ForceLock() before calling this function. + template<typename Callable> + void ForEachChunk(const Callable &callback) { + for (uptr i = 0; i < n_chunks_; i++) + callback(GetUser(chunks_[i])); + } + private: static const int kMaxNumChunks = 1 << FIRST_32_SECOND_64(15, 18); struct Header { @@ -1168,6 +1214,15 @@ class CombinedAllocator { primary_.ForceUnlock(); } + // Iterate over existing chunks. May include chunks that are not currently + // allocated to the user (e.g. freed). + // The caller is expected to call ForceLock() before calling this function. + template<typename Callable> + void ForEachChunk(const Callable &callback) { + primary_.ForEachChunk(callback); + secondary_.ForEachChunk(callback); + } + private: PrimaryAllocator primary_; SecondaryAllocator secondary_; |

