From 2a3047773e9cd7553e817486b735b6339ac16fee Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Wed, 18 Nov 2015 15:11:32 -0500 Subject: [PATCH] Support GGC finalizers with PCH. * ggc-page.c (ggc_globals): Change finalizers and vec_finalizers to be vecs of vecs. (add_finalizer): Split out from ggc_internal_alloc. (ggc_handle_finalizers): Run finalizers for the current depth. (init_ggc, ggc_pch_read): Reserve space for finalizers. From-SVN: r230564 --- gcc/ChangeLog | 8 +++++ gcc/ggc-page.c | 93 +++++++++++++++++++++++++++++++++----------------- 2 files changed, 70 insertions(+), 31 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9249f14d74a..635de672c97 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2015-11-18 Jason Merrill + + * ggc-page.c (ggc_globals): Change finalizers and vec_finalizers + to be vecs of vecs. + (add_finalizer): Split out from ggc_internal_alloc. + (ggc_handle_finalizers): Run finalizers for the current depth. + (init_ggc, ggc_pch_read): Reserve space for finalizers. + 2015-11-18 Sandra Loosemore PR target/68410 diff --git a/gcc/ggc-page.c b/gcc/ggc-page.c index deb21bba464..1a285f33f89 100644 --- a/gcc/ggc-page.c +++ b/gcc/ggc-page.c @@ -361,7 +361,7 @@ private: void (*m_function)(void *); size_t m_object_size; size_t m_n_objects; - }; +}; #ifdef ENABLE_GC_ALWAYS_COLLECT /* List of free objects to be verified as actually free on the @@ -456,11 +456,11 @@ static struct ggc_globals better runtime data access pattern. */ unsigned long **save_in_use; - /* Finalizers for single objects. */ - vec finalizers; + /* Finalizers for single objects. The first index is collection_depth. */ + vec > finalizers; /* Finalizers for vectors of objects. */ - vec vec_finalizers; + vec > vec_finalizers; #ifdef ENABLE_GC_ALWAYS_COLLECT /* List of free objects to be verified as actually free on the @@ -1240,6 +1240,25 @@ ggc_round_alloc_size (size_t requested_size) return size; } +/* Push a finalizer onto the appropriate vec. */ + +static void +add_finalizer (void *result, void (*f)(void *), size_t s, size_t n) +{ + if (f == NULL) + /* No finalizer. */; + else if (n == 1) + { + finalizer fin (result, f); + G.finalizers[G.context_depth].safe_push (fin); + } + else + { + vec_finalizer fin (reinterpret_cast (result), f, s, n); + G.vec_finalizers[G.context_depth].safe_push (fin); + } +} + /* Allocate a chunk of memory of SIZE bytes. Its contents are undefined. */ void * @@ -1387,11 +1406,8 @@ ggc_internal_alloc (size_t size, void (*f)(void *), size_t s, size_t n /* For timevar statistics. */ timevar_ggc_mem_total += object_size; - if (f && n == 1) - G.finalizers.safe_push (finalizer (result, f)); - else if (f) - G.vec_finalizers.safe_push - (vec_finalizer (reinterpret_cast (result), f, s, n)); + if (f) + add_finalizer (result, f, s, n); if (GATHER_STATISTICS) { @@ -1788,6 +1804,11 @@ init_ggc (void) G.by_depth_max = INITIAL_PTE_COUNT; G.by_depth = XNEWVEC (page_entry *, G.by_depth_max); G.save_in_use = XNEWVEC (unsigned long *, G.by_depth_max); + + /* Allocate space for the depth 0 finalizers. */ + G.finalizers.safe_push (vNULL); + G.vec_finalizers.safe_push (vNULL); + gcc_assert (G.finalizers.length() == 1); } /* Merge the SAVE_IN_USE_P and IN_USE_P arrays in P so that IN_USE_P @@ -1875,36 +1896,42 @@ clear_marks (void) static void ggc_handle_finalizers () { - if (G.context_depth != 0) - return; - - unsigned length = G.finalizers.length (); - for (unsigned int i = 0; i < length;) + unsigned dlen = G.finalizers.length(); + for (unsigned d = G.context_depth; d < dlen; ++d) { - finalizer &f = G.finalizers[i]; - if (!ggc_marked_p (f.addr ())) + vec &v = G.finalizers[d]; + unsigned length = v.length (); + for (unsigned int i = 0; i < length;) { - f.call (); - G.finalizers.unordered_remove (i); - length--; + finalizer &f = v[i]; + if (!ggc_marked_p (f.addr ())) + { + f.call (); + v.unordered_remove (i); + length--; + } + else + i++; } - else - i++; } - - length = G.vec_finalizers.length (); - for (unsigned int i = 0; i < length;) + gcc_assert (dlen == G.vec_finalizers.length()); + for (unsigned d = G.context_depth; d < dlen; ++d) { - vec_finalizer &f = G.vec_finalizers[i]; - if (!ggc_marked_p (f.addr ())) + vec &vv = G.vec_finalizers[d]; + unsigned length = vv.length (); + for (unsigned int i = 0; i < length;) { - f.call (); - G.vec_finalizers.unordered_remove (i); - length--; + vec_finalizer &f = vv[i]; + if (!ggc_marked_p (f.addr ())) + { + f.call (); + vv.unordered_remove (i); + length--; + } + else + i++; } - else - i++; } } @@ -2545,6 +2572,10 @@ ggc_pch_read (FILE *f, void *addr) pages to be 1 too. PCH pages will have depth 0. */ gcc_assert (!G.context_depth); G.context_depth = 1; + /* Allocate space for the depth 1 finalizers. */ + G.finalizers.safe_push (vNULL); + G.vec_finalizers.safe_push (vNULL); + gcc_assert (G.finalizers.length() == 2); for (i = 0; i < NUM_ORDERS; i++) { page_entry *p; -- 2.30.2