Commit 2a304777 by Jason Merrill Committed by Jason Merrill

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
parent 231f6e09
2015-11-18 Jason Merrill <jason@redhat.com>
* 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 <sandra@codesourcery.com> 2015-11-18 Sandra Loosemore <sandra@codesourcery.com>
PR target/68410 PR target/68410
...@@ -361,7 +361,7 @@ private: ...@@ -361,7 +361,7 @@ private:
void (*m_function)(void *); void (*m_function)(void *);
size_t m_object_size; size_t m_object_size;
size_t m_n_objects; size_t m_n_objects;
}; };
#ifdef ENABLE_GC_ALWAYS_COLLECT #ifdef ENABLE_GC_ALWAYS_COLLECT
/* List of free objects to be verified as actually free on the /* List of free objects to be verified as actually free on the
...@@ -456,11 +456,11 @@ static struct ggc_globals ...@@ -456,11 +456,11 @@ static struct ggc_globals
better runtime data access pattern. */ better runtime data access pattern. */
unsigned long **save_in_use; unsigned long **save_in_use;
/* Finalizers for single objects. */ /* Finalizers for single objects. The first index is collection_depth. */
vec<finalizer> finalizers; vec<vec<finalizer> > finalizers;
/* Finalizers for vectors of objects. */ /* Finalizers for vectors of objects. */
vec<vec_finalizer> vec_finalizers; vec<vec<vec_finalizer> > vec_finalizers;
#ifdef ENABLE_GC_ALWAYS_COLLECT #ifdef ENABLE_GC_ALWAYS_COLLECT
/* List of free objects to be verified as actually free on the /* List of free objects to be verified as actually free on the
...@@ -1240,6 +1240,25 @@ ggc_round_alloc_size (size_t requested_size) ...@@ -1240,6 +1240,25 @@ ggc_round_alloc_size (size_t requested_size)
return 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<uintptr_t> (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. */ /* Allocate a chunk of memory of SIZE bytes. Its contents are undefined. */
void * void *
...@@ -1387,11 +1406,8 @@ ggc_internal_alloc (size_t size, void (*f)(void *), size_t s, size_t n ...@@ -1387,11 +1406,8 @@ ggc_internal_alloc (size_t size, void (*f)(void *), size_t s, size_t n
/* For timevar statistics. */ /* For timevar statistics. */
timevar_ggc_mem_total += object_size; timevar_ggc_mem_total += object_size;
if (f && n == 1) if (f)
G.finalizers.safe_push (finalizer (result, f)); add_finalizer (result, f, s, n);
else if (f)
G.vec_finalizers.safe_push
(vec_finalizer (reinterpret_cast<uintptr_t> (result), f, s, n));
if (GATHER_STATISTICS) if (GATHER_STATISTICS)
{ {
...@@ -1788,6 +1804,11 @@ init_ggc (void) ...@@ -1788,6 +1804,11 @@ init_ggc (void)
G.by_depth_max = INITIAL_PTE_COUNT; G.by_depth_max = INITIAL_PTE_COUNT;
G.by_depth = XNEWVEC (page_entry *, G.by_depth_max); G.by_depth = XNEWVEC (page_entry *, G.by_depth_max);
G.save_in_use = XNEWVEC (unsigned long *, 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 /* 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) ...@@ -1875,36 +1896,42 @@ clear_marks (void)
static void static void
ggc_handle_finalizers () ggc_handle_finalizers ()
{ {
if (G.context_depth != 0) unsigned dlen = G.finalizers.length();
return; for (unsigned d = G.context_depth; d < dlen; ++d)
unsigned length = G.finalizers.length ();
for (unsigned int i = 0; i < length;)
{ {
finalizer &f = G.finalizers[i]; vec<finalizer> &v = G.finalizers[d];
if (!ggc_marked_p (f.addr ())) unsigned length = v.length ();
for (unsigned int i = 0; i < length;)
{ {
f.call (); finalizer &f = v[i];
G.finalizers.unordered_remove (i); if (!ggc_marked_p (f.addr ()))
length--; {
f.call ();
v.unordered_remove (i);
length--;
}
else
i++;
} }
else
i++;
} }
gcc_assert (dlen == G.vec_finalizers.length());
length = G.vec_finalizers.length (); for (unsigned d = G.context_depth; d < dlen; ++d)
for (unsigned int i = 0; i < length;)
{ {
vec_finalizer &f = G.vec_finalizers[i]; vec<vec_finalizer> &vv = G.vec_finalizers[d];
if (!ggc_marked_p (f.addr ())) unsigned length = vv.length ();
for (unsigned int i = 0; i < length;)
{ {
f.call (); vec_finalizer &f = vv[i];
G.vec_finalizers.unordered_remove (i); if (!ggc_marked_p (f.addr ()))
length--; {
f.call ();
vv.unordered_remove (i);
length--;
}
else
i++;
} }
else
i++;
} }
} }
...@@ -2545,6 +2572,10 @@ ggc_pch_read (FILE *f, void *addr) ...@@ -2545,6 +2572,10 @@ ggc_pch_read (FILE *f, void *addr)
pages to be 1 too. PCH pages will have depth 0. */ pages to be 1 too. PCH pages will have depth 0. */
gcc_assert (!G.context_depth); gcc_assert (!G.context_depth);
G.context_depth = 1; 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++) for (i = 0; i < NUM_ORDERS; i++)
{ {
page_entry *p; page_entry *p;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment