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]

collecting struct function


We seem to have two different things aimed at the same job --
f->can_garbage_collect = 1 and DECL_DEFER_OUTPUT (f->decl).

Frankly, I don't really understand f->can_garbage_collect.
If we can collect it, why aren't we just freeing up the 
struct function bits that lead to it so that we don't find
it during mark+sweep?

The following changes eliminate memory leaks from the 
struct function heirarchy.  It could stand to be tidied a
bit, but I want to know yall's thoughts on the above before
I do anything with it.

Oh, the addition of `f->decl &&' to the DECL_DEFER_OUTPUT
test is due to init_dummy_function_start.  We could just
allocate a dummy decl node to go in there instead.


r~


	* emit-rtl.c (free_emit_status): Check f->decl nonnull before
	checking for defered output.  Free the emit struct.
	* except.c (mark_eh_state): Check nonnull before marking.
	(free_eh_status): New.
	* expr.c (mark_expr_state): New.
	(free_expr_status): New.
	* function.c (free_after_compilation): Call free_expr_status. 
	Check f->decl nonnull.
	(expand_dummy_function_end): Call free_after_compilation; free
	current_function.
	(mark_function_chain): Move expr code to mark_expr_state.
	* function.h (free_eh_status, free_expr_status): Declare.
	* ggc.h (mark_expr_status): Declare.
	* stmt.c (free_stmt_status): Free the stmt struct. 
	Call free_eh_status.
	* varasm.c (mark_varasm_state): Check nonnull before marking.
	(free_varasm_status): Check f->decl nonnull.  Free the struct.
	

Index: emit-rtl.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/emit-rtl.c,v
retrieving revision 1.84
diff -c -p -d -r1.84 emit-rtl.c
*** emit-rtl.c	1999/09/09 18:55:34	1.84
--- emit-rtl.c	1999/09/11 19:57:10
*************** void
*** 1615,1627 ****
  free_emit_status (f)
       struct function *f;
  {
!   if (DECL_DEFER_OUTPUT (f->decl))
      return;
  
    free (f->emit->x_regno_reg_rtx);
    free (f->emit->regno_pointer_flag);
    free (f->emit->regno_pointer_align);
!   f->emit->x_regno_reg_rtx = 0;
  }
  
  /* Go through all the RTL insn bodies and copy any invalid shared structure.
--- 1615,1628 ----
  free_emit_status (f)
       struct function *f;
  {
!   if (f->decl && DECL_DEFER_OUTPUT (f->decl))
      return;
  
    free (f->emit->x_regno_reg_rtx);
    free (f->emit->regno_pointer_flag);
    free (f->emit->regno_pointer_align);
!   free (f->emit);
!   f->emit = NULL;
  }
  
  /* Go through all the RTL insn bodies and copy any invalid shared structure.
Index: except.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/except.c,v
retrieving revision 1.98
diff -c -p -d -r1.98 except.c
*** except.c	1999/09/10 20:28:12	1.98
--- except.c	1999/09/11 19:57:10
*************** void
*** 2408,2413 ****
--- 2408,2416 ----
  mark_eh_state (eh)
       struct eh_status *eh;
  {
+   if (eh == 0)
+     return;
+ 
    mark_eh_stack (&eh->x_ehstack);
    mark_eh_stack (&eh->x_catchstack);
    mark_eh_queue (&eh->x_ehqueue);
*************** init_eh ()
*** 2479,2485 ****
  void
  init_eh_for_function ()
  {
!   current_function->eh = (struct eh_status *) xmalloc (sizeof (struct eh_status));
  
    ehstack.top = 0;
    catchstack.top = 0;
--- 2482,2489 ----
  void
  init_eh_for_function ()
  {
!   current_function->eh
!     = (struct eh_status *) xmalloc (sizeof (struct eh_status));
  
    ehstack.top = 0;
    catchstack.top = 0;
*************** init_eh_for_function ()
*** 2493,2498 ****
--- 2497,2515 ----
    eh_return_stack_adjust = NULL_RTX;
    eh_return_handler = NULL_RTX;
    eh_return_stub_label = NULL_RTX;
+ }
+ 
+ void
+ free_eh_status (f)
+      struct function *f;
+ {
+   /* Need to keep eh_return_stub_label for code generation.  */
+ 
+   if (f->decl && DECL_DEFER_OUTPUT (f->decl))
+     return;
+ 
+   free (f->eh);
+   f->eh = NULL;
  }
  
  /* This section is for the exception handling specific optimization
Index: expr.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/expr.c,v
retrieving revision 1.167
diff -c -p -d -r1.167 expr.c
*** expr.c	1999/09/07 05:47:45	1.167
--- expr.c	1999/09/11 19:57:10
*************** init_expr ()
*** 290,295 ****
--- 290,320 ----
    forced_labels = 0;
  }
  
+ void
+ mark_expr_state (p)
+      struct expr_status *p;
+ {
+   if (p == NULL)
+     return;
+ 
+   ggc_mark_rtx (p->x_saveregs_value);
+   ggc_mark_rtx (p->x_apply_args_value);
+   ggc_mark_rtx (p->x_forced_labels);
+ }
+ 
+ void
+ free_expr_status (f)
+      struct function *f;
+ {
+   /* Need to keep forced_labels for code generation.  */
+ 
+   if (f->decl && DECL_DEFER_OUTPUT (f->decl))
+     return;
+ 
+   free (f->expr);
+   f->expr = NULL;
+ }
+ 
  /* Small sanity check that the queue is empty at the end of a function.  */
  void
  finish_expr_for_function ()
Index: function.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/function.c,v
retrieving revision 1.111
diff -c -p -d -r1.111 function.c
*** function.c	1999/09/09 23:04:12	1.111
--- function.c	1999/09/11 19:57:11
*************** void
*** 397,409 ****
  free_after_compilation (f)
       struct function *f;
  {
    free_emit_status (f);
    free_varasm_status (f);
    free_stmt_status (f);
    if (free_lang_status)
      (*free_lang_status) (f);
  
!   if (!DECL_DEFER_OUTPUT (f->decl))
      {
        free (f->x_parm_reg_stack_loc);
        f->can_garbage_collect = 1;
--- 397,410 ----
  free_after_compilation (f)
       struct function *f;
  {
+   free_expr_status (f);
    free_emit_status (f);
    free_varasm_status (f);
    free_stmt_status (f);
    if (free_lang_status)
      (*free_lang_status) (f);
  
!   if (!f->decl || !DECL_DEFER_OUTPUT (f->decl))
      {
        free (f->x_parm_reg_stack_loc);
        f->can_garbage_collect = 1;
*************** expand_dummy_function_end ()
*** 6000,6005 ****
--- 6001,6009 ----
  
    /* Outside function body, can't compute type's actual size
       until next function's body starts.  */
+ 
+   free_after_compilation (current_function);
+   free (current_function);
    current_function = 0;
  }
  
*************** mark_function_chain (arg)
*** 6753,6762 ****
        mark_eh_state (f->eh);
        mark_emit_state (f->emit);
        mark_varasm_state (f->varasm);
! 
!       ggc_mark_rtx (f->expr->x_saveregs_value);
!       ggc_mark_rtx (f->expr->x_apply_args_value);
!       ggc_mark_rtx (f->expr->x_forced_labels);
  
        if (mark_machine_status)
  	(*mark_machine_status) (f);
--- 6757,6763 ----
        mark_eh_state (f->eh);
        mark_emit_state (f->emit);
        mark_varasm_state (f->varasm);
!       mark_expr_state (f->expr);
  
        if (mark_machine_status)
  	(*mark_machine_status) (f);
Index: function.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/function.h,v
retrieving revision 1.30
diff -c -p -d -r1.30 function.h
*** function.h	1999/09/09 18:55:34	1.30
--- function.h	1999/09/11 19:57:11
*************** extern void init_varasm_status		PROTO((s
*** 557,562 ****
--- 557,565 ----
  extern void free_varasm_status		PROTO((struct function *));
  extern void free_emit_status		PROTO((struct function *));
  extern void free_stmt_status            PROTO((struct function *));
+ extern void free_eh_status		PROTO((struct function *));
+ extern void free_expr_status		PROTO((struct function *));
+ 
  extern rtx get_first_block_beg		PROTO((void));
  
  extern void init_virtual_regs		PROTO((struct emit_status *));
Index: ggc.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/ggc.h,v
retrieving revision 1.11
diff -c -p -d -r1.11 ggc.h
*** ggc.h	1999/09/11 19:50:42	1.11
--- ggc.h	1999/09/11 19:57:11
*************** extern int ggc_p;
*** 33,38 ****
--- 33,39 ----
     just forward-declare them here.  */
  struct eh_status;
  struct emit_status;
+ struct expr_status;
  struct hash_table;
  struct label_node;
  struct rtvec_def;
*************** void lang_mark_false_label_stack PROTO (
*** 122,128 ****
  /* Mark functions for various structs scattered about.  */
  
  void mark_eh_state PROTO ((struct eh_status *));
- void mark_stmt_state PROTO ((struct stmt_status *));
  void mark_emit_state PROTO ((struct emit_status *));
  void mark_varasm_state PROTO ((struct varasm_status *));
  void mark_optab PROTO ((void *));
--- 123,130 ----
  /* Mark functions for various structs scattered about.  */
  
  void mark_eh_state PROTO ((struct eh_status *));
  void mark_emit_state PROTO ((struct emit_status *));
+ void mark_expr_status PROTO ((struct expr_status *));
+ void mark_stmt_state PROTO ((struct stmt_status *));
  void mark_varasm_state PROTO ((struct varasm_status *));
  void mark_optab PROTO ((void *));
Index: stmt.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/stmt.c,v
retrieving revision 1.87
diff -c -p -d -r1.87 stmt.c
*** stmt.c	1999/09/09 18:55:36	1.87
--- stmt.c	1999/09/11 19:57:11
*************** free_stmt_status (f)
*** 561,567 ****
    /* We're about to free the function obstack.  If we hold pointers to
       things allocated there, then we'll try to mark them when we do
       GC.  So, we clear them out here explicitly.  */
!   f->stmt->x_goto_fixup_chain = 0;
  }
  
  /* Mark P for GC.  */
--- 561,571 ----
    /* We're about to free the function obstack.  If we hold pointers to
       things allocated there, then we'll try to mark them when we do
       GC.  So, we clear them out here explicitly.  */
! 
!   free (f->stmt);
!   f->stmt = NULL;
! 
!   free_eh_status (f);
  }
  
  /* Mark P for GC.  */
Index: varasm.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/varasm.c,v
retrieving revision 1.79
diff -c -p -d -r1.79 varasm.c
*** varasm.c	1999/09/09 18:55:37	1.79
--- varasm.c	1999/09/11 19:57:11
*************** mark_pool_sym_hash_table (pps)
*** 3226,3233 ****
  
  void
  mark_varasm_state (p)
!   struct varasm_status *p;
  {
    mark_pool_constant (p->x_first_pool);
    mark_pool_sym_hash_table (p->x_const_rtx_sym_hash_table);
    ggc_mark_rtx (p->x_const_double_chain);
--- 3226,3236 ----
  
  void
  mark_varasm_state (p)
!      struct varasm_status *p;
  {
+   if (p == NULL)
+     return;
+ 
    mark_pool_constant (p->x_first_pool);
    mark_pool_sym_hash_table (p->x_const_rtx_sym_hash_table);
    ggc_mark_rtx (p->x_const_double_chain);
*************** free_varasm_status (f)
*** 3243,3259 ****
  {
    struct varasm_status *p;
  
!   if (DECL_DEFER_OUTPUT (f->decl))
      return;
  
    p = f->varasm;
    free (p->x_const_rtx_hash_table);
    free (p->x_const_rtx_sym_hash_table);
! 
!   p->x_first_pool = p->x_last_pool = 0;
!   p->x_const_rtx_hash_table = 0;
!   p->x_const_rtx_sym_hash_table = 0;
!   p->x_const_double_chain = 0;
  }
  
  enum kind { RTX_DOUBLE, RTX_INT };
--- 3246,3259 ----
  {
    struct varasm_status *p;
  
!   if (f->decl && DECL_DEFER_OUTPUT (f->decl))
      return;
  
    p = f->varasm;
    free (p->x_const_rtx_hash_table);
    free (p->x_const_rtx_sym_hash_table);
!   free (p);
!   f->varasm = NULL;
  }
  
  enum kind { RTX_DOUBLE, RTX_INT };


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