From d9da20f56f10bb618a3ef0e563b44153cb280bf9 Mon Sep 17 00:00:00 2001 From: Sergey Matveev Date: Mon, 13 May 2013 11:58:48 +0000 Subject: [PATCH] [sanitizer] Generic sorting in sanitizer_common. llvm-svn: 181698 --- .../lib/sanitizer_common/sanitizer_common.cc | 46 ++++--------------- .../lib/sanitizer_common/sanitizer_common.h | 38 +++++++++++++++ 2 files changed, 46 insertions(+), 38 deletions(-) diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common.cc b/compiler-rt/lib/sanitizer_common/sanitizer_common.cc index 3bb8e8118d40..12d5b6cf5b65 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common.cc @@ -132,45 +132,15 @@ uptr ReadFileToBuffer(const char *file_name, char **buff, return read_len; } -// We don't want to use std::sort to avoid including , as -// we may end up with two implementation of std::sort - one in instrumented -// code, and the other in runtime. -// qsort() from stdlib won't work as it calls malloc(), which results -// in deadlock in ASan allocator. -// We re-implement in-place sorting w/o recursion as straightforward heapsort. +typedef bool UptrComparisonFunction(const uptr &a, const uptr &b); + +template +static inline bool CompareLess(const T &a, const T &b) { + return a < b; +} + void SortArray(uptr *array, uptr size) { - if (size < 2) - return; - // Stage 1: insert elements to the heap. - for (uptr i = 1; i < size; i++) { - uptr j, p; - for (j = i; j > 0; j = p) { - p = (j - 1) / 2; - if (array[j] > array[p]) - Swap(array[j], array[p]); - else - break; - } - } - // Stage 2: swap largest element with the last one, - // and sink the new top. - for (uptr i = size - 1; i > 0; i--) { - Swap(array[0], array[i]); - uptr j, max_ind; - for (j = 0; j < i; j = max_ind) { - uptr left = 2 * j + 1; - uptr right = 2 * j + 2; - max_ind = j; - if (left < i && array[left] > array[max_ind]) - max_ind = left; - if (right < i && array[right] > array[max_ind]) - max_ind = right; - if (max_ind != j) - Swap(array[j], array[max_ind]); - else - break; - } - } + InternalSort(&array, size, CompareLess); } // We want to map a chunk of address space aligned to 'alignment'. diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common.h b/compiler-rt/lib/sanitizer_common/sanitizer_common.h index 92ba0d53b994..252224f57868 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common.h @@ -340,6 +340,44 @@ class InternalVector { uptr capacity_; uptr size_; }; + +// HeapSort for arrays and InternalVector. +template +void InternalSort(Container *v, uptr size, Compare comp) { + if (size < 2) + return; + // Stage 1: insert elements to the heap. + for (uptr i = 1; i < size; i++) { + uptr j, p; + for (j = i; j > 0; j = p) { + p = (j - 1) / 2; + if (comp((*v)[p], (*v)[j])) + Swap((*v)[j], (*v)[p]); + else + break; + } + } + // Stage 2: swap largest element with the last one, + // and sink the new top. + for (uptr i = size - 1; i > 0; i--) { + Swap((*v)[0], (*v)[i]); + uptr j, max_ind; + for (j = 0; j < i; j = max_ind) { + uptr left = 2 * j + 1; + uptr right = 2 * j + 2; + max_ind = j; + if (left < i && comp((*v)[max_ind], (*v)[left])) + max_ind = left; + if (right < i && comp((*v)[max_ind], (*v)[right])) + max_ind = right; + if (max_ind != j) + Swap((*v)[j], (*v)[max_ind]); + else + break; + } + } +} + } // namespace __sanitizer #endif // SANITIZER_COMMON_H