summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSergey Matveev <earthdok@google.com>2013-05-13 11:58:48 +0000
committerSergey Matveev <earthdok@google.com>2013-05-13 11:58:48 +0000
commitd9da20f56f10bb618a3ef0e563b44153cb280bf9 (patch)
tree92dbabaa5f091ea6dbc32743f84c8d6d86a55607
parent37432e815e6897c4e2df4e10c592263c6f626404 (diff)
downloadbcm5719-llvm-d9da20f56f10bb618a3ef0e563b44153cb280bf9.tar.gz
bcm5719-llvm-d9da20f56f10bb618a3ef0e563b44153cb280bf9.zip
[sanitizer] Generic sorting in sanitizer_common.
llvm-svn: 181698
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_common.cc46
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_common.h38
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 3bb8e8118d4..12d5b6cf5b6 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 <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'.
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common.h b/compiler-rt/lib/sanitizer_common/sanitizer_common.h
index 92ba0d53b99..252224f5786 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<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
OpenPOWER on IntegriCloud