[PATCH] [sanitizer] Generic sorting in sanitizer_common.

Sergey Matveev earthdok at google.com
Mon May 13 04:42:39 PDT 2013


Hi kcc, glider, samsonov,

InternalSort for use with arrays and InternalVector.

http://llvm-reviews.chandlerc.com/D784

Files:
  lib/sanitizer_common/sanitizer_common.cc
  lib/sanitizer_common/sanitizer_common.h

Index: lib/sanitizer_common/sanitizer_common.cc
===================================================================
--- lib/sanitizer_common/sanitizer_common.cc
+++ lib/sanitizer_common/sanitizer_common.cc
@@ -132,45 +132,15 @@
   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'.
Index: lib/sanitizer_common/sanitizer_common.h
===================================================================
--- lib/sanitizer_common/sanitizer_common.h
+++ lib/sanitizer_common/sanitizer_common.h
@@ -340,6 +340,44 @@
   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
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D784.1.patch
Type: text/x-patch
Size: 3167 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130513/432a9163/attachment.bin>


More information about the llvm-commits mailing list