forked from OSchip/llvm-project
[sanitizer] Generic sorting in sanitizer_common.
llvm-svn: 181698
This commit is contained in:
parent
37432e815e
commit
d9da20f56f
|
|
@ -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 <algorithm>, 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<class T>
|
||||
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<uptr*, UptrComparisonFunction>(&array, size, CompareLess);
|
||||
}
|
||||
|
||||
// We want to map a chunk of address space aligned to 'alignment'.
|
||||
|
|
|
|||
|
|
@ -340,6 +340,44 @@ class InternalVector {
|
|||
uptr capacity_;
|
||||
uptr size_;
|
||||
};
|
||||
|
||||
// HeapSort for arrays and InternalVector.
|
||||
template<class Container, class Compare>
|
||||
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
|
||||
|
|
|
|||
Loading…
Reference in New Issue