diff mbox

RFA (GGC): PATCH to support GGC finalizers with PCH

Message ID 564B352B.8090005@redhat.com
State New
Headers show

Commit Message

Jason Merrill Nov. 17, 2015, 2:09 p.m. UTC
While I was looking at the interaction of delayed folding with GGC, I 
noticed that ggc_handle_finalizers currently runs no finalizers if 
G.context_depth != 0.  So any GC objects in a greater depth will still 
be collected, but they won't have their finalizers run.  This 
specifically affects compiles that use a PCH file, since G.context_depth 
is set to 1 after loading the PCH.

This patch fixes ggc_handle_finalizers to look at the depth of each 
finalizer so that we still don't try to run finalizers for 
non-collectable objects loaded from the PCH, but we do run finalizers 
for collectable objects allocated after loading the PCH.

I ended up not relying on this for delayed folding, but it still seems 
like a good bug fix.

Tested x86_64-pc-linux-gnu.  OK for trunk?

Comments

Richard Biener Nov. 17, 2015, 2:39 p.m. UTC | #1
On Tue, Nov 17, 2015 at 3:09 PM, Jason Merrill <jason@redhat.com> wrote:
> While I was looking at the interaction of delayed folding with GGC, I
> noticed that ggc_handle_finalizers currently runs no finalizers if
> G.context_depth != 0.  So any GC objects in a greater depth will still be
> collected, but they won't have their finalizers run.  This specifically
> affects compiles that use a PCH file, since G.context_depth is set to 1
> after loading the PCH.
>
> This patch fixes ggc_handle_finalizers to look at the depth of each
> finalizer so that we still don't try to run finalizers for non-collectable
> objects loaded from the PCH, but we do run finalizers for collectable
> objects allocated after loading the PCH.
>
> I ended up not relying on this for delayed folding, but it still seems like
> a good bug fix.
>
> Tested x86_64-pc-linux-gnu.  OK for trunk?

Hmm, this enlarges finalizer/vec_finalizer.  Wouldn't it be better to
add separate finalizer vectors for context_depth != 0?  (I'm proposing
to add one for exactly context_depth == 1)

When is context_depth increased other than for PCH?

Richard.
diff mbox

Patch

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.

diff --git a/gcc/ggc-page.c b/gcc/ggc-page.c
index deb21bb..1d5aeef 100644
--- a/gcc/ggc-page.c
+++ b/gcc/ggc-page.c
@@ -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);