This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


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?
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);

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]