1*38fd1498Szrj /* Garbage collection for the GNU compiler.
2*38fd1498Szrj
3*38fd1498Szrj Copyright (C) 1998-2018 Free Software Foundation, Inc.
4*38fd1498Szrj
5*38fd1498Szrj This file is part of GCC.
6*38fd1498Szrj
7*38fd1498Szrj GCC is free software; you can redistribute it and/or modify it under
8*38fd1498Szrj the terms of the GNU General Public License as published by the Free
9*38fd1498Szrj Software Foundation; either version 3, or (at your option) any later
10*38fd1498Szrj version.
11*38fd1498Szrj
12*38fd1498Szrj GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13*38fd1498Szrj WARRANTY; without even the implied warranty of MERCHANTABILITY or
14*38fd1498Szrj FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15*38fd1498Szrj for more details.
16*38fd1498Szrj
17*38fd1498Szrj You should have received a copy of the GNU General Public License
18*38fd1498Szrj along with GCC; see the file COPYING3. If not see
19*38fd1498Szrj <http://www.gnu.org/licenses/>. */
20*38fd1498Szrj
21*38fd1498Szrj #ifndef GCC_GGC_H
22*38fd1498Szrj #define GCC_GGC_H
23*38fd1498Szrj
24*38fd1498Szrj /* Symbols are marked with `ggc' for `gcc gc' so as not to interfere with
25*38fd1498Szrj an external gc library that might be linked in. */
26*38fd1498Szrj
27*38fd1498Szrj /* Internal functions and data structures used by the GTY
28*38fd1498Szrj machinery, including the generated gt*.[hc] files. */
29*38fd1498Szrj
30*38fd1498Szrj #include "gtype-desc.h"
31*38fd1498Szrj
32*38fd1498Szrj /* One of these applies its third parameter (with cookie in the fourth
33*38fd1498Szrj parameter) to each pointer in the object pointed to by the first
34*38fd1498Szrj parameter, using the second parameter. */
35*38fd1498Szrj typedef void (*gt_note_pointers) (void *, void *, gt_pointer_operator,
36*38fd1498Szrj void *);
37*38fd1498Szrj
38*38fd1498Szrj /* One of these is called before objects are re-ordered in memory.
39*38fd1498Szrj The first parameter is the original object, the second is the
40*38fd1498Szrj subobject that has had its pointers reordered, the third parameter
41*38fd1498Szrj can compute the new values of a pointer when given the cookie in
42*38fd1498Szrj the fourth parameter. */
43*38fd1498Szrj typedef void (*gt_handle_reorder) (void *, void *, gt_pointer_operator,
44*38fd1498Szrj void *);
45*38fd1498Szrj
46*38fd1498Szrj /* Used by the gt_pch_n_* routines. Register an object in the hash table. */
47*38fd1498Szrj extern int gt_pch_note_object (void *, void *, gt_note_pointers);
48*38fd1498Szrj
49*38fd1498Szrj /* Used by the gt_pch_n_* routines. Register that an object has a reorder
50*38fd1498Szrj function. */
51*38fd1498Szrj extern void gt_pch_note_reorder (void *, void *, gt_handle_reorder);
52*38fd1498Szrj
53*38fd1498Szrj /* generated function to clear caches in gc memory. */
54*38fd1498Szrj extern void gt_clear_caches ();
55*38fd1498Szrj
56*38fd1498Szrj /* Mark the object in the first parameter and anything it points to. */
57*38fd1498Szrj typedef void (*gt_pointer_walker) (void *);
58*38fd1498Szrj
59*38fd1498Szrj /* Structures for the easy way to mark roots.
60*38fd1498Szrj In an array, terminated by having base == NULL. */
61*38fd1498Szrj struct ggc_root_tab {
62*38fd1498Szrj void *base;
63*38fd1498Szrj size_t nelt;
64*38fd1498Szrj size_t stride;
65*38fd1498Szrj gt_pointer_walker cb;
66*38fd1498Szrj gt_pointer_walker pchw;
67*38fd1498Szrj };
68*38fd1498Szrj #define LAST_GGC_ROOT_TAB { NULL, 0, 0, NULL, NULL }
69*38fd1498Szrj /* Pointers to arrays of ggc_root_tab, terminated by NULL. */
70*38fd1498Szrj extern const struct ggc_root_tab * const gt_ggc_rtab[];
71*38fd1498Szrj extern const struct ggc_root_tab * const gt_ggc_deletable_rtab[];
72*38fd1498Szrj extern const struct ggc_root_tab * const gt_pch_scalar_rtab[];
73*38fd1498Szrj
74*38fd1498Szrj /* If EXPR is not NULL and previously unmarked, mark it and evaluate
75*38fd1498Szrj to true. Otherwise evaluate to false. */
76*38fd1498Szrj #define ggc_test_and_set_mark(EXPR) \
77*38fd1498Szrj ((EXPR) != NULL && ((void *) (EXPR)) != (void *) 1 && ! ggc_set_mark (EXPR))
78*38fd1498Szrj
79*38fd1498Szrj #define ggc_mark(EXPR) \
80*38fd1498Szrj do { \
81*38fd1498Szrj const void *const a__ = (EXPR); \
82*38fd1498Szrj if (a__ != NULL && a__ != (void *) 1) \
83*38fd1498Szrj ggc_set_mark (a__); \
84*38fd1498Szrj } while (0)
85*38fd1498Szrj
86*38fd1498Szrj /* Actually set the mark on a particular region of memory, but don't
87*38fd1498Szrj follow pointers. This function is called by ggc_mark_*. It
88*38fd1498Szrj returns zero if the object was not previously marked; nonzero if
89*38fd1498Szrj the object was already marked, or if, for any other reason,
90*38fd1498Szrj pointers in this data structure should not be traversed. */
91*38fd1498Szrj extern int ggc_set_mark (const void *);
92*38fd1498Szrj
93*38fd1498Szrj /* Return 1 if P has been marked, zero otherwise.
94*38fd1498Szrj P must have been allocated by the GC allocator; it mustn't point to
95*38fd1498Szrj static objects, stack variables, or memory allocated with malloc. */
96*38fd1498Szrj extern int ggc_marked_p (const void *);
97*38fd1498Szrj
98*38fd1498Szrj /* PCH and GGC handling for strings, mostly trivial. */
99*38fd1498Szrj extern void gt_pch_n_S (const void *);
100*38fd1498Szrj extern void gt_ggc_m_S (const void *);
101*38fd1498Szrj
102*38fd1498Szrj /* End of GTY machinery API. */
103*38fd1498Szrj
104*38fd1498Szrj /* Initialize the string pool. */
105*38fd1498Szrj extern void init_stringpool (void);
106*38fd1498Szrj
107*38fd1498Szrj /* Initialize the garbage collector. */
108*38fd1498Szrj extern void init_ggc (void);
109*38fd1498Szrj
110*38fd1498Szrj /* When true, identifier nodes are considered as GC roots. When
111*38fd1498Szrj false, identifier nodes are treated like any other GC-allocated
112*38fd1498Szrj object, and the identifier hash table is treated as a weak
113*38fd1498Szrj hash. */
114*38fd1498Szrj extern bool ggc_protect_identifiers;
115*38fd1498Szrj
116*38fd1498Szrj /* Write out all GCed objects to F. */
117*38fd1498Szrj extern void gt_pch_save (FILE *f);
118*38fd1498Szrj
119*38fd1498Szrj
120*38fd1498Szrj /* Allocation. */
121*38fd1498Szrj
122*38fd1498Szrj /* The internal primitive. */
123*38fd1498Szrj extern void *ggc_internal_alloc (size_t, void (*)(void *), size_t,
124*38fd1498Szrj size_t CXX_MEM_STAT_INFO)
125*38fd1498Szrj ATTRIBUTE_MALLOC;
126*38fd1498Szrj
127*38fd1498Szrj inline void *
ggc_internal_alloc(size_t s CXX_MEM_STAT_INFO)128*38fd1498Szrj ggc_internal_alloc (size_t s CXX_MEM_STAT_INFO)
129*38fd1498Szrj {
130*38fd1498Szrj return ggc_internal_alloc (s, NULL, 0, 1 PASS_MEM_STAT);
131*38fd1498Szrj }
132*38fd1498Szrj
133*38fd1498Szrj extern size_t ggc_round_alloc_size (size_t requested_size);
134*38fd1498Szrj
135*38fd1498Szrj /* Allocates cleared memory. */
136*38fd1498Szrj extern void *ggc_internal_cleared_alloc (size_t, void (*)(void *),
137*38fd1498Szrj size_t, size_t
138*38fd1498Szrj CXX_MEM_STAT_INFO) ATTRIBUTE_MALLOC;
139*38fd1498Szrj
140*38fd1498Szrj inline void *
ggc_internal_cleared_alloc(size_t s CXX_MEM_STAT_INFO)141*38fd1498Szrj ggc_internal_cleared_alloc (size_t s CXX_MEM_STAT_INFO)
142*38fd1498Szrj {
143*38fd1498Szrj return ggc_internal_cleared_alloc (s, NULL, 0, 1 PASS_MEM_STAT);
144*38fd1498Szrj }
145*38fd1498Szrj
146*38fd1498Szrj /* Resize a block. */
147*38fd1498Szrj extern void *ggc_realloc (void *, size_t CXX_MEM_STAT_INFO);
148*38fd1498Szrj
149*38fd1498Szrj /* Free a block. To be used when known for certain it's not reachable. */
150*38fd1498Szrj extern void ggc_free (void *);
151*38fd1498Szrj
152*38fd1498Szrj extern void dump_ggc_loc_statistics (bool);
153*38fd1498Szrj
154*38fd1498Szrj /* Reallocator. */
155*38fd1498Szrj #define GGC_RESIZEVEC(T, P, N) \
156*38fd1498Szrj ((T *) ggc_realloc ((P), (N) * sizeof (T) MEM_STAT_INFO))
157*38fd1498Szrj
158*38fd1498Szrj template<typename T>
159*38fd1498Szrj void
finalize(void * p)160*38fd1498Szrj finalize (void *p)
161*38fd1498Szrj {
162*38fd1498Szrj static_cast<T *> (p)->~T ();
163*38fd1498Szrj }
164*38fd1498Szrj
165*38fd1498Szrj template<typename T>
166*38fd1498Szrj inline bool
need_finalization_p()167*38fd1498Szrj need_finalization_p ()
168*38fd1498Szrj {
169*38fd1498Szrj #if GCC_VERSION >= 4003
170*38fd1498Szrj return !__has_trivial_destructor (T);
171*38fd1498Szrj #else
172*38fd1498Szrj return true;
173*38fd1498Szrj #endif
174*38fd1498Szrj }
175*38fd1498Szrj
176*38fd1498Szrj template<typename T>
177*38fd1498Szrj inline T *
ggc_alloc(ALONE_CXX_MEM_STAT_INFO)178*38fd1498Szrj ggc_alloc (ALONE_CXX_MEM_STAT_INFO)
179*38fd1498Szrj {
180*38fd1498Szrj if (need_finalization_p<T> ())
181*38fd1498Szrj return static_cast<T *> (ggc_internal_alloc (sizeof (T), finalize<T>, 0, 1
182*38fd1498Szrj PASS_MEM_STAT));
183*38fd1498Szrj else
184*38fd1498Szrj return static_cast<T *> (ggc_internal_alloc (sizeof (T), NULL, 0, 1
185*38fd1498Szrj PASS_MEM_STAT));
186*38fd1498Szrj }
187*38fd1498Szrj
188*38fd1498Szrj template<typename T>
189*38fd1498Szrj inline T *
ggc_cleared_alloc(ALONE_CXX_MEM_STAT_INFO)190*38fd1498Szrj ggc_cleared_alloc (ALONE_CXX_MEM_STAT_INFO)
191*38fd1498Szrj {
192*38fd1498Szrj if (need_finalization_p<T> ())
193*38fd1498Szrj return static_cast<T *> (ggc_internal_cleared_alloc (sizeof (T),
194*38fd1498Szrj finalize<T>, 0, 1
195*38fd1498Szrj PASS_MEM_STAT));
196*38fd1498Szrj else
197*38fd1498Szrj return static_cast<T *> (ggc_internal_cleared_alloc (sizeof (T), NULL, 0, 1
198*38fd1498Szrj PASS_MEM_STAT));
199*38fd1498Szrj }
200*38fd1498Szrj
201*38fd1498Szrj template<typename T>
202*38fd1498Szrj inline T *
ggc_vec_alloc(size_t c CXX_MEM_STAT_INFO)203*38fd1498Szrj ggc_vec_alloc (size_t c CXX_MEM_STAT_INFO)
204*38fd1498Szrj {
205*38fd1498Szrj if (need_finalization_p<T> ())
206*38fd1498Szrj return static_cast<T *> (ggc_internal_alloc (c * sizeof (T), finalize<T>,
207*38fd1498Szrj sizeof (T), c PASS_MEM_STAT));
208*38fd1498Szrj else
209*38fd1498Szrj return static_cast<T *> (ggc_internal_alloc (c * sizeof (T), NULL, 0, 0
210*38fd1498Szrj PASS_MEM_STAT));
211*38fd1498Szrj }
212*38fd1498Szrj
213*38fd1498Szrj template<typename T>
214*38fd1498Szrj inline T *
ggc_cleared_vec_alloc(size_t c CXX_MEM_STAT_INFO)215*38fd1498Szrj ggc_cleared_vec_alloc (size_t c CXX_MEM_STAT_INFO)
216*38fd1498Szrj {
217*38fd1498Szrj if (need_finalization_p<T> ())
218*38fd1498Szrj return static_cast<T *> (ggc_internal_cleared_alloc (c * sizeof (T),
219*38fd1498Szrj finalize<T>,
220*38fd1498Szrj sizeof (T), c
221*38fd1498Szrj PASS_MEM_STAT));
222*38fd1498Szrj else
223*38fd1498Szrj return static_cast<T *> (ggc_internal_cleared_alloc (c * sizeof (T), NULL,
224*38fd1498Szrj 0, 0 PASS_MEM_STAT));
225*38fd1498Szrj }
226*38fd1498Szrj
227*38fd1498Szrj inline void *
ggc_alloc_atomic(size_t s CXX_MEM_STAT_INFO)228*38fd1498Szrj ggc_alloc_atomic (size_t s CXX_MEM_STAT_INFO)
229*38fd1498Szrj {
230*38fd1498Szrj return ggc_internal_alloc (s PASS_MEM_STAT);
231*38fd1498Szrj }
232*38fd1498Szrj
233*38fd1498Szrj /* Allocate a gc-able string, and fill it with LENGTH bytes from CONTENTS.
234*38fd1498Szrj If LENGTH is -1, then CONTENTS is assumed to be a
235*38fd1498Szrj null-terminated string and the memory sized accordingly. */
236*38fd1498Szrj extern const char *ggc_alloc_string (const char *contents, int length
237*38fd1498Szrj CXX_MEM_STAT_INFO);
238*38fd1498Szrj
239*38fd1498Szrj /* Make a copy of S, in GC-able memory. */
240*38fd1498Szrj #define ggc_strdup(S) ggc_alloc_string ((S), -1 MEM_STAT_INFO)
241*38fd1498Szrj
242*38fd1498Szrj /* Invoke the collector. Garbage collection occurs only when this
243*38fd1498Szrj function is called, not during allocations. */
244*38fd1498Szrj extern void ggc_collect (void);
245*38fd1498Szrj
246*38fd1498Szrj /* Assume that all GGC memory is reachable and grow the limits for next collection. */
247*38fd1498Szrj extern void ggc_grow (void);
248*38fd1498Szrj
249*38fd1498Szrj /* Register an additional root table. This can be useful for some
250*38fd1498Szrj plugins. Does nothing if the passed pointer is NULL. */
251*38fd1498Szrj extern void ggc_register_root_tab (const struct ggc_root_tab *);
252*38fd1498Szrj
253*38fd1498Szrj /* Read objects previously saved with gt_pch_save from F. */
254*38fd1498Szrj extern void gt_pch_restore (FILE *f);
255*38fd1498Szrj
256*38fd1498Szrj /* Statistics. */
257*38fd1498Szrj
258*38fd1498Szrj /* Print allocation statistics. */
259*38fd1498Szrj extern void ggc_print_statistics (void);
260*38fd1498Szrj
261*38fd1498Szrj extern void stringpool_statistics (void);
262*38fd1498Szrj
263*38fd1498Szrj /* Heuristics. */
264*38fd1498Szrj extern void init_ggc_heuristics (void);
265*38fd1498Szrj
266*38fd1498Szrj #define ggc_alloc_rtvec_sized(NELT) \
267*38fd1498Szrj (rtvec_def *) ggc_internal_alloc (sizeof (struct rtvec_def) \
268*38fd1498Szrj + ((NELT) - 1) * sizeof (rtx)) \
269*38fd1498Szrj
270*38fd1498Szrj /* Memory statistics passing versions of some allocators. Too few of them to
271*38fd1498Szrj make gengtype produce them, so just define the needed ones here. */
272*38fd1498Szrj inline struct rtx_def *
ggc_alloc_rtx_def_stat(size_t s CXX_MEM_STAT_INFO)273*38fd1498Szrj ggc_alloc_rtx_def_stat (size_t s CXX_MEM_STAT_INFO)
274*38fd1498Szrj {
275*38fd1498Szrj return (struct rtx_def *) ggc_internal_alloc (s PASS_MEM_STAT);
276*38fd1498Szrj }
277*38fd1498Szrj
278*38fd1498Szrj inline union tree_node *
ggc_alloc_tree_node_stat(size_t s CXX_MEM_STAT_INFO)279*38fd1498Szrj ggc_alloc_tree_node_stat (size_t s CXX_MEM_STAT_INFO)
280*38fd1498Szrj {
281*38fd1498Szrj return (union tree_node *) ggc_internal_alloc (s PASS_MEM_STAT);
282*38fd1498Szrj }
283*38fd1498Szrj
284*38fd1498Szrj inline union tree_node *
ggc_alloc_cleared_tree_node_stat(size_t s CXX_MEM_STAT_INFO)285*38fd1498Szrj ggc_alloc_cleared_tree_node_stat (size_t s CXX_MEM_STAT_INFO)
286*38fd1498Szrj {
287*38fd1498Szrj return (union tree_node *) ggc_internal_cleared_alloc (s PASS_MEM_STAT);
288*38fd1498Szrj }
289*38fd1498Szrj
290*38fd1498Szrj inline gimple *
ggc_alloc_cleared_gimple_statement_stat(size_t s CXX_MEM_STAT_INFO)291*38fd1498Szrj ggc_alloc_cleared_gimple_statement_stat (size_t s CXX_MEM_STAT_INFO)
292*38fd1498Szrj {
293*38fd1498Szrj return (gimple *) ggc_internal_cleared_alloc (s PASS_MEM_STAT);
294*38fd1498Szrj }
295*38fd1498Szrj
296*38fd1498Szrj inline void
gt_ggc_mx(const char * s)297*38fd1498Szrj gt_ggc_mx (const char *s)
298*38fd1498Szrj {
299*38fd1498Szrj ggc_test_and_set_mark (const_cast<char *> (s));
300*38fd1498Szrj }
301*38fd1498Szrj
302*38fd1498Szrj inline void
gt_pch_nx(const char *)303*38fd1498Szrj gt_pch_nx (const char *)
304*38fd1498Szrj {
305*38fd1498Szrj }
306*38fd1498Szrj
307*38fd1498Szrj inline void
gt_ggc_mx(int)308*38fd1498Szrj gt_ggc_mx (int)
309*38fd1498Szrj {
310*38fd1498Szrj }
311*38fd1498Szrj
312*38fd1498Szrj inline void
gt_pch_nx(int)313*38fd1498Szrj gt_pch_nx (int)
314*38fd1498Szrj {
315*38fd1498Szrj }
316*38fd1498Szrj
317*38fd1498Szrj inline void
gt_pch_nx(unsigned int)318*38fd1498Szrj gt_pch_nx (unsigned int)
319*38fd1498Szrj {
320*38fd1498Szrj }
321*38fd1498Szrj
322*38fd1498Szrj #endif
323