return curr;
}
-static
-void sort_hash_array ( VgHashNode** shadows, UInt n_shadows )
-{
- Int incs[14] = { 1, 4, 13, 40, 121, 364, 1093, 3280,
- 9841, 29524, 88573, 265720,
- 797161, 2391484 };
- Int lo = 0;
- Int hi = n_shadows-1;
- Int i, j, h, bigN, hp;
- VgHashNode* v;
-
- bigN = hi - lo + 1; if (bigN < 2) return;
- hp = 0; while (hp < 14 && incs[hp] < bigN) hp++; hp--;
- vg_assert(0 <= hp && hp < 14);
-
- for (; hp >= 0; hp--) {
- h = incs[hp];
- i = lo + h;
- while (1) {
- if (i > hi) break;
- v = shadows[i];
- j = i;
- while (shadows[j-h]->key > v->key) {
- shadows[j] = shadows[j-h];
- j = j - h;
- if (j <= (lo + h - 1)) break;
- }
- shadows[j] = v;
- i++;
- }
- }
-}
-
/* Allocates a suitably-sized array, copies all the malloc'd block
- shadows into it, sorts it by the `key' field, then returns both the array
- and the size of it. This is used by the memory-leak detector.
+ shadows into it, then returns both the array and the size of it. This is
+ used by the memory-leak detector.
*/
-VgHashNode** VG_(HT_to_sorted_array) ( VgHashTable table,
- /*OUT*/ UInt* n_shadows )
+VgHashNode** VG_(HT_to_array) ( VgHashTable table, /*OUT*/ UInt* n_shadows )
{
UInt i, j;
VgHashNode** arr;
}
vg_assert(j == *n_shadows);
- sort_hash_array(arr, *n_shadows);
-
- /* Sanity check; assert that the blocks are now in order */
- for (i = 0; i < *n_shadows-1; i++) {
- vg_assert( arr[i]->key < arr[i+1]->key );
- }
-
return arr;
}
extern VgHashNode* VG_(HT_get_node) ( VgHashTable t, UInt key,
/*OUT*/VgHashNode*** next_ptr );
-/* Allocates a sorted array of pointers to all the shadow chunks of malloc'd
- blocks. */
-extern VgHashNode** VG_(HT_to_sorted_array) ( VgHashTable t,
- /*OUT*/ UInt* n_shadows );
+/* Allocates an array of pointers to all the shadow chunks of malloc'd
+ blocks. Must be freed with VG_(free)(). */
+extern VgHashNode** VG_(HT_to_array) ( VgHashTable t, /*OUT*/ UInt* n_shadows );
/* Returns first node that matches predicate `p', or NULL if none do.
Extra arguments can be implicitly passed to `p' using nested functions;
Int MAC_(bytes_reachable) = 0;
Int MAC_(bytes_suppressed) = 0;
+static Int lc_compar(void* n1, void* n2)
+{
+ MAC_Chunk* mc1 = *(MAC_Chunk**)n1;
+ MAC_Chunk* mc2 = *(MAC_Chunk**)n2;
+ return (mc1->data < mc2->data ? -1 : 1);
+}
+
/* Top level entry point to leak detector. Call here, passing in
suitable address-validating functions (see comment at top of
vg_scan_all_valid_memory above). All this is to avoid duplication
LossRecord* errlist;
LossRecord* p;
- /* VG_(HashTable_to_array) allocates storage for shadows */
- lc_shadows = (MAC_Chunk**)VG_(HT_to_sorted_array)( MAC_(malloc_list),
- &lc_n_shadows );
+ /* VG_(HT_to_array) allocates storage for shadows */
+ lc_shadows = (MAC_Chunk**)VG_(HT_to_array)( MAC_(malloc_list),
+ &lc_n_shadows );
+
+ /* Sort the array. */
+ VG_(ssort)((void*)lc_shadows, lc_n_shadows, sizeof(VgHashNode*), lc_compar);
+
+ /* Sanity check; assert that the blocks are now in order */
+ for (i = 0; i < lc_n_shadows-1; i++) {
+ sk_assert( lc_shadows[i]->data <= lc_shadows[i+1]->data);
+ }
/* Sanity check -- make sure they don't overlap */
for (i = 0; i < lc_n_shadows-1; i++) {