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]

[boehm-gc] Add type information for GC-allocated objects


Hi,

This is a first tiny step towards custom marker routines. This patch
adds a footer to every GC-allocated object where its type tag is
stored. I've adopted http://gcc.gnu.org/ml/gcc/2004-01/msg01081.html
patch for this. For sanity check I've converted the single ggc_alloc()
in alias.c to use typed allocation.

Note that Boehm's GC has its own facilities for typed allocation, see
gc_typed.h. I've made a choice not to use them, but rather add my own
flag, because I hope this code might be reused not only for ggc-boehm.

Commited to the boehms-gc branch.

--
Laurynas
Index: gcc/gengtype.c
===================================================================
--- gcc/gengtype.c	(revision 115762)
+++ gcc/gengtype.c	(working copy)
@@ -1545,6 +1545,8 @@
       use_param_num = oo->name[9] == '\0' ? 0 : oo->name[9] - '0';
     else if (strcmp (oo->name, "use_params") == 0)
       use_params_p = 1;
+    else if (strcmp (oo->name, "size_not_fixed") == 0)
+      ;
     else if (strcmp (oo->name, "desc") == 0)
       desc = oo->info;
     else if (strcmp (oo->name, "nested_ptr") == 0)
@@ -2436,7 +2438,7 @@
 {
   type_p s;
 
-  oprintf (header_file, "\n/* Enumeration of types known.  */\n");
+  oprintf (header_file, "\n/* Enumeration of known types.  */\n");
   oprintf (header_file, "enum gt_types_enum {\n");
   for (s = structures; s; s = s->next)
     if (s->gc_used == GC_POINTED_TO
@@ -2450,6 +2452,7 @@
 	output_mangled_typename (header_file, s);
 	oprintf (header_file, ", \n");
       }
+
   for (s = param_structs; s; s = s->next)
     if (s->gc_used == GC_POINTED_TO)
       {
@@ -2457,10 +2460,76 @@
 	output_mangled_typename (header_file, s);
 	oprintf (header_file, ", \n");
       }
+
   oprintf (header_file, " gt_types_enum_last\n");
   oprintf (header_file, "};\n");
 }
 
+/* Write out a macro for typed allocations for each known struct or union.  */
+
+static void
+write_typed_alloc_defns (type_p structures)
+{
+  type_p s;
+  pair_p p;
+
+  oprintf (header_file,
+	   "\n/* Typed allocation for known structs and unions.  */\n");
+  for (s = structures; s; s = s->next)
+    if (s->gc_used == GC_POINTED_TO
+	|| (s->gc_used == GC_MAYBE_POINTED_TO && s->u.s.line.file != NULL))
+      {
+	options_p o;
+	int have_size = 0;
+	const char *type_kind;
+
+	for (o = s->u.s.opt; o; o = o->next)
+	  if (strcmp (o->name, "size_not_fixed") == 0)
+	    have_size = 1;
+ 
+	if (s->kind == TYPE_STRUCT)
+	  type_kind = "struct ";
+	else if (s->kind == TYPE_UNION)
+	  type_kind = "union ";
+	else
+	  type_kind = "";
+
+	oprintf (header_file, "#define ggc_alloc_%s(%s) \\\n",
+		 s->u.s.tag, (have_size ? "SIZE" : ""));
+	oprintf (header_file, "  ggc_alloc_typed(gt_ggc_e_");
+	output_mangled_typename (header_file, s);
+	if (have_size)
+	  oprintf (header_file, ", SIZE)\n");
+	else
+	  oprintf (header_file, ", sizeof (%s%s))\n",
+		   type_kind, s->u.s.tag);
+      }
+
+  oprintf (header_file,
+           "\n/* Typed allocation for known typedefs.  */\n");
+  for (p = typedefs; p != NULL; p = p->next)
+    {
+      s = p->type;
+      if (strcmp (p->name, s->u.s.tag) == 0)
+	continue;
+
+      if (s->gc_used == GC_POINTED_TO
+	  || (s->gc_used == GC_MAYBE_POINTED_TO && s->u.s.line.file != NULL))
+	{
+	  if (s->kind != TYPE_STRUCT
+	      && s->kind != TYPE_UNION)
+	    continue;
+
+	  oprintf (header_file, "#define ggc_alloc_%s(%s) \\\n",
+		   p->name, s->kind == TYPE_STRUCT ? "" : "__SIZE");
+	  oprintf (header_file, "  ggc_alloc_typed(gt_ggc_e_");
+	  output_mangled_typename (header_file, s);
+	  oprintf (header_file, ", sizeof (%s%s))\n",
+		   s->kind == TYPE_STRUCT ? "struct " : "", s->u.s.tag);
+	}
+    }
+}
+
 /* Might T contain any non-pointer elements?  */
 
 static int
@@ -3083,6 +3152,7 @@
 
   open_base_files ();
   write_enum_defn (structures, param_structs);
