WinDBG/Exts/CodeAnalyzer/gdbplus/gdb-7.7/gdb/heap.c
/*
 * Input is a heap memory address
 * Return the sum of sizes of all memory blocks (and their count) reachable by the block
 * 		i.e. referenced directly or indirectly by it (avoid duplicates)
 */
Input is a heap memory address
Return the sum of sizes of all memory blocks (and their count) reachable by the block
i.e. referenced directly or indirectly by it (avoid duplicates)
Input is a heap memory address Return the sum of sizes of all memory blocks ( and their count ) reachable by the block i . e . referenced directly or indirectly by it ( avoid duplicates )
static size_t heap_aggregate_size(struct inuse_block *blk,
								struct inuse_block *inuse_blocks,
								unsigned long num_inuse_blocks,
								unsigned int* qv_bitmap,
								unsigned long *aggr_count)
{
	size_t sum = 0;
	*aggr_count = 0;
	if (is_queued_or_visited(qv_bitmap, blk - inuse_blocks))
		return 0;
	while (blk)
	{
		struct inuse_block *nextblk = NULL;
		unsigned int* indexp;
		unsigned long blk_index = blk - inuse_blocks;
		sum += blk->size;
		(*aggr_count)++;
		reset_queued(qv_bitmap, blk_index);
		set_visited(qv_bitmap, blk_index);
		if (!blk->reachable.index_map)
		{
			if (!build_block_index_map(blk, inuse_blocks, num_inuse_blocks))
				return 0;
		}
		indexp = blk->reachable.index_map;
		while (*indexp != UINT_MAX)
		{
			unsigned int index = *indexp;
			if (!is_queued_or_visited(qv_bitmap, index))
			{
				set_queued(qv_bitmap, index);
				if (!nextblk)
					nextblk = inuse_blocks + index;
			}
			indexp++;
		}
		if (!nextblk)
		{
			unsigned long next_index = get_next_queued_index(qv_bitmap, num_inuse_blocks, blk_index);
			if (next_index < num_inuse_blocks)
				nextblk = inuse_blocks + next_index;
		}
		blk = nextblk;
	}
	return sum;
}
static size_t heap_aggregate_size ( struct inuse_block * blk , struct inuse_block * inuse_blocks , unsigned long num_inuse_blocks , unsigned int * qv_bitmap , unsigned long * aggr_count ) { size_t sum = 0 ; * aggr_count = 0 ; if ( is_queued_or_visited ( qv_bitmap , blk - inuse_blocks ) ) return 0 ; while ( blk ) { struct inuse_block * nextblk = NULL ; unsigned int * indexp ; unsigned long blk_index = blk - inuse_blocks ; sum += blk -> size ; ( * aggr_count ) ++ ; reset_queued ( qv_bitmap , blk_index ) ; set_visited ( qv_bitmap , blk_index ) ; if ( ! blk -> reachable . index_map ) { if ( ! build_block_index_map ( blk , inuse_blocks , num_inuse_blocks ) ) return 0 ; } indexp = blk -> reachable . index_map ; while ( * indexp != UINT_MAX ) { unsigned int index = * indexp ; if ( ! is_queued_or_visited ( qv_bitmap , index ) ) { set_queued ( qv_bitmap , index ) ; if ( ! nextblk ) nextblk = inuse_blocks + index ; } indexp ++ ; } if ( ! nextblk ) { unsigned long next_index = get_next_queued_index ( qv_bitmap , num_inuse_blocks , blk_index ) ; if ( next_index < num_inuse_blocks ) nextblk = inuse_blocks + next_index ; } blk = nextblk ; } return sum ; }
Input is a heap memory address
 Return the sum of sizes of all memory blocks (and their count) reachable by the block
              i.e.
Input is a heap memory address Return the sum of sizes of all memory blocks ( and their count ) reachable by the block i . e .
// Get the inuse_block struct of the input address // Big loop until all reachable have been visited // mark this block is reachable and accounted for // Prepare this block's index map, which is an array of indexes of sub blocks // We have index map to work with by now //if (index >= num_inuse_blocks) //{ //	CA_PRINT("Internal fatal error: sub block index out of bound\n"); //	return 0; //} // Get the next block that is queued // block processed doesn't have any subfield that points to an unvisited in-use block // starts from the current block and wrap around