]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/vec.c
New memory allocation statistics infrastructure.
[thirdparty/gcc.git] / gcc / vec.c
CommitLineData
ada55151 1/* Vector API for GNU compiler.
5624e564 2 Copyright (C) 2004-2015 Free Software Foundation, Inc.
ada55151 3 Contributed by Nathan Sidwell <nathan@codesourcery.com>
0823efed 4 Re-implemented in C++ by Diego Novillo <dnovillo@google.com>
ada55151
NS
5
6This file is part of GCC.
7
8GCC is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
9dcd6f09 10Software Foundation; either version 3, or (at your option) any later
ada55151
NS
11version.
12
13GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16for more details.
17
18You should have received a copy of the GNU General Public License
9dcd6f09
NC
19along with GCC; see the file COPYING3. If not see
20<http://www.gnu.org/licenses/>. */
ada55151 21
2d5bc016
DD
22/* This file is compiled twice: once for the generator programs
23 once for the compiler. */
24#ifdef GENERATOR_FILE
25#include "bconfig.h"
26#else
ada55151 27#include "config.h"
2d5bc016
DD
28#endif
29
ada55151 30#include "system.h"
fc64b448 31#include "coretypes.h"
ada55151
NS
32#include "ggc.h"
33#include "vec.h"
718f9c0f 34#include "diagnostic-core.h"
d3492572 35#include "hashtab.h"
2d44c7de
ML
36#include "mem-stats.h"
37#include "hash-map.h"
38#include "mem-stats.h"
ada55151 39
6e1aa848
DN
40/* vNULL is an empty type with a template cast operation that returns
41 a zero-initialized vec<T, A, L> instance. Use this when you want
42 to assign nil values to new vec instances or pass a nil vector as
43 a function call argument.
44
45 We use this technique because vec<T, A, L> must be PODs (they are
46 stored in unions and passed in vararg functions), this means that
47 they cannot have ctors/dtors. */
48vnull vNULL;
49
2d44c7de
ML
50/* Vector memory usage. */
51struct vec_usage: public mem_usage
d3492572 52{
2d44c7de
ML
53 /* Default constructor. */
54 vec_usage (): m_items (0), m_items_peak (0) {}
55
56 /* Constructor. */
57 vec_usage (size_t allocated, size_t times, size_t peak,
58 size_t items, size_t items_peak)
59 : mem_usage (allocated, times, peak),
60 m_items (items), m_items_peak (items_peak) {}
61
62 /* Comparison operator. */
63 inline bool operator< (const vec_usage &second) const
64 {
65 return (m_allocated == second.m_allocated ?
66 (m_peak == second.m_peak ? m_times < second.m_times
67 : m_peak < second.m_peak) : m_allocated < second.m_allocated);
68 }
69
70 /* Sum the usage with SECOND usage. */
71 vec_usage operator+ (const vec_usage &second)
72 {
73 return vec_usage (m_allocated + second.m_allocated,
74 m_times + second.m_times,
75 m_peak + second.m_peak,
76 m_items + second.m_items,
77 m_items_peak + second.m_items_peak);
78 }
79
80 /* Dump usage coupled to LOC location, where TOTAL is sum of all rows. */
81 inline void dump (mem_location *loc, mem_usage &total) const
82 {
83 char s[4096];
84 sprintf (s, "%s:%i (%s)", loc->get_trimmed_filename (),
85 loc->m_line, loc->m_function);
86
87 s[48] = '\0';
88
89 fprintf (stderr, "%-48s %10li:%4.1f%%%10li%10li:%4.1f%%%11li%11li\n", s,
90 (long)m_allocated, m_allocated * 100.0 / total.m_allocated,
91 (long)m_peak, (long)m_times, m_times * 100.0 / total.m_times,
92 (long)m_items, (long)m_items_peak);
93 }
94
95 /* Dump footer. */
96 inline void dump_footer ()
97 {
98 print_dash_line ();
99 fprintf (stderr, "%s%55li%25li%17li\n", "Total", (long)m_allocated,
100 (long)m_times, (long)m_items);
101 print_dash_line ();
102 }
103
104 /* Dump header with NAME. */
105 static inline void dump_header (const char *name)
106 {
107 fprintf (stderr, "%-48s %11s%15s%10s%17s%11s\n", name, "Leak", "Peak",
108 "Times", "Leak items", "Peak items");
109 print_dash_line ();
110 }
111
112 /* Compare wrapper used by qsort method. */
113 static int compare (const void *first, const void *second)
114 {
115 typedef std::pair<mem_location *, vec_usage *> mem_pair_t;
116
117 const mem_pair_t f = *(const mem_pair_t *)first;
118 const mem_pair_t s = *(const mem_pair_t *)second;
119
120 return (*f.second) < (*s.second);
121 }
122
123 /* Current number of items allocated. */
124 size_t m_items;
125 /* Peak value of number of allocated items. */
126 size_t m_items_peak;
d3492572
JH
127};
128
2d44c7de
ML
129/* Vector memory description. */
130static mem_alloc_description <vec_usage> vec_mem_desc;
d3492572
JH
131
132/* Account the overhead. */
9771b263
DN
133
134void
2d44c7de
ML
135vec_prefix::register_overhead (void *ptr, size_t size, size_t elements
136 MEM_STAT_DECL)
d3492572 137{
2d44c7de
ML
138 vec_mem_desc.register_descriptor (ptr, VEC, false FINAL_PASS_MEM_STAT);
139 vec_usage *usage = vec_mem_desc.register_instance_overhead (size, ptr);
140 usage->m_items += elements;
141 if (usage->m_items_peak < usage->m_items)
142 usage->m_items_peak = usage->m_items;
d3492572
JH
143}
144
9771b263
DN
145/* Notice that the memory allocated for the vector has been freed. */
146
147void
2d44c7de
ML
148vec_prefix::release_overhead (void *ptr, size_t size, bool in_dtor
149 MEM_STAT_DECL)
d3492572 150{
2d44c7de
ML
151 if (!vec_mem_desc.contains_descriptor_for_instance (ptr))
152 vec_mem_desc.register_descriptor (ptr, VEC, false FINAL_PASS_MEM_STAT);
153 vec_mem_desc.release_instance_overhead (ptr, size, in_dtor);
d3492572
JH
154}
155
d3492572 156
9771b263 157/* Calculate the number of slots to reserve a vector, making sure that
3a938d75 158 it is of at least DESIRED size by growing ALLOC exponentially. */
d4e6fecb 159
9771b263 160unsigned
3a938d75 161vec_prefix::calculate_allocation_1 (unsigned alloc, unsigned desired)
d4e6fecb 162{
d4e6fecb 163 /* We must have run out of room. */
3a938d75
RB
164 gcc_assert (alloc < desired);
165
166 /* Exponential growth. */
167 if (!alloc)
168 alloc = 4;
169 else if (alloc < 16)
170 /* Double when small. */
171 alloc = alloc * 2;
d4e6fecb 172 else
3a938d75
RB
173 /* Grow slower when large. */
174 alloc = (alloc * 3 / 2);
175
176 /* If this is still too small, set it to the right size. */
177 if (alloc < desired)
178 alloc = desired;
d4e6fecb
NS
179 return alloc;
180}
181
d3492572 182/* Dump per-site memory statistics. */
7aa6d18a 183
d3492572
JH
184void
185dump_vec_loc_statistics (void)
186{
2d44c7de 187 vec_mem_desc.dump (VEC);
d3492572 188}