+  write_typed_alloc_defns (structures);
   write_types (structures, param_structs, &ggc_wtd);
   write_types (structures, param_structs, &pch_wtd);
   write_local (structures, param_structs);
Index: gcc/ggc-boehm.c
===================================================================
--- gcc/ggc-boehm.c	(revision 116062)
+++ gcc/ggc-boehm.c	(working copy)
@@ -16,17 +16,25 @@
 static int ggc_htab_unregister_weak_ptr(void **slot, void *info);
 static void ggc_htab_delete_weak_ptr(void ** slot, void * object,
 				     void * info);
+
 static size_t get_used_heap_size(void);
 static void register_gty_roots(void);
 static void gc_warning_filter(char * msg, GC_word arg);
+
+static enum gt_types_enum *get_type_offset(void * block);
+static enum gt_types_enum get_block_type(void * block);
+
 static void register_weak_pointers(void);
 static void unregister_weak_pointers(void);
 
 static size_t last_allocated = 0;
+static size_t type_overhead = 0;
 static ggc_stringpool_roots stringpool_roots;
 
 static GC_warn_proc default_warn_proc;
 
+#define OBJ_OVERHEAD sizeof(enum gt_types_enum)
+
 void
 init_ggc (void)
 {
@@ -52,7 +60,39 @@
   return result;
 }
 
+enum gt_types_enum *
+get_type_offset(void * block)
+{
+  return (enum gt_types_enum *)((char *)block + GC_size(block) - OBJ_OVERHEAD);
+}
+
 void *
+ggc_alloc_typed_stat (enum gt_types_enum type, size_t size MEM_STAT_DECL)
+{
+  void * result = NULL;
+
+  size_t actual_obj_size;
+  const size_t obj_plus_info_size = size + OBJ_OVERHEAD;
+  type_overhead += obj_plus_info_size;
+
+  result = GC_malloc (obj_plus_info_size);
+  actual_obj_size = GC_size(result);
+
+  *(get_type_offset(result)) = type;
+
+  /* Verification */
+  gcc_assert (type == get_block_type (result));
+
+  return result;
+}
+
+enum gt_types_enum
+get_block_type(void * block)
+{
+  return *(get_type_offset(block));
+}
+
+void *
 ggc_realloc_stat (void *x, size_t size MEM_STAT_DECL)
 {
   void * result = GC_REALLOC(x, size);
@@ -177,8 +217,9 @@
 size_t
 ggc_get_size (const void * block)
 {
-  return GC_size((void *)block); /* Note that GC_size may return a bit larger
-			            value than originally requested */
+  return GC_size((void *)block) - OBJ_OVERHEAD; /* Note that GC_size may return
+						   a bit larger value than
+						   originally requested */
 }
 
 int
@@ -267,6 +308,9 @@
   fprintf (stderr,
 	   "Used bytes in the heap: %lu\n",
 	   (unsigned long)get_used_heap_size());
+  fprintf (stderr,
+	   "Local ggc-boehm overhead: %lu\n",
+	   (unsigned long)type_overhead);
 }
 
 int
Index: gcc/tree.h
===================================================================
--- gcc/tree.h	(revision 115762)
+++ gcc/tree.h	(working copy)
@@ -3143,7 +3143,8 @@
    for various types of node.  */
 
 union tree_node GTY ((ptr_alias (union lang_tree_node),
-		      desc ("tree_node_structure (&%h)")))
+		      desc ("tree_node_structure (&%h)"),
+		      size_not_fixed ("")))
 {
   struct tree_common GTY ((tag ("TS_COMMON"))) common;
   struct tree_int_cst GTY ((tag ("TS_INT_CST"))) int_cst;
Index: gcc/alias.c
===================================================================
--- gcc/alias.c	(revision 115762)
+++ gcc/alias.c	(working copy)
@@ -670,7 +670,7 @@
     {
       /* Create an entry for the SUPERSET, so that we have a place to
 	 attach the SUBSET.  */
-      superset_entry = ggc_alloc (sizeof (struct alias_set_entry));
+      superset_entry = ggc_alloc_alias_set_entry();
       superset_entry->alias_set = superset;
       superset_entry->children
 	= splay_tree_new_ggc (splay_tree_compare_ints);
Index: gcc/rtl.h
===================================================================
--- gcc/rtl.h	(revision 115762)
+++ gcc/rtl.h	(working copy)
@@ -232,7 +232,8 @@
 /* RTL expression ("rtx").  */
 
 struct rtx_def GTY((chain_next ("RTX_NEXT (&%h)"),
-		    chain_prev ("RTX_PREV (&%h)")))
+		    chain_prev ("RTX_PREV (&%h)"),
+		    size_not_fixed ("")))
 {
   /* The kind of expression this is.  */
   ENUM_BITFIELD(rtx_code) code: 16;

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