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]

[commited] Avoid memory leak caused by cgraph edges pointing to call_exprs


Hi,
another reason for good portion of function bodies to remain allocated
after compilation is the cgraph still pointing to call_exprs and another
minor leak in cgraph_remove_node forgetting to kill DECL_INITIAL.

The whole memory management issue in cgraph probably deserve better
organization.  I've made some changes yesterday but I will probably
delay it for post 3.5.

Bootstrapped&regtested i686-pc-gnu-linux and I am going to commit it
now.

2004-09-07  Jan Hubicka  <jh@suse.cz>
	* cgraph.c (cgraph_remove_node): Free DECL_INITIAL field of node.
	* cgraphunit.c (verify_cgraph): Don't verify on syntax errors.
	(cgraph_expand_function): Remove stale cgraph edges of currently
	compiled function; fix non-unit-at-a-time code copying function
	node for later reuse.
Index: cgraph.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cgraph.c,v
retrieving revision 1.54
diff -c -3 -p -r1.54 cgraph.c
*** cgraph.c	6 Sep 2004 10:07:45 -0000	1.54
--- cgraph.c	7 Sep 2004 14:14:02 -0000
*************** cgraph_remove_node (struct cgraph_node *
*** 360,365 ****
--- 360,366 ----
  	{
  	  DECL_SAVED_TREE (node->decl) = NULL;
  	  DECL_STRUCT_FUNCTION (node->decl) = NULL;
+           DECL_INITIAL (node->decl) = error_mark_node;
  	}
      }
    cgraph_n_nodes--;
Index: cgraphunit.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cgraphunit.c,v
retrieving revision 1.74
diff -c -3 -p -r1.74 cgraphunit.c
*** cgraphunit.c	6 Sep 2004 10:07:45 -0000	1.74
--- cgraphunit.c	7 Sep 2004 14:14:03 -0000
*************** verify_cgraph (void)
*** 611,616 ****
--- 611,619 ----
  {
    struct cgraph_node *node;
  
+   if (sorrycount || errorcount)
+     return;
+ 
    for (node = cgraph_nodes; node; node = node->next)
      verify_cgraph_node (node);
  }
*************** cgraph_expand_function (struct cgraph_no
*** 806,817 ****
      abort ();
  
    current_function_decl = NULL;
!   if (DECL_SAVED_TREE (node->decl)
!       && !cgraph_preserve_function_body_p (node->decl))
      {
        DECL_SAVED_TREE (node->decl) = NULL;
        DECL_STRUCT_FUNCTION (node->decl) = NULL;
        DECL_INITIAL (node->decl) = error_mark_node;
      }
  }
  
--- 809,823 ----
      abort ();
  
    current_function_decl = NULL;
!   if (!cgraph_preserve_function_body_p (node->decl))
      {
        DECL_SAVED_TREE (node->decl) = NULL;
        DECL_STRUCT_FUNCTION (node->decl) = NULL;
        DECL_INITIAL (node->decl) = error_mark_node;
+       /* Elliminate all call edges.  This is important so the call_expr no longer
+ 	 points to the dead function body.  */
+       while (node->callees)
+ 	cgraph_remove_edge (node->callees);
      }
  }
  
Index: tree-optimize.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-optimize.c,v
retrieving revision 2.41
diff -c -3 -p -r2.41 tree-optimize.c
*** tree-optimize.c	6 Sep 2004 10:08:02 -0000	2.41
--- tree-optimize.c	7 Sep 2004 14:14:03 -0000
*************** tree_rest_of_compilation (tree fndecl, b
*** 604,609 ****
--- 604,614 ----
  	}
      }
  
+   /* We are not going to maintain the cgraph edges up to date.
+      Kill it so it won't confuse us.  */
+   while (node->callees)
+     cgraph_remove_edge (node->callees);
+ 
    if (!vars_to_rename)
      vars_to_rename = BITMAP_XMALLOC ();
  
*************** tree_rest_of_compilation (tree fndecl, b
*** 632,639 ****
  	    cgraph_remove_edge (node->callees);
  	  node->callees = saved_node->callees;
  	  saved_node->callees = NULL;
! 	  for (e = saved_node->callees; e; e = e->next_callee)
! 	    e->caller = node;
  	  cgraph_remove_node (saved_node);
  	}
      }
--- 637,648 ----
  	    cgraph_remove_edge (node->callees);
  	  node->callees = saved_node->callees;
  	  saved_node->callees = NULL;
! 	  for (e = node->callees; e; e = e->next_callee)
! 	    {
! 	      if (e->callee->global.inlined_to)
! 		e->callee->global.inlined_to = node;
! 	      e->caller = node;
! 	    }
  	  cgraph_remove_node (saved_node);
  	}
      }


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