xref: /dflybsd-src/contrib/gcc-8.0/gcc/ggc.h (revision 38fd149817dfbff97799f62fcb70be98c4e32523)
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