commit 0bd746ae39b37b9b08e4d861d97fe30ecf4e8ad8
Author: Jason Merrill <jason@redhat.com>
Date: Fri Nov 13 09:39:15 2015 -0500
Support GGC finalizers with PCH.
* ggc-page.c (class finalizer): Add m_depth field.
(finalizer::finalizer): Initialize it.
(finalizer::depth): Return it.
(class vec_finalizer): Likewise.
(ggc_internal_alloc): Adjust constructor calls.
(ggc_handle_finalizers): Run finalizers that are deep enough.
@@ -331,22 +331,26 @@ typedef struct page_table_chain
class finalizer
{
public:
- finalizer (void *addr, void (*f)(void *)) : m_addr (addr), m_function (f) {}
+ finalizer (void *addr, void (*f)(void *), unsigned short depth)
+ : m_addr (addr), m_function (f), m_depth(depth) {}
void *addr () const { return m_addr; }
-
+ unsigned short depth () const { return m_depth; }
void call () const { m_function (m_addr); }
private:
void *m_addr;
void (*m_function)(void *);
+ unsigned short m_depth;
};
class vec_finalizer
{
public:
- vec_finalizer (uintptr_t addr, void (*f)(void *), size_t s, size_t n) :
- m_addr (addr), m_function (f), m_object_size (s), m_n_objects (n) {}
+ vec_finalizer (uintptr_t addr, void (*f)(void *), size_t s, size_t n,
+ unsigned short depth)
+ : m_addr (addr), m_function (f), m_object_size (s), m_n_objects (n),
+ m_depth (depth) {}
void call () const
{
@@ -355,13 +359,15 @@ public:
}
void *addr () const { return reinterpret_cast<void *> (m_addr); }
+ unsigned short depth () const { return m_depth; }
private:
uintptr_t m_addr;
void (*m_function)(void *);
size_t m_object_size;
size_t m_n_objects;
- };
+ unsigned short m_depth;
+};
#ifdef ENABLE_GC_ALWAYS_COLLECT
/* List of free objects to be verified as actually free on the
@@ -1388,10 +1394,11 @@ ggc_internal_alloc (size_t size, void (*f)(void *), size_t s, size_t n
timevar_ggc_mem_total += object_size;
if (f && n == 1)
- G.finalizers.safe_push (finalizer (result, f));
+ G.finalizers.safe_push (finalizer (result, f, G.context_depth));
else if (f)
G.vec_finalizers.safe_push
- (vec_finalizer (reinterpret_cast<uintptr_t> (result), f, s, n));
+ (vec_finalizer (reinterpret_cast<uintptr_t> (result), f, s, n,
+ G.context_depth));
if (GATHER_STATISTICS)
{
@@ -1875,14 +1882,12 @@ 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;)
{
finalizer &f = G.finalizers[i];
- if (!ggc_marked_p (f.addr ()))
+ if (f.depth() >= G.context_depth
+ && !ggc_marked_p (f.addr ()))
{
f.call ();
G.finalizers.unordered_remove (i);
@@ -1897,7 +1902,8 @@ ggc_handle_finalizers ()
for (unsigned int i = 0; i < length;)
{
vec_finalizer &f = G.vec_finalizers[i];
- if (!ggc_marked_p (f.addr ()))
+ if (f.depth() >= G.context_depth
+ && !ggc_marked_p (f.addr ()))
{
f.call ();
G.vec_finalizers.unordered_remove (i);