xref: /dragonfly/contrib/gcc-8.0/gcc/ggc-tests.c (revision 0600465e)
1 /* Unit tests for GCC's garbage collector (and gengtype etc).
2    Copyright (C) 2015-2018 Free Software Foundation, Inc.
3 
4 This file is part of GCC.
5 
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
10 
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3.  If not see
18 <http://www.gnu.org/licenses/>.  */
19 
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "tree-core.h"
24 #include "tree.h"
25 #include "ggc-internal.h" /* (for ggc_force_collect).  */
26 #include "selftest.h"
27 
28 #if CHECKING_P
29 
30 /* A helper function for writing ggc tests.  */
31 
32 void
33 selftest::forcibly_ggc_collect ()
34 {
35   ggc_force_collect = true;
36   ggc_collect ();
37   ggc_force_collect = false;
38 }
39 
40 /* The various GTY markers must be outside of a namespace to be seen by
41    gengtype, so we don't put this file within the selftest namespace.  */
42 
43 
44 
45 /* Verify that a simple struct works, and that it can
46    own references to non-roots, and have them be marked.  */
47 
48 struct GTY(()) test_struct
49 {
50   struct test_struct *other;
51 };
52 
53 static GTY(()) test_struct *root_test_struct;
54 
55 static void
56 test_basic_struct ()
57 {
58   root_test_struct = ggc_cleared_alloc <test_struct> ();
59   root_test_struct->other = ggc_cleared_alloc <test_struct> ();
60 
61   selftest::forcibly_ggc_collect ();
62 
63   ASSERT_TRUE (ggc_marked_p (root_test_struct));
64   ASSERT_TRUE (ggc_marked_p (root_test_struct->other));
65 }
66 
67 
68 
69 /* Selftest for GTY((length)).  */
70 
71 /* A test struct using GTY((length)).  */
72 
73 struct GTY(()) test_of_length
74 {
75   int num_elem;
76   struct test_of_length * GTY ((length ("%h.num_elem"))) elem[1];
77 };
78 
79 static GTY(()) test_of_length *root_test_of_length;
80 
81 static void
82 test_length ()
83 {
84   const int count = 5;
85   size_t sz = sizeof (test_of_length) + (count- 1) * sizeof (test_of_length *);
86   root_test_of_length = (test_of_length *)ggc_internal_cleared_alloc (sz);
87   root_test_of_length->num_elem = count;
88   for (int i = 0; i < count; i++)
89     root_test_of_length->elem[i] = ggc_cleared_alloc <test_of_length> ();
90 
91   selftest::forcibly_ggc_collect ();
92 
93   ASSERT_TRUE (ggc_marked_p (root_test_of_length));
94   for (int i = 0; i < count; i++)
95     ASSERT_TRUE (ggc_marked_p (root_test_of_length->elem[i]));
96 }
97 
98 
99 
100 /* Selftest for unions, GTY((tag)), and GTY((desc)).  */
101 
102 /* A struct with a reference that's an a different offset to test_struct,
103    to ensure that we're using the correct types.  */
104 
105 struct GTY(()) test_other
106 {
107   char dummy[256];
108   test_struct *m_ptr;
109 };
110 
111 enum which_field
112 {
113   WHICH_FIELD_USE_TEST_STRUCT,
114   WHICH_FIELD_USE_TEST_OTHER
115 };
116 
117 /* An example function for use by a GTY((desc)) marker.  */
118 
119 static enum which_field
120 calc_desc (int kind)
121 {
122   switch (kind)
123     {
124     case 0: return WHICH_FIELD_USE_TEST_STRUCT;
125     case 1: return WHICH_FIELD_USE_TEST_OTHER;
126     default:
127       gcc_unreachable ();
128     }
129 }
130 
131 /* A struct containing an example of a union, showing the "tag" and
132    "desc" markers.  */
133 
134 struct GTY(()) test_of_union
135 {
136   int m_kind;
137   union u {
138     test_struct * GTY ((tag ("WHICH_FIELD_USE_TEST_STRUCT") )) u_test_struct;
139     test_other * GTY ((tag ("WHICH_FIELD_USE_TEST_OTHER") )) u_test_other;
140   } GTY ((desc ("calc_desc (%0.m_kind)"))) m_u;
141 };
142 
143 /* Example roots.  */
144 
145 static GTY(()) test_of_union *root_test_of_union_1;
146 static GTY(()) test_of_union *root_test_of_union_2;
147 
148 /* Verify that the above work correctly.  */
149 
150 static void
151 test_union ()
152 {
153   root_test_of_union_1 = ggc_cleared_alloc <test_of_union> ();
154   root_test_of_union_1->m_kind = 0;
155   test_struct *ts = ggc_cleared_alloc <test_struct> ();
156   root_test_of_union_1->m_u.u_test_struct = ts;
157 
158   root_test_of_union_2 = ggc_cleared_alloc <test_of_union> ();
159   root_test_of_union_2->m_kind = 1;
160   test_other *other = ggc_cleared_alloc <test_other> ();
161   root_test_of_union_2->m_u.u_test_other = other;
162   test_struct *referenced_by_other = ggc_cleared_alloc <test_struct> ();
163   other->m_ptr = referenced_by_other;
164 
165   selftest::forcibly_ggc_collect ();
166 
167   ASSERT_TRUE (ggc_marked_p (root_test_of_union_1));
168   ASSERT_TRUE (ggc_marked_p (ts));
169 
170   ASSERT_TRUE (ggc_marked_p (root_test_of_union_2));
171   ASSERT_TRUE (ggc_marked_p (other));
172   ASSERT_TRUE (ggc_marked_p (referenced_by_other));
173 }
174 
175 
176 
177 /* Verify that destructors get run when instances are collected.  */
178 
179 struct GTY(()) test_struct_with_dtor
180 {
181   /* This struct has a destructor; it *ought* to be called
182      by the ggc machinery when instances are collected.  */
183   ~test_struct_with_dtor () { dtor_call_count++; }
184 
185   static int dtor_call_count;
186 };
187 
188 int test_struct_with_dtor::dtor_call_count;
189 
190 static void
191 test_finalization ()
192 {
193 #if GCC_VERSION >= 4003
194   ASSERT_FALSE (need_finalization_p <test_struct> ());
195   ASSERT_TRUE (need_finalization_p <test_struct_with_dtor> ());
196 #endif
197 
198   /* Create some garbage.  */
199   const int count = 10;
200   for (int i = 0; i < count; i++)
201     ggc_cleared_alloc <test_struct_with_dtor> ();
202 
203   test_struct_with_dtor::dtor_call_count = 0;
204 
205   selftest::forcibly_ggc_collect ();
206 
207   /* Verify that the destructor was run for each instance.  */
208   ASSERT_EQ (count, test_struct_with_dtor::dtor_call_count);
209 }
210 
211 
212 
213 /* Verify that a global can be marked as "deletable".  */
214 
215 static GTY((deletable)) test_struct *test_of_deletable;
216 
217 static void
218 test_deletable_global ()
219 {
220   test_of_deletable = ggc_cleared_alloc <test_struct> ();
221   ASSERT_TRUE (test_of_deletable != NULL);
222 
223   selftest::forcibly_ggc_collect ();
224 
225   ASSERT_EQ (NULL, test_of_deletable);
226 }
227 
228 
229 
230 /* Verify that gengtype etc can cope with inheritance.  */
231 
232 class GTY((desc("%h.m_kind"), tag("0"))) example_base
233 {
234  public:
235   example_base ()
236     : m_kind (0),
237       m_a (ggc_cleared_alloc <test_struct> ())
238   {}
239 
240   void *
241   operator new (size_t sz)
242   {
243     return ggc_internal_cleared_alloc (sz);
244   }
245 
246  protected:
247   example_base (int kind)
248     : m_kind (kind),
249       m_a (ggc_cleared_alloc <test_struct> ())
250   {}
251 
252  public:
253   int m_kind;
254   test_struct *m_a;
255 };
256 
257 class GTY((tag("1"))) some_subclass : public example_base
258 {
259  public:
260   some_subclass ()
261     : example_base (1),
262       m_b (ggc_cleared_alloc <test_struct> ())
263   {}
264 
265   test_struct *m_b;
266 };
267 
268 class GTY((tag("2"))) some_other_subclass : public example_base
269 {
270  public:
271   some_other_subclass ()
272     : example_base (2),
273       m_c (ggc_cleared_alloc <test_struct> ())
274   {}
275 
276   test_struct *m_c;
277 };
278 
279 /* Various test roots, both expressed as a ptr to the actual class, and
280    as a ptr to the base class.  */
281 static GTY(()) example_base *test_example_base;
282 static GTY(()) some_subclass *test_some_subclass;
283 static GTY(()) some_other_subclass *test_some_other_subclass;
284 static GTY(()) example_base *test_some_subclass_as_base_ptr;
285 static GTY(()) example_base *test_some_other_subclass_as_base_ptr;
286 
287 static void
288 test_inheritance ()
289 {
290   test_example_base = new example_base ();
291   test_some_subclass = new some_subclass ();
292   test_some_other_subclass = new some_other_subclass ();
293   test_some_subclass_as_base_ptr = new some_subclass ();
294   test_some_other_subclass_as_base_ptr = new some_other_subclass ();
295 
296   selftest::forcibly_ggc_collect ();
297 
298   /* Verify that the roots and everything referenced by them got marked
299      (both for fields in the base class and those in subclasses).  */
300   ASSERT_TRUE (ggc_marked_p (test_example_base));
301   ASSERT_TRUE (ggc_marked_p (test_example_base->m_a));
302 
303   ASSERT_TRUE (ggc_marked_p (test_some_subclass));
304   ASSERT_TRUE (ggc_marked_p (test_some_subclass->m_a));
305   ASSERT_TRUE (ggc_marked_p (test_some_subclass->m_b));
306 
307   ASSERT_TRUE (ggc_marked_p (test_some_other_subclass));
308   ASSERT_TRUE (ggc_marked_p (test_some_other_subclass->m_a));
309   ASSERT_TRUE (ggc_marked_p (test_some_other_subclass->m_c));
310 
311   ASSERT_TRUE (ggc_marked_p (test_some_subclass_as_base_ptr));
312   ASSERT_TRUE (ggc_marked_p (test_some_subclass_as_base_ptr->m_a));
313   ASSERT_TRUE (ggc_marked_p (((some_subclass *)
314 			      test_some_subclass_as_base_ptr)->m_b));
315 
316   ASSERT_TRUE (ggc_marked_p (test_some_other_subclass_as_base_ptr));
317   ASSERT_TRUE (ggc_marked_p (test_some_other_subclass_as_base_ptr->m_a));
318   ASSERT_TRUE (ggc_marked_p (((some_other_subclass *)
319 			      test_some_other_subclass_as_base_ptr)->m_c));
320 }
321 
322 
323 
324 /* Test of chain_next/chain_prev
325 
326    Construct a very long linked list, so that without
327    the chain_next/chain_prev optimization we'd have
328    a stack overflow when gt_ggc_mx_test_node recurses.  */
329 
330 struct GTY(( chain_next ("%h.m_next"),
331 	     chain_prev ("%h.m_prev") )) test_node
332 {
333   test_node *m_prev;
334   test_node *m_next;
335   int m_idx;
336 };
337 
338 static GTY(()) test_node *root_test_node;
339 
340 static void
341 test_chain_next ()
342 {
343   /* Ideally we would construct a long list so that the number of
344      stack frames would be deep enough to crash if gengtype has created
345      something that recurses.
346 
347      However, as the list is lengthened to increase the chance of
348      overflowing the stack, the test will require more time and memory
349      to run.  On a Fedora 20 x86_64 box with 128GB of RAM, count=2000000
350      without the chain_next optimization reliably overflowed the stack,
351      but the test took 0.5s to run.
352 
353      For now this test runs with a low value for "count", which defeats
354      the main purpose of the test - though it at least gives us coverage
355      for walking a GTY((chain_next)) list.
356 
357      We could potentially increase this value once we have a better sense
358      of the time and space requirements of the test on different hosts,
359      or perhaps find a way to reduce the stack size when running this
360      testcase.  */
361   const int count = 10;
362 
363   /* Build the linked list.  */
364   root_test_node = ggc_cleared_alloc <test_node> ();
365   test_node *tail_node = root_test_node;
366   for (int i = 0; i < count; i++)
367     {
368       test_node *new_node = ggc_cleared_alloc <test_node> ();
369       tail_node->m_next = new_node;
370       new_node->m_prev = tail_node;
371       new_node->m_idx = i;
372       tail_node = new_node;
373     }
374 
375   selftest::forcibly_ggc_collect ();
376 
377   /* If we got here, we survived.  */
378 
379   /* Verify that all nodes in the list were marked.  */
380   ASSERT_TRUE (ggc_marked_p (root_test_node));
381   test_node *iter_node = root_test_node->m_next;
382   for (int i = 0; i < count; i++)
383     {
384       ASSERT_TRUE (ggc_marked_p (iter_node));
385       ASSERT_EQ (i, iter_node->m_idx);
386       iter_node = iter_node->m_next;
387     }
388 }
389 
390 
391 
392 /* Test for GTY((user)).  */
393 
394 struct GTY((user)) user_struct
395 {
396   char dummy[16];
397   test_struct *m_ptr;
398 };
399 
400 static GTY(()) user_struct *root_user_struct_ptr;
401 
402 /* A global for verifying that the user-provided gt_ggc_mx gets
403    called.  */
404 static int num_calls_to_user_gt_ggc_mx;
405 
406 /* User-provided implementation of gt_ggc_mx.  */
407 
408 static void
409 gt_ggc_mx (user_struct *p)
410 {
411   num_calls_to_user_gt_ggc_mx++;
412   gt_ggc_mx_test_struct (p->m_ptr);
413 }
414 
415 /* User-provided implementation of gt_pch_nx.  */
416 
417 static void
418 gt_pch_nx (user_struct *p)
419 {
420   gt_pch_nx_test_struct (p->m_ptr);
421 }
422 
423 /* User-provided implementation of gt_pch_nx.  */
424 
425 static void
426 gt_pch_nx (user_struct *p, gt_pointer_operator op, void *cookie)
427 {
428   op (&(p->m_ptr), cookie);
429 }
430 
431 /* Verify that GTY((user)) works.  */
432 
433 static void
434 test_user_struct ()
435 {
436   root_user_struct_ptr = ggc_cleared_alloc <user_struct> ();
437   test_struct *referenced = ggc_cleared_alloc <test_struct> ();
438   root_user_struct_ptr->m_ptr = referenced;
439 
440   num_calls_to_user_gt_ggc_mx = 0;
441 
442   selftest::forcibly_ggc_collect ();
443 
444   ASSERT_TRUE (ggc_marked_p (root_user_struct_ptr));
445   ASSERT_TRUE (ggc_marked_p (referenced));
446   ASSERT_TRUE (num_calls_to_user_gt_ggc_mx > 0);
447 }
448 
449 
450 
451 /* Smoketest to ensure that the tree type is marked.  */
452 
453 static GTY(()) tree dummy_unittesting_tree;
454 
455 static void
456 test_tree_marking ()
457 {
458   dummy_unittesting_tree = build_int_cst (integer_type_node, 1066);
459 
460   selftest::forcibly_ggc_collect ();
461 
462   ASSERT_TRUE (ggc_marked_p (dummy_unittesting_tree));
463 }
464 
465 
466 
467 /* Ideas for other tests:
468    - pch-handling  */
469 
470 namespace selftest {
471 
472 /* Run all of the selftests within this file.  */
473 
474 void
475 ggc_tests_c_tests ()
476 {
477   test_basic_struct ();
478   test_length ();
479   test_union ();
480   test_finalization ();
481   test_deletable_global ();
482   test_inheritance ();
483   test_chain_next ();
484   test_user_struct ();
485   test_tree_marking ();
486 }
487 
488 } // namespace selftest
489 
490 #include "gt-ggc-tests.h"
491 
492 #else /* #if CHECKING_P */
493 
494 /* The #if CHECKING_P code above has various GTY-marked roots.
495    gengtype has no knowledge of the preprocessor, and so detects
496    these roots and writes them out to gt-ggc-tests.h.
497    In a !CHECKING_P build we can ignore gt-ggc-tests.h, but the
498    root tables are referenced in the various generated gtype-*.c
499    files like this:
500 
501       ...snip...
502       extern const struct ggc_root_tab gt_ggc_r_gt_ggc_tests_h[];
503       ...snip...
504 
505       EXPORTED_CONST struct ggc_root_tab * const gt_ggc_rtab[] = {
506         ...snip...
507         gt_ggc_r_gt_ggc_tests_h,
508         ...snip...
509       };
510 
511     Hence to avoid a link failure, we provide dummy implementations
512     of these root tables in an unchecked build.
513 
514     Note that these conditional roots imply that PCH files are
515     incompatible between checked and unchecked builds.  */
516 
517 EXPORTED_CONST struct ggc_root_tab gt_ggc_r_gt_ggc_tests_h[] = {
518   LAST_GGC_ROOT_TAB
519 };
520 
521 EXPORTED_CONST struct ggc_root_tab gt_ggc_rd_gt_ggc_tests_h[] = {
522   LAST_GGC_ROOT_TAB
523 };
524 
525 #endif /* #else clause of #if CHECKING_P */
526