+ struct alloc_zone *zone;
+ struct ggc_statistics stats;
+ size_t total_overhead = 0, total_allocated = 0, total_bytes_mapped = 0;
+ size_t pte_overhead, i;
+
+ /* Clear the statistics. */
+ memset (&stats, 0, sizeof (stats));
+
+ /* Make sure collection will really occur. */
+ ggc_force_collect = true;
+
+ /* Collect and print the statistics common across collectors. */
+ ggc_print_common_statistics (stderr, &stats);
+
+ ggc_force_collect = false;
+
+ /* Release free pages so that we will not count the bytes allocated
+ there as part of the total allocated memory. */
+ for (zone = G.zones; zone; zone = zone->next_zone)
+ release_pages (zone);
+
+ /* Collect some information about the various sizes of
+ allocation. */
+ fprintf (stderr,
+ "Memory still allocated at the end of the compilation process\n");
+
+ fprintf (stderr, "%20s %10s %10s %10s\n",
+ "Zone", "Allocated", "Used", "Overhead");
+ for (zone = G.zones; zone; zone = zone->next_zone)
+ {
+ struct large_page_entry *large_page;
+ size_t overhead, allocated, in_use;
+
+ /* Skip empty zones. */
+ if (!zone->pages && !zone->large_pages)
+ continue;
+
+ allocated = in_use = 0;
+
+ overhead = sizeof (struct alloc_zone);
+
+ for (large_page = zone->large_pages; large_page != NULL;
+ large_page = large_page->next)
+ {
+ allocated += large_page->bytes;
+ in_use += large_page->bytes;
+ overhead += sizeof (struct large_page_entry);
+ }
+
+ /* There's no easy way to walk through the small pages finding
+ used and unused objects. Instead, add all the pages, and
+ subtract out the free list. */
+
+ allocated += GGC_PAGE_SIZE * zone->n_small_pages;
+ in_use += GGC_PAGE_SIZE * zone->n_small_pages;
+ overhead += G.small_page_overhead * zone->n_small_pages;
+
+ for (i = 0; i <= NUM_FREE_BINS; i++)
+ {
+ struct alloc_chunk *chunk = zone->free_chunks[i];
+ while (chunk)
+ {
+ in_use -= ggc_get_size (chunk);
+ chunk = chunk->next_free;
+ }
+ }
+
+ fprintf (stderr, "%20s %10lu%c %10lu%c %10lu%c\n",
+ zone->name,
+ SCALE (allocated), LABEL (allocated),
+ SCALE (in_use), LABEL (in_use),
+ SCALE (overhead), LABEL (overhead));
+
+ gcc_assert (in_use == zone->allocated);
+
+ total_overhead += overhead;
+ total_allocated += zone->allocated;
+ total_bytes_mapped += zone->bytes_mapped;
+ }
+
+ /* Count the size of the page table as best we can. */
+#if HOST_BITS_PER_PTR <= 32
+ pte_overhead = sizeof (G.lookup);
+ for (i = 0; i < PAGE_L1_SIZE; i++)
+ if (G.lookup[i])
+ pte_overhead += PAGE_L2_SIZE * sizeof (struct page_entry *);
+#else
+ {
+ page_table table = G.lookup;
+ pte_overhead = 0;
+ while (table)
+ {
+ pte_overhead += sizeof (*table);
+ for (i = 0; i < PAGE_L1_SIZE; i++)
+ if (table->table[i])
+ pte_overhead += PAGE_L2_SIZE * sizeof (struct page_entry *);
+ table = table->next;
+ }
+ }
+#endif
+ fprintf (stderr, "%20s %11s %11s %10lu%c\n", "Page Table",
+ "", "", SCALE (pte_overhead), LABEL (pte_overhead));
+ total_overhead += pte_overhead;
+
+ fprintf (stderr, "%20s %10lu%c %10lu%c %10lu%c\n", "Total",
+ SCALE (total_bytes_mapped), LABEL (total_bytes_mapped),
+ SCALE (total_allocated), LABEL(total_allocated),
+ SCALE (total_overhead), LABEL (total_overhead));
+
+#ifdef GATHER_STATISTICS
+ {
+ unsigned long long all_overhead = 0, all_allocated = 0;
+ unsigned long long all_overhead_under32 = 0, all_allocated_under32 = 0;
+ unsigned long long all_overhead_under64 = 0, all_allocated_under64 = 0;
+ unsigned long long all_overhead_under128 = 0, all_allocated_under128 = 0;
+
+ fprintf (stderr, "\nTotal allocations and overheads during the compilation process\n");
+
+ for (zone = G.zones; zone; zone = zone->next_zone)
+ {
+ all_overhead += zone->stats.total_overhead;
+ all_allocated += zone->stats.total_allocated;
+
+ all_allocated_under32 += zone->stats.total_allocated_under32;
+ all_overhead_under32 += zone->stats.total_overhead_under32;
+
+ all_allocated_under64 += zone->stats.total_allocated_under64;
+ all_overhead_under64 += zone->stats.total_overhead_under64;
+
+ all_allocated_under128 += zone->stats.total_allocated_under128;
+ all_overhead_under128 += zone->stats.total_overhead_under128;
+
+ fprintf (stderr, "%20s: %10lld\n",
+ zone->name, zone->stats.total_allocated);
+ }
+
+ fprintf (stderr, "\n");
+
+ fprintf (stderr, "Total Overhead: %10lld\n",
+ all_overhead);
+ fprintf (stderr, "Total Allocated: %10lld\n",
+ all_allocated);
+
+ fprintf (stderr, "Total Overhead under 32B: %10lld\n",
+ all_overhead_under32);
+ fprintf (stderr, "Total Allocated under 32B: %10lld\n",
+ all_allocated_under32);
+ fprintf (stderr, "Total Overhead under 64B: %10lld\n",
+ all_overhead_under64);
+ fprintf (stderr, "Total Allocated under 64B: %10lld\n",
+ all_allocated_under64);
+ fprintf (stderr, "Total Overhead under 128B: %10lld\n",
+ all_overhead_under128);
+ fprintf (stderr, "Total Allocated under 128B: %10lld\n",
+ all_allocated_under128);
+ }
+#endif