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]

[debuglocus] rewrite debuglocus table for GC


Hi Andrew.

The segments in the debuglocus table contain trees that were allocated
via GC.  Since the debuglocus table is not marked in GC (because it
lives on the heap), these trees are being swiped from under us when
the collector gets called.  Because there's no way to make heap and GC
coexist, I moved all the table into GC memory, and marked it as such.

Bootstrapped on x86-64 Linux.  Tests are almost done, and both C and C++
look good so far :).

OK once tests finish?

p.s. There's a gratuitous change to new_debuglocus_entry(), where we
were calling get_debuglocus_entry() twice for the same entry.  I changed
it to use the cached copy.

	* debuglocus.c: Move DEBUGLOCUS_VEC_SIZE to debuglocus.h.
	Redefine DEBUGLOCUS_VEC_MEM.
	Mark `debugtable' as a GC root.
	(init_debuglocus_table): Adjust for GC'ed table.
	(destroy_debuglocus_table): Same.
	(get_debuglocus_entry): Same.
	(debuglocus_index_from_pointer): Same.
	(new_debuglocus_entry): Same.  Return previously computed dlocus.
	(debuglocus_from_pointer): Fix formatting.
	Include gt-debuglocus.h.
	* debuglocus.h (struct debuglocus_entry_d): Mark with GTY.
	(DEBUGLOCUS_VEC_SIZE): Define.
	(struct debuglocus_segment_d): Define.
	Define vector of debuglocus_segment_d's.
	Remove debuglocus_p vector.
	(struct debuglocus_table_d): Use segments.
	* Makefile.in (debuglocus.o): Depend on gt-debuglocus.h.
	(GTFILES): Add debuglocus.c.

Index: debuglocus.c
===================================================================
--- debuglocus.c	(revision 145618)
+++ debuglocus.c	(working copy)
@@ -45,10 +45,8 @@ along with GCC; see the file COPYING3.  
    allowing for transparent use of source locations on statements.  */
 
   
-#define DEBUGLOCUS_VEC_SIZE	8192
-#define DEBUGLOCUS_VEC_MEM	(DEBUGLOCUS_VEC_SIZE * sizeof (debuglocus))
 #define DEBUGLOCUS_INDEX(LOCUS) ((LOCUS) & ~DEBUGLOCUS_BIT)
-
+#define DEBUGLOCUS_VEC_MEM	(sizeof (struct debuglocus_segment_d))
 
 
 /* Create and initialize a new debuglocus table.  */
@@ -56,12 +54,12 @@ static debuglocus_table_t *
 init_debuglocus_table (void)
 {
   debuglocus_table_t *tab;
-  debuglocus_p dlocus;
+  debuglocus_segment_p seg;
 
-  tab = (debuglocus_table_t *) xmalloc (sizeof (debuglocus_table_t));
-  tab->table = VEC_alloc (debuglocus_p, heap, 100);
-  dlocus = (debuglocus_p) xmalloc (DEBUGLOCUS_VEC_MEM);
-  VEC_safe_push (debuglocus_p, heap, tab->table, dlocus);
+  tab = (debuglocus_table_t *) ggc_alloc (sizeof (debuglocus_table_t));
+  tab->table = VEC_alloc (debuglocus_segment_p, gc, 100);
+  seg = (debuglocus_segment_p) ggc_alloc_cleared (DEBUGLOCUS_VEC_MEM);
+  VEC_safe_push (debuglocus_segment_p, gc, tab->table, seg);
 
   /* Reserve space number 0 for the NULL entry.  */
   tab->size = 1;
@@ -69,7 +67,7 @@ init_debuglocus_table (void)
 }
 
 
-static debuglocus_table_t *debugtable = NULL;
+static GTY(()) debuglocus_table_t *debugtable = NULL;
 
 /* Create the current debuglocus table.  */
 void
@@ -87,10 +85,14 @@ destroy_debuglocus_table (void)
   if (debugtable)
     {
       unsigned int x;
-      for (x = 0; x < VEC_length (debuglocus_p, debugtable->table); x++)
-        free (VEC_index (debuglocus_p, debugtable->table, x));
-      VEC_free (debuglocus_p, heap, debugtable->table);
-      free (debugtable);
+      for (x = 0; x < VEC_length (debuglocus_segment_p, debugtable->table); x++)
+	{
+	  /* I wonder if it's worth it to free the segments individually, or let
+	     GC do it's thing.  */
+	  ggc_free (VEC_index (debuglocus_segment_p, debugtable->table, x));
+	}
+      VEC_free (debuglocus_segment_p, gc, debugtable->table);
+      ggc_free (debugtable);
     }
   debugtable = NULL;
 }
@@ -109,14 +111,14 @@ static debuglocus_p
 get_debuglocus_entry (debuglocus_table_t *tab, unsigned int i)
 {
   int v,e;
-  debuglocus_p table_vec;
+  debuglocus_segment_p seg;
   gcc_assert (tab != NULL);
   gcc_assert (i > 0 && i < tab->size);
 
   v = i / DEBUGLOCUS_VEC_SIZE;
   e = i % DEBUGLOCUS_VEC_SIZE;
-  table_vec = VEC_index (debuglocus_p, tab->table, v);
-  return &(table_vec[e]);
+  seg = VEC_index (debuglocus_segment_p, tab->table, v);
+  return &seg->entries[e];
 }
 
 
@@ -144,8 +146,9 @@ new_debuglocus_entry (debuglocus_table_t
   /* Check if we need to increase the size of the table vector.  */
   if (i % DEBUGLOCUS_VEC_SIZE == 0)
     {
-      dlocus = (debuglocus_p) xmalloc (DEBUGLOCUS_VEC_MEM);
-      VEC_safe_push (debuglocus_p, heap, tab->table, dlocus);
+      debuglocus_segment_p seg;
+      seg = (debuglocus_segment_p) ggc_alloc_cleared (DEBUGLOCUS_VEC_MEM);
+      VEC_safe_push (debuglocus_segment_p, gc, tab->table, seg);
     }
 
   dlocus = get_debuglocus_entry (tab, i);
@@ -155,7 +158,7 @@ new_debuglocus_entry (debuglocus_table_t
   dlocus->decl = NULL_TREE;
   dlocus->order = i;		    /* Initially the issuing index.  */
   dlocus->prev = dlocus->next = i;  /* Initialize the circular linked list.  */
-  return get_debuglocus_entry (tab, i);
+  return dlocus;
 }
 
 
@@ -263,9 +266,11 @@ debuglocus_index_from_pointer (debuglocu
   source_location idx = UNKNOWN_LOCATION;
   debuglocus_table_t *tab = current_debuglocus_table();
 
-  for (x = 0; x  < VEC_length (debuglocus_p, tab->table); x++)
+  for (x = 0; x  < VEC_length (debuglocus_segment_p, tab->table); x++)
     {
-      debuglocus_p ptr = VEC_index (debuglocus_p, tab->table, x);
+      debuglocus_segment_p seg = VEC_index (debuglocus_segment_p, tab->table, x);
+      debuglocus_p ptr = &seg->entries[0];
+
       /* Find the table this pointer belongs to.  */
       if (ptr <= dlocus && dlocus < ptr + DEBUGLOCUS_VEC_SIZE)
         {
@@ -297,7 +302,7 @@ debuglocus_from_pointer (debuglocus_p dl
 debuglocus_p 
 create_debuglocus_for_decl (tree var)
 {
-  debuglocus_p ptr = create_debuglocus_entry();
+  debuglocus_p ptr = create_debuglocus_entry ();
   ptr->decl = var;
   return ptr;
 }
@@ -754,3 +759,5 @@ debuglocus_bitmap_verify (FILE *f, bitma
 	  fprintf (f, "debuglocus: orphaned debuglocus entry: %u\n", i);
     }
 }
+
+#include "gt-debuglocus.h"
Index: debuglocus.h
===================================================================
--- debuglocus.h	(revision 145618)
+++ debuglocus.h	(working copy)
@@ -24,7 +24,7 @@ along with GCC; see the file COPYING3.  
 /* No entry. Used for terminating lists and returning no matches.  */
 #define DEBUGLOCUS_NONE			0
 
-struct debuglocus_entry_d GTY((skip)) {
+struct debuglocus_entry_d GTY(()) {
   tree decl;			/* debug decl  */
   int order;			/* Ordering for emission sorting.  */
   source_location locus;	/* locus of statement.  */
@@ -35,17 +35,30 @@ struct debuglocus_entry_d GTY((skip)) {
 typedef struct debuglocus_entry_d debuglocus;
 typedef struct debuglocus_entry_d *debuglocus_p;
 
+/* Number of debuglocus entries per segment.  */
+#define DEBUGLOCUS_VEC_SIZE	8192
 
-DEF_VEC_P(debuglocus_p);
-DEF_VEC_ALLOC_P(debuglocus_p, heap);
+/* Debuglocus segments for use in the debuglocus table, pathetically
+   laid out so GTY can understand what's inside the vector that's
+   inside the table.  */
+struct debuglocus_segment_d GTY(()) {
+  debuglocus entries[DEBUGLOCUS_VEC_SIZE];
+};
+
+typedef struct debuglocus_segment_d *debuglocus_segment_p;
+
+DEF_VEC_P(debuglocus_segment_p);
+DEF_VEC_ALLOC_P(debuglocus_segment_p, gc);
 
 /* The debuglocus table is implemented simply as an array of segments. This
    allows for simple growth of the table without having to relocate existing 
    memory in use.  The table can never shrink in size.  */
 
-struct debuglocus_table_d GTY((skip)) {
-  unsigned int size;		    /* Current number of debuglocus entries.  */
-  VEC(debuglocus_p, heap) *table;   /* list of Table segments.  */
+struct debuglocus_table_d GTY(()) {
+  /* Total number of debuglocus entries.  */
+  unsigned int size;
+  /* Vector of debuglocus segments.  */
+  VEC(debuglocus_segment_p, gc) *table;
 };
 
 typedef struct debuglocus_table_d debuglocus_table_t;
Index: Makefile.in
===================================================================
--- Makefile.in	(revision 145618)
+++ Makefile.in	(working copy)
@@ -2544,7 +2544,7 @@ dbxout.o : dbxout.c $(CONFIG_H) $(SYSTEM
    $(TOPLEV_H) $(GGC_H) $(OBSTACK_H) $(EXPR_H) gt-dbxout.h
 debug.o : debug.c debug.h $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H)
 debuglocus.o : debuglocus.c debuglocus.h $(CONFIG_H) $(SYSTEM_H) coretypes.h \
-   $(TM_H) $(INPUT_H)
+   gt-debuglocus.h $(TM_H) $(INPUT_H)
 sdbout.o : sdbout.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) debug.h \
    $(TREE_H) $(GGC_H) $(RTL_H) $(REGS_H) $(FLAGS_H) insn-config.h \
    output.h $(TOPLEV_H) $(TM_P_H) gsyms.h langhooks.h $(TARGET_H) sdbout.h \
@@ -3296,6 +3296,7 @@ GTFILES = $(CPP_ID_DATA_H) $(srcdir)/inp
   $(srcdir)/sdbout.c $(srcdir)/stor-layout.c \
   $(srcdir)/stringpool.c $(srcdir)/tree.c $(srcdir)/varasm.c \
   $(srcdir)/gimple.h $(srcdir)/gimple.c \
+  $(srcdir)/debuglocus.h $(srcdir)/debuglocus.c \
   $(srcdir)/tree-mudflap.c $(srcdir)/tree-flow.h \
   $(srcdir)/tree-ssanames.c $(srcdir)/tree-eh.c $(srcdir)/tree-ssa-address.c \
   $(srcdir)/tree-cfg.c \


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