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]

[boehms-gc] Convert GCC to use typed GC allocation routines


Hi,

This is a quite big patch, that makes all of GCC to use typed GC
allocation routines instead of  generic ggc_alloc(). Fun, isn't it :)
It is very hard to break this patch into independent parts, so I send
it as a whole.

Now let's discuss the details, many of them:
1) All these changes are fairly independent from ggc-boehm and might
be ported to other allocators.
1) Gengtype was further hacked to cast allocation result to the exact
data type pointer. This helped quite a lot during debugging and
enabled to remove virtually all casts from the GC allocation routines.
2) The typed allocation routine output was refactored in gengtype to
avoid "copy-paste-change-a-bit" code that plagued it earlier. OTOH,
I'm not sure if the result is much better :)
3) Function ggc_alloc() was renamed to ggc_internal_alloc() to show
that it's not external API anymore. I'm thinking about splitting up
ggc.h into internal and external parts in the future. The same story
with ggc_alloc_zone().
4) Bunch of new functions and defines to perform atomic/typed
cleared/non-cleared vector/single-element allocations.
5) It is impossible to use Boehm's GC with custom marking routines to
reallocate non-atomic data. Thus ggc_realloc() was renamed to
ggc_realloc_atomic() and checks were added to implementation to verify
that it really operates on atomic data. This may change in the future.
7) All GGC_NEW macro family was renamed and redefined to be
atomic-only. For non-atomic data please use typed allocation.
8) Compatibility with ggc-zone lost for now. It's quite easy to fix,
just make gengtype generate zoned versions of all allocation routines,
but that involves doubling once again the number of routines
generated.
9) Collectors ggc-page and ggc-zone are broken for now.
10) Libiberty change: splay_tree_new_with_allocator has a new
parameter so that two different typed allocators could be used for
allocating tree itself and its nodes.
11) All non-typed GC allocation calls were replaced with typed/atomic versions.
12) MEM_STAT stuff in tree.c and rtl.c is broken for now.
13) Atomic allocation is used quite liberally, in all cases where
gengtype outputs nothing about corresponding type. It shouldn't be an
obstacle in short-term: I guess that currently gengtype cannot output
marker routines for such data types neither, so they are collected on
the first ggc_collect() call - which should correspond to the
ggc-boehm behaviour with atomic allocation of such data types.
However, in the future we would like to use atomic only for things
like char * and have exact information about everything else: for
copying allocation, enabling collection at points where it's
impossible currently, and so on. Moreover, a couple of current atomic
allocations look like real bugs right now. Probably gengtype will have
to acquire some more smarts.
14) There are instances where for non-atomic data type variable it is
known in advance which member of the union will be used and less
memory than sizeof() is allocated for it. All these optimisations are
removed for now in favour of typed allocations. Maybe I'll just use
GTY flag "size_not_fixed" for such data types in future.
15) Removed my_malloc() from treelang frontend.
16) I've touched zillion of backends without any testing. It seems
that I'll have to build quite a lot of cross-compilers in future :)

Bootstrapped on AMD64 Linux and commited to the branch. Not a single
GC allocation without type information survived - way for custom
marking is clear now.

Index: gcc/gengtype.c
===================================================================
--- gcc/gengtype.c	(revision 116225)
+++ gcc/gengtype.c	(working copy)
@@ -2465,7 +2465,75 @@

/* Write out a macro for typed allocations for each known struct or union. */

+static const char *
+get_tag_string (const type_p s)
+{
+  if (s->kind == TYPE_STRUCT || s->kind == TYPE_LANG_STRUCT)
+    return "struct ";
+  if (s->kind == TYPE_UNION)
+    return "union ";
+  return "";
+}
+
+static int
+has_size_p (const type_p s)
+{
+  options_p o;
+  for (o = s->u.s.opt; o; o = o->next)
+    if (strcmp (o->name, "size_not_fixed") == 0)
+      return 1;
+  return 0;
+}
+
static void
+write_typecast_to_ptr (const type_p s)
+{
+  oprintf (header_file, "(%s%s *)", get_tag_string (s), s->u.s.tag);
+}
+
+static void
+write_typed_struct_alloc_def (const type_p s, const char * const fn_type,
+			      int is_vector)
+{
+  int have_size = has_size_p (s);
+  const char *type_kind = get_tag_string (s);
+
+  oprintf (header_file, "#define ggc_alloc_%s%s(%s%s%s) \\\n", fn_type,
+	   s->u.s.tag, (have_size ? "SIZE" : ""),
+	   ((have_size && is_vector) ? ", " : ""), (is_vector ? "n" : ""));
+  oprintf (header_file, "  ");
+  write_typecast_to_ptr (s);
+  oprintf (header_file, " ggc_alloc_%styped(gt_ggc_e_", fn_type);
+  output_mangled_typename (header_file, s);
+  if (have_size)
+    oprintf (header_file, ", SIZE%s)\n", (is_vector ? " * (n)" : ""));
+  else
+    oprintf (header_file, ", sizeof (%s%s)%s)\n",
+	     type_kind, s->u.s.tag, (is_vector ? " * (n)" : ""));
+}
+
+static void
+write_typed_typedef_alloc_def (const pair_p p, const char * const fn_type,
+			       int is_vector)
+{
+  type_p s = p->type;
+
+  oprintf (header_file, "#define ggc_alloc_%s%s%s(%s) \\\n", fn_type,
+	   p->name, s->kind == TYPE_STRUCT ? "" : "__SIZE",
+	   (is_vector ? "n" : ""));
+  oprintf (header_file, "  ");
+  write_typecast_to_ptr (s);
+  oprintf (header_file, " ggc_alloc_%styped(gt_ggc_e_", fn_type);
+  output_mangled_typename (header_file, s);
+  oprintf (header_file, ", sizeof (%s%s)%s)\n",
+	   s->kind == TYPE_STRUCT ? "struct " : "", s->u.s.tag,
+	   (is_vector ? " * (n)" : ""));
+}
+
+#define NON_VECTOR_DEF 0
+#define VECTOR_DEF 1
+
+static void
write_typed_alloc_defns (type_p structures)
{
  type_p s;
@@ -2475,63 +2543,12 @@
	   "\n/* Typed allocation for known structs and unions.  */\n");
  for (s = structures; s; s = s->next)
    {
-      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 || s->kind == TYPE_LANG_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, "#define ggc_alloc_cleared_%s(%s) \\\n",
-	       s->u.s.tag, (have_size ? "SIZE" : ""));
-      oprintf (header_file, "  ggc_alloc_cleared_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, "#define ggc_alloc_vec_%s(%sn) \\\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, ", (n) * SIZE)\n");
-      else
-	oprintf (header_file, ", (n) * sizeof (%s%s))\n",
-		 type_kind, s->u.s.tag);
-
-      oprintf (header_file, "#define ggc_alloc_cleared_vec_%s(%sn) \\\n",
-	       s->u.s.tag, (have_size ? "SIZE, " : ""));
-      oprintf (header_file, "  ggc_alloc_cleared_typed(gt_ggc_e_");
-      output_mangled_typename (header_file, s);
-      if (have_size)
-	oprintf (header_file, ", (n) * SIZE)\n");
-      else
-	oprintf (header_file, ", (n) * sizeof (%s%s))\n",
-		 type_kind, s->u.s.tag);
+      write_typed_struct_alloc_def (s, "", NON_VECTOR_DEF);
+      write_typed_struct_alloc_def (s, "cleared_", NON_VECTOR_DEF);
+      write_typed_struct_alloc_def (s, "vec_", VECTOR_DEF);
+      write_typed_struct_alloc_def (s, "cleared_vec_", VECTOR_DEF);
    }
-  oprintf (header_file,
-           "\n/* Typed allocation for known typedefs.  */\n");
+  oprintf (header_file, "\n/* Typed allocation for known typedefs.  */\n");
  for (p = typedefs; p != NULL; p = p->next)
    {
      s = p->type;
@@ -2542,33 +2559,10 @@
	  && 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);
-
-      oprintf (header_file, "#define ggc_alloc_cleared_%s(%s) \\\n",
-	       p->name, s->kind == TYPE_STRUCT ? "" : "__SIZE");
-      oprintf (header_file, "  ggc_alloc_cleared_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);
-
-      oprintf (header_file, "#define ggc_alloc_vec_%s(%sn) \\\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, ", (n) * sizeof (%s%s))\n",
-	       s->kind == TYPE_STRUCT ? "struct " : "", s->u.s.tag);
-
-      oprintf (header_file, "#define ggc_alloc_cleared_vec_%s(%sn) \\\n",
-	       p->name, s->kind == TYPE_STRUCT ? "" : "__SIZE, ");
-      oprintf (header_file, "  ggc_alloc_cleared_typed(gt_ggc_e_");
-      output_mangled_typename (header_file, s);
-      oprintf (header_file, ", (n) * sizeof (%s%s))\n",
-	       s->kind == TYPE_STRUCT ? "struct " : "", s->u.s.tag);
+      write_typed_typedef_alloc_def (p, "", NON_VECTOR_DEF);
+      write_typed_typedef_alloc_def (p, "cleared_", NON_VECTOR_DEF);
+      write_typed_typedef_alloc_def (p, "vec_", VECTOR_DEF);
+      write_typed_typedef_alloc_def (p, "cleared_vec_", VECTOR_DEF);
    }
}

Index: gcc/gengtype.h
===================================================================
--- gcc/gengtype.h	(revision 116135)
+++ gcc/gengtype.h	(working copy)
@@ -18,7 +18,7 @@
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.  */

-/* A file position, mostly for error messages.
+/* A file position, mostly for error messages.
   The FILE element may be compared using pointer equality.  */
struct fileloc {
  const char *file;
@@ -46,7 +46,7 @@
  type_p type;
  const char *convert_to;
  const char *convert_from;
-};
+};

/* A way to pass data through to the output end.  */
typedef struct options {
@@ -120,7 +120,7 @@
extern struct fileloc lexer_line;

/* Print an error message.  */
-extern void error_at_line
+extern void error_at_line
  (struct fileloc *pos, const char *msg, ...) ATTRIBUTE_PRINTF_2;

/* Combines xmalloc() and vasprintf().  */
@@ -156,7 +156,7 @@
/* Output file handling.  */

/* Structure representing an output file.  */
-struct outf
+struct outf
{
  struct outf *next;
  const char *name;
@@ -170,7 +170,7 @@
/* An output file, suitable for definitions, that can see declarations
   made in INPUT_FILE and is linked into every language that uses
   INPUT_FILE.  */
-extern outf_p get_output_file_with_visibility
+extern outf_p get_output_file_with_visibility
   (const char *input_file);
const char *get_output_file_name (const char *);

Index: gcc/ggc-boehm.c
===================================================================
--- gcc/ggc-boehm.c	(revision 116165)
+++ gcc/ggc-boehm.c	(working copy)
@@ -54,7 +54,7 @@
}

void *
-ggc_alloc_stat (size_t size MEM_STAT_DECL)
+ggc_internal_alloc_stat (size_t size MEM_STAT_DECL)
{
  void * result = GC_MALLOC(size);
  return result;
@@ -86,14 +86,28 @@
  return result;
}

-void *ggc_alloc_cleared_typed_stat (enum gt_types_enum type,
-				    size_t size MEM_STAT_DECL)
+void *
+ggc_alloc_cleared_typed_stat (enum gt_types_enum type,
+			      size_t size MEM_STAT_DECL)
{
  void * result = ggc_alloc_typed_stat(type, size);
  memset (result, 0, size);
  return result;
}

+void *
+ggc_alloc_atomic_stat (size_t size MEM_STAT_INFO)
+{
+  return ggc_alloc_typed_stat (gt_types_enum_atomic_data, size);
+}
+
+void *
+ggc_alloc_cleared_atomic_stat (size_t size MEM_STAT_INFO)
+{
+  return ggc_alloc_cleared_typed_stat (gt_types_enum_atomic_data, size);
+}
+
+
enum gt_types_enum
get_block_type(void * block)
{
@@ -101,9 +115,14 @@
}

void *
-ggc_realloc_stat (void *x, size_t size MEM_STAT_DECL)
+ggc_realloc_atomic_stat (void *x, size_t size MEM_STAT_DECL)
{
-  void * result = GC_REALLOC(x, size);
+  void * result;
+  if (x == NULL)
+    return ggc_alloc_atomic_stat (size);
+  gcc_assert (get_block_type(x) == gt_types_enum_atomic_data);
+  result = GC_REALLOC(x, size);
+  *(get_type_offset(result)) = gt_types_enum_atomic_data;
  return result;
}

Index: gcc/cgraph.c
===================================================================
--- gcc/cgraph.c	(revision 116135)
+++ gcc/cgraph.c	(working copy)
@@ -181,7 +181,7 @@
{
  struct cgraph_node *node;

-  node = GGC_CNEW (struct cgraph_node);
+  node = ggc_alloc_cleared_cgraph_node ();
  node->next = cgraph_nodes;
  node->uid = cgraph_max_uid++;
  node->order = cgraph_order++;
@@ -316,7 +316,7 @@
cgraph_create_edge (struct cgraph_node *caller, struct cgraph_node *callee,
		    tree call_stmt, gcov_type count, int nest)
{
-  struct cgraph_edge *edge = GGC_NEW (struct cgraph_edge);
+  struct cgraph_edge *edge = ggc_alloc_cgraph_edge();
#ifdef ENABLE_CHECKING
  struct cgraph_edge *e;

@@ -759,7 +759,7 @@
    htab_find_slot (cgraph_varpool_hash, &key, INSERT);
  if (*slot)
    return *slot;
-  node = GGC_CNEW (struct cgraph_varpool_node);
+  node = ggc_alloc_cleared_cgraph_varpool_node ();
  node->decl = decl;
  node->order = cgraph_order++;
  node->next = cgraph_varpool_nodes;
@@ -912,7 +912,7 @@
{
  struct cgraph_asm_node *node;

-  node = GGC_CNEW (struct cgraph_asm_node);
+  node = ggc_alloc_cleared_cgraph_asm_node ();
  node->asm_str = asm_str;
  node->order = cgraph_order++;
  node->next = NULL;
Index: gcc/tree.c
===================================================================
--- gcc/tree.c	(revision 116166)
+++ gcc/tree.c	(working copy)
@@ -522,10 +522,11 @@
  tree_node_sizes[(int) kind] += length;
#endif

+  /* TODO: MEM_STAT broken */
  if (code == IDENTIFIER_NODE)
-    t = ggc_alloc_zone_pass_stat (length, &tree_id_zone);
+    t = ggc_alloc_tree_node (length); /* TODO: tree_id_zone */
  else
-    t = ggc_alloc_zone_pass_stat (length, &tree_zone);
+    t = ggc_alloc_tree_node (length); /* TODO: tree_zone */

memset (t, 0, length);

@@ -613,7 +614,7 @@
  gcc_assert (code != STATEMENT_LIST);

  length = tree_size (node);
-  t = ggc_alloc_zone_pass_stat (length, &tree_zone);
+  t = ggc_alloc_tree_node (length); /* TODO: MEM_STAT broken, tree_zone */
  memcpy (t, node, length);

  TREE_CHAIN (t) = 0;
@@ -1059,7 +1060,7 @@
     Consider doing it via real_convert now.  */

  v = make_node (REAL_CST);
-  dp = ggc_alloc (sizeof (REAL_VALUE_TYPE));
+  dp = ggc_alloc_real_value ();
  memcpy (dp, &d, sizeof (REAL_VALUE_TYPE));

  TREE_TYPE (v) = type;
@@ -1165,7 +1166,7 @@
  tree_node_sizes[(int) binfo_kind] += length;
#endif

-  t = ggc_alloc_zone_pass_stat (length, &tree_zone);
+  t = ggc_alloc_tree_node (length); /* TODO: MEM_STAT broken, tree_zone */

memset (t, 0, offsetof (struct tree_binfo, base_binfos));

@@ -1190,7 +1191,7 @@
  tree_node_sizes[(int) vec_kind] += length;
#endif

-  t = ggc_alloc_zone_pass_stat (length, &tree_zone);
+  t = ggc_alloc_tree_node (length); /* TODO: MEM_STAT broken, tree_zone */

memset (t, 0, length);

@@ -1656,7 +1657,8 @@
{
  tree node;

-  node = ggc_alloc_zone_pass_stat (sizeof (struct tree_list), &tree_zone);
+  /* TODO: MEM_STAT broken, tree_zone */
+  node = ggc_alloc_tree_node (sizeof (struct tree_list));

memset (node, 0, sizeof (struct tree_common));

@@ -2793,7 +2795,7 @@

gcc_assert (TREE_CODE_LENGTH (code) == 1);

-  t = ggc_alloc_zone_pass_stat (length, &tree_zone);
+  t = ggc_alloc_tree_node (length); /* TODO: MEM_STAT broken, tree_zone */

memset (t, 0, sizeof (struct tree_common));

@@ -6819,7 +6821,7 @@
  length = omp_clause_num_ops[code];
  size = (sizeof (struct tree_omp_clause) + (length - 1) * sizeof (tree));

-  t = ggc_alloc (size);
+  t = ggc_alloc_tree_node (size);
  memset (t, 0, size);
  TREE_SET_CODE (t, OMP_CLAUSE);
  OMP_CLAUSE_SET_CODE (t, code);
Index: gcc/bitmap.c
===================================================================
--- gcc/bitmap.c	(revision 116135)
+++ gcc/bitmap.c	(working copy)
@@ -136,7 +136,7 @@
	  /*  Inner list was just a singleton.  */
	  bitmap_ggc_free = element->prev;
      else
-	element = GGC_NEW (bitmap_element);
+	element = ggc_alloc_bitmap_element_def();
    }

  memset (element->bits, 0, sizeof (element->bits));
@@ -255,7 +255,7 @@
{
  bitmap map;

-  map = GGC_NEW (struct bitmap_head_def);
+  map = ggc_alloc_bitmap_head_def();
  bitmap_initialize (map, NULL);

  return map;
Index: gcc/lambda-mat.c
===================================================================
--- gcc/lambda-mat.c	(revision 116166)
+++ gcc/lambda-mat.c	(working copy)
@@ -37,7 +37,7 @@
  lambda_matrix mat;
  int i;

-  mat = ggc_alloc (m * sizeof (lambda_vector));
+  mat = ggc_alloc_atomic (m * sizeof (lambda_vector));

  for (i = 0; i < m; i++)
    mat[i] = lambda_vector_new (n);
Index: gcc/tree-phinodes.c
===================================================================
--- gcc/tree-phinodes.c	(revision 116135)
+++ gcc/tree-phinodes.c	(working copy)
@@ -153,7 +153,7 @@
    }
  else
    {
-      phi = ggc_alloc (size);
+      phi = ggc_alloc_tree_node (size);
#ifdef GATHER_STATISTICS
      phi_nodes_created++;
      tree_node_counts[(int) phi_kind]++;
Index: gcc/objc/objc-act.c
===================================================================
--- gcc/objc/objc-act.c	(revision 116135)
+++ gcc/objc/objc-act.c	(working copy)
@@ -937,7 +937,7 @@

      if (!*loc)
	{
-	  *loc = ggc_alloc (sizeof (key));
+	  *loc = ggc_alloc_volatilized_type ();
	  ((struct volatilized_type *) *loc)->type = t;
	}

@@ -1930,7 +1930,7 @@
  if (!desc)
    {
      tree var;
-      *loc = desc = ggc_alloc (sizeof (*desc));
+      *loc = desc = ggc_alloc_string_descriptor ();
      desc->literal = string;

      /* GNU:    (NXConstantString *) & ((__builtin_ObjCString) {
NULL, string, length })  */
@@ -6735,10 +6735,10 @@
static void
hash_init (void)
{
-  nst_method_hash_list
-    = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
-  cls_method_hash_list
-    = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
+  nst_method_hash_list = ggc_alloc_cleared_vec_atomic (SIZEHASHTABLE,
+						       sizeof (hash));
+  cls_method_hash_list = ggc_alloc_cleared_vec_atomic (SIZEHASHTABLE,
+						       sizeof (hash));

  /* Initialize the hash table used to hold the constant string objects.  */
  string_htab = htab_create_ggc (31, string_hash,
@@ -6760,7 +6760,7 @@
  hash obj;
  int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;

-  obj = (hash) ggc_alloc (sizeof (struct hashed_entry));
+  obj = ggc_alloc_hashed_entry ();
  obj->list = 0;
  obj->next = hashlist[slot];
  obj->key = method;
@@ -6790,7 +6790,7 @@
{
  attr obj;

-  obj = (attr) ggc_alloc (sizeof (struct hashed_attribute));
+  obj = ggc_alloc_hashed_attribute ();
  obj->next = entry->list;
  obj->value = value;

@@ -6988,7 +6988,7 @@
			      INSERT);
  if (!*slot)
    {
-      *slot = (struct interface_tuple *) ggc_alloc_cleared (sizeof
(struct interface_tuple));
+      *slot = ggc_alloc_cleared_interface_tuple ();
      (*slot)->id = name;
    }
  (*slot)->class_name = class_name;
@@ -7628,7 +7628,7 @@
      uprivate_record = CLASS_STATIC_TEMPLATE (implementation_template);
      objc_instance_type = build_pointer_type (uprivate_record);

-      imp_entry = (struct imp_entry *) ggc_alloc (sizeof (struct imp_entry));
+      imp_entry = ggc_alloc_imp_entry ();

      imp_entry->next = imp_list;
      imp_entry->imp_context = class;
Index: gcc/objc/objc-act.h
===================================================================
--- gcc/objc/objc-act.h	(revision 116135)
+++ gcc/objc/objc-act.h	(working copy)
@@ -83,7 +83,7 @@
#define SIZEOF_OBJC_TYPE_LANG_SPECIFIC sizeof (struct lang_type)
#define ALLOC_OBJC_TYPE_LANG_SPECIFIC(NODE)				\
  do {									\
-    TYPE_LANG_SPECIFIC (NODE) = GGC_CNEW (struct lang_type);		\
+    TYPE_LANG_SPECIFIC (NODE) = ggc_alloc_cleared_lang_type();		\
  } while (0)

#define TYPE_HAS_OBJC_INFO(TYPE)				\
Index: gcc/cfg.c
===================================================================
--- gcc/cfg.c	(revision 116166)
+++ gcc/cfg.c	(working copy)
@@ -84,9 +84,9 @@
  if (!cfun->cfg)
    cfun->cfg = ggc_alloc_cleared_control_flow_graph();
  n_edges = 0;
-  ENTRY_BLOCK_PTR = ggc_alloc_cleared (sizeof (struct basic_block_def));
+  ENTRY_BLOCK_PTR = ggc_alloc_cleared_basic_block_def();
  ENTRY_BLOCK_PTR->index = ENTRY_BLOCK;
-  EXIT_BLOCK_PTR = ggc_alloc_cleared (sizeof (struct basic_block_def));
+  EXIT_BLOCK_PTR = ggc_alloc_cleared_basic_block_def();
  EXIT_BLOCK_PTR->index = EXIT_BLOCK;
  ENTRY_BLOCK_PTR->next_bb = EXIT_BLOCK_PTR;
  EXIT_BLOCK_PTR->prev_bb = ENTRY_BLOCK_PTR;
@@ -133,7 +133,7 @@
alloc_block (void)
{
  basic_block bb;
-  bb = ggc_alloc_cleared (sizeof (*bb));
+  bb = ggc_alloc_cleared_basic_block_def ();
  return bb;
}

@@ -263,7 +263,7 @@
unchecked_make_edge (basic_block src, basic_block dst, int flags)
{
  edge e;
-  e = ggc_alloc_cleared (sizeof (*e));
+  e = ggc_alloc_cleared_edge_def ();
  n_edges++;

  e->src = src;
Index: gcc/objcp/objcp-decl.h
===================================================================
--- gcc/objcp/objcp-decl.h	(revision 116135)
+++ gcc/objcp/objcp-decl.h	(working copy)
@@ -72,9 +72,8 @@
#define SIZEOF_OBJC_TYPE_LANG_SPECIFIC sizeof (struct lang_type_class)
#undef ALLOC_OBJC_TYPE_LANG_SPECIFIC
#define ALLOC_OBJC_TYPE_LANG_SPECIFIC(NODE)				\
-  do {									\
-    TYPE_LANG_SPECIFIC (NODE) = GGC_CNEWVAR	                        \
-      (struct lang_type, sizeof (struct lang_type_class));		\
+  do {	/* TODO: allocate sizeof (struct lang_type_class) bytes here */	\
+    TYPE_LANG_SPECIFIC (NODE) = ggc_alloc_cleared_lang_type();          \
    TYPE_LANG_SPECIFIC (NODE)->u.c.h.is_lang_type_class = 1;		\
  } while (0)

Index: gcc/vec.c
===================================================================
--- gcc/vec.c	(revision 116135)
+++ gcc/vec.c	(working copy)
@@ -112,7 +112,8 @@
  if (!alloc)
    return NULL;

-  vec = ggc_realloc_stat (vec, vec_offset + alloc * elt_size PASS_MEM_STAT);
+  vec = ggc_realloc_atomic_stat (vec,
+				 vec_offset + alloc * elt_size PASS_MEM_STAT);
  ((struct vec_prefix *)vec)->alloc = alloc;
  if (!pfx)
    ((struct vec_prefix *)vec)->num = 0;
Index: gcc/cp/class.c
===================================================================
--- gcc/cp/class.c	(revision 116135)
+++ gcc/cp/class.c	(working copy)
@@ -5072,8 +5072,7 @@
  n_fields = count_fields (TYPE_FIELDS (t));
  if (n_fields > 7)
    {
-      struct sorted_fields_type *field_vec = GGC_NEWVAR
-	 (struct sorted_fields_type,
+      struct sorted_fields_type *field_vec = ggc_alloc_sorted_fields_type(
	  sizeof (struct sorted_fields_type) + n_fields * sizeof (tree));
      field_vec->len = n_fields;
      add_fields_to_record_type (TYPE_FIELDS (t), field_vec, 0);
Index: gcc/cp/decl.c
===================================================================
--- gcc/cp/decl.c	(revision 116135)
+++ gcc/cp/decl.c	(working copy)
@@ -2221,7 +2221,7 @@
  /* Record this label on the list of labels used in this function.
     We do this before calling make_label_decl so that we get the
     IDENTIFIER_LABEL_VALUE before the new label is declared.  */
-  ent = GGC_CNEW (struct named_label_entry);
+  ent = ggc_alloc_named_label_entry ();
  ent->label_decl = decl;

  slot = htab_find_slot (named_labels, ent, INSERT);
@@ -2432,7 +2432,7 @@
	  && ent->uses->names_in_scope == current_binding_level->names)
	return;

-      new_use = GGC_NEW (struct named_label_use_entry);
+      new_use = ggc_alloc_named_label_use_entry ();
      new_use->binding_level = current_binding_level;
      new_use->names_in_scope = current_binding_level->names;
      new_use->o_goto_locus = input_location;
@@ -10769,7 +10769,7 @@
  gcc_assert (!DECL_PENDING_INLINE_P (decl));

  /* Make a copy.  */
-  f = GGC_NEW (struct language_function);
+  f = ggc_alloc_language_function ();
  memcpy (f, cp_function_chain, sizeof (struct language_function));
  DECL_SAVED_FUNCTION_DATA (decl) = f;

@@ -11448,7 +11448,7 @@
void
cxx_push_function_context (struct function * f)
{
-  struct language_function *p = GGC_CNEW (struct language_function);
+  struct language_function *p = ggc_alloc_cleared_language_function ();
  f->language = p;

  /* Whenever we start a new function, we destroy temporaries in the
Index: gcc/cp/cp-objcp-common.c
===================================================================
--- gcc/cp/cp-objcp-common.c	(revision 116135)
+++ gcc/cp/cp-objcp-common.c	(working copy)
@@ -229,7 +229,7 @@
  struct tree_map *h;
  void **loc;

-  h = GGC_NEW (struct tree_map);
+  h = ggc_alloc_tree_map ();
  h->hash = htab_hash_pointer (from);
  h->from = from;
  h->to = to;
Index: gcc/cp/cp-tree.h
===================================================================
--- gcc/cp/cp-tree.h	(revision 116135)
+++ gcc/cp/cp-tree.h	(working copy)
@@ -2600,15 +2600,14 @@
   hashed POINTER_TYPE, and can only be used on the POINTER_TYPE.  */
#define TYPE_GET_PTRMEMFUNC_TYPE(NODE) \
  (TYPE_LANG_SPECIFIC (NODE) ? LANG_TYPE_PTRMEM_CHECK (NODE)->record : NULL)
-#define TYPE_SET_PTRMEMFUNC_TYPE(NODE, VALUE)				\
-  do {									\
-    if (TYPE_LANG_SPECIFIC (NODE) == NULL)				\
-      {									\
-	TYPE_LANG_SPECIFIC (NODE) = GGC_CNEWVAR				\
-	 (struct lang_type, sizeof (struct lang_type_ptrmem));		\
-	TYPE_LANG_SPECIFIC (NODE)->u.ptrmem.h.is_lang_type_class = 0;	\
-      }									\
-    TYPE_LANG_SPECIFIC (NODE)->u.ptrmem.record = (VALUE);		\
+#define TYPE_SET_PTRMEMFUNC_TYPE(NODE, VALUE)				 \
+  do {									 \
+    if (TYPE_LANG_SPECIFIC (NODE) == NULL)				 \
+      {	/* TODO: allocate sizeof (struct lang_type_ptrmem) bytes here */ \
+	TYPE_LANG_SPECIFIC (NODE) = ggc_alloc_cleared_lang_type();	 \
+	TYPE_LANG_SPECIFIC (NODE)->u.ptrmem.h.is_lang_type_class = 0;    \
+      }								       \
+    TYPE_LANG_SPECIFIC (NODE)->u.ptrmem.record = (VALUE);	       \
  } while (0)

/* For a pointer-to-member type of the form `T X::*', this is `X'.
Index: gcc/cp/typeck2.c
===================================================================
--- gcc/cp/typeck2.c	(revision 116135)
+++ gcc/cp/typeck2.c	(working copy)
@@ -265,7 +265,7 @@
      slot = htab_find_slot_with_hash (abstract_pending_vars, type,
				      (hashval_t)TYPE_UID (type), INSERT);

-      pat = GGC_NEW (struct pending_abstract_type);
+      pat = ggc_alloc_pending_abstract_type ();
      pat->type = type;
      pat->decl = decl;
      pat->locus = ((decl && DECL_P (decl))
Index: gcc/cp/name-lookup.c
===================================================================
--- gcc/cp/name-lookup.c	(revision 116135)
+++ gcc/cp/name-lookup.c	(working copy)
@@ -85,7 +85,7 @@
      free_binding_entry = entry->chain;
    }
  else
-    entry = GGC_NEW (struct binding_entry_s);
+    entry = ggc_alloc_binding_entry_s ();

  entry->name = name;
  entry->type = type;
@@ -128,7 +128,7 @@
{
  table->chain_count = chain_count;
  table->entry_count = 0;
-  table->chain = GGC_CNEWVEC (binding_entry, table->chain_count);
+  table->chain = GGC_CNEWVEC_ATOMIC (binding_entry, table->chain_count);
}

/* Make TABLE's entries ready for reuse.  */
@@ -162,7 +162,7 @@
static inline binding_table
binding_table_new (size_t chain_count)
{
-  binding_table table = GGC_NEW (struct binding_table_s);
+  binding_table table = ggc_alloc_binding_table_s ();
  table->chain = NULL;
  binding_table_construct (table, chain_count);
  return table;
@@ -276,7 +276,7 @@
      free_bindings = binding->previous;
    }
  else
-    binding = GGC_NEW (cxx_binding);
+    binding = ggc_alloc_cxx_binding ();

cxx_binding_init (binding, value, type);

@@ -685,7 +685,7 @@
		      = htab_create_ggc (20, cxx_int_tree_map_hash,
					 cxx_int_tree_map_eq, NULL);

-		  h = GGC_NEW (struct cxx_int_tree_map);
+		  h = ggc_alloc_cxx_int_tree_map ();
		  h->uid = DECL_UID (x);
		  h->to = t;
		  loc = htab_find_slot_with_hash
@@ -1271,7 +1271,7 @@
      free_binding_level = scope->level_chain;
    }
  else
-    scope = GGC_NEW (cxx_scope);
+    scope = ggc_alloc_cxx_scope ();
  memset (scope, 0, sizeof (cxx_scope));

  scope->this_entity = entity;
@@ -4983,7 +4983,7 @@
  int need_pop;

  timevar_push (TV_NAME_LOOKUP);
-  s = GGC_CNEW (struct saved_scope);
+  s = ggc_alloc_cleared_saved_scope();

b = scope_chain ? current_binding_level : 0;

Index: gcc/cp/lex.c
===================================================================
--- gcc/cp/lex.c	(revision 116135)
+++ gcc/cp/lex.c	(working copy)
@@ -316,7 +316,7 @@
	      | D_OBJC
	      | (flag_no_gnu_keywords ? D_EXT : 0));

-  ridpointers = GGC_CNEWVEC (tree, (int) RID_MAX);
+  ridpointers = GGC_CNEWVEC_ATOMIC(tree, (int) RID_MAX);
  for (i = 0; i < ARRAY_SIZE (reswords); i++)
    {
      id = get_identifier (reswords[i].word);
@@ -684,12 +684,13 @@
  struct lang_decl *ld;
  size_t size;

+  /* TODO: find a way to use size for allocation too. */
  if (CAN_HAVE_FULL_LANG_DECL_P (t))
    size = sizeof (struct lang_decl);
  else
    size = sizeof (struct lang_decl_flags);

-  ld = GGC_CNEWVAR (struct lang_decl, size);
+  ld = ggc_alloc_cleared_lang_decl ();

  ld->decl_flags.can_be_full = CAN_HAVE_FULL_LANG_DECL_P (t) ? 1 : 0;
  ld->decl_flags.u1sel = TREE_CODE (t) == NAMESPACE_DECL ? 1 : 0;
@@ -723,11 +724,13 @@
  if (! DECL_LANG_SPECIFIC (node))
    return;

+  /*  TODO: find a way to put use this size for allocation */
  if (!CAN_HAVE_FULL_LANG_DECL_P (node))
    size = sizeof (struct lang_decl_flags);
  else
-    size = sizeof (struct lang_decl);
-  ld = GGC_NEWVAR (struct lang_decl, size);
+  size = sizeof (struct lang_decl);
+
+  ld = ggc_alloc_lang_decl ();
  memcpy (ld, DECL_LANG_SPECIFIC (node), size);
  DECL_LANG_SPECIFIC (node) = ld;

@@ -760,11 +763,12 @@
  if (! TYPE_LANG_SPECIFIC (node))
    return;

+  /*  TODO: find a way to use this size for allocation */
  if (TYPE_LANG_SPECIFIC (node)->u.h.is_lang_type_class)
    size = sizeof (struct lang_type);
  else
    size = sizeof (struct lang_type_ptrmem);
-  lt = GGC_NEWVAR (struct lang_type, size);
+  lt = ggc_alloc_lang_type ();
  memcpy (lt, TYPE_LANG_SPECIFIC (node), size);
  TYPE_LANG_SPECIFIC (node) = lt;

@@ -795,7 +799,7 @@
  if (IS_AGGR_TYPE_CODE (code)
      || code == BOUND_TEMPLATE_TEMPLATE_PARM)
    {
-      struct lang_type *pi = GGC_CNEW (struct lang_type);
+      struct lang_type *pi = ggc_alloc_cleared_lang_type();

      TYPE_LANG_SPECIFIC (t) = pi;
      pi->u.c.h.is_lang_type_class = 1;
Index: gcc/cp/parser.c
===================================================================
--- gcc/cp/parser.c	(revision 116135)
+++ gcc/cp/parser.c	(working copy)
@@ -263,7 +263,7 @@
  c_common_no_more_pch ();

  /* Allocate the memory.  */
-  lexer = GGC_CNEW (cp_lexer);
+  lexer = ggc_alloc_cleared_cp_lexer ();

#ifdef ENABLE_CHECKING
  /* Initially we are not debugging.  */
@@ -274,7 +274,10 @@

  /* Create the buffer.  */
  alloc = CP_LEXER_BUFFER_SIZE;
-  buffer = GGC_NEWVEC (cp_token, alloc);
+  buffer = GGC_NEWVEC_ATOMIC (cp_token, alloc);
+  /* TODO: atomic here looks very stinky.  Typed alloc below not possible
+     because of realloc.  */
+  /* buffer = ggc_alloc_vec_cp_token (alloc); */

  /* Put the first token in the buffer.  */
  space = alloc;
@@ -289,7 +292,7 @@
	{
	  space = alloc;
	  alloc *= 2;
-	  buffer = GGC_RESIZEVEC (cp_token, buffer, alloc);
+	  buffer = GGC_RESIZEVEC_ATOMIC (cp_token, buffer, alloc);
	  pos = buffer + space;
	}
      cp_lexer_get_preprocessor_token (lexer, pos);
@@ -316,7 +319,7 @@
{
  cp_token *first = cache->first;
  cp_token *last = cache->last;
-  cp_lexer *lexer = GGC_CNEW (cp_lexer);
+  cp_lexer *lexer = ggc_alloc_cleared_cp_lexer ();

  /* We do not own the buffer.  */
  lexer->buffer = NULL;
@@ -743,7 +746,7 @@
static cp_token_cache *
cp_token_cache_new (cp_token *first, cp_token *last)
{
-  cp_token_cache *cache = GGC_NEW (cp_token_cache);
+  cp_token_cache *cache = ggc_alloc_cp_token_cache ();
  cache->first = first;
  cache->last = last;
  return cache;
@@ -1191,7 +1194,7 @@
      memset (context, 0, sizeof (*context));
    }
  else
-    context = GGC_CNEW (cp_parser_context);
+    context = ggc_alloc_cleared_cp_parser_context ();

  /* No errors have occurred yet in this context.  */
  context->status = CP_PARSER_STATUS_KIND_NO_ERROR;
@@ -2472,7 +2475,7 @@
  cp_lexer *lexer;
  unsigned i;

-  /* cp_lexer_new_main is called before calling ggc_alloc because
+  /* cp_lexer_new_main is called before allocating GC memory because
     cp_lexer_new_main might load a PCH file.  */
  lexer = cp_lexer_new_main ();

@@ -2481,7 +2484,7 @@
  for (i = 0; i < sizeof (binops) / sizeof (binops[0]); i++)
    binops_by_token[binops[i].token_type] = binops[i];

-  parser = GGC_CNEW (cp_parser);
+  parser = ggc_alloc_cleared_cp_parser ();
  parser->lexer = lexer;
  parser->context = cp_parser_context_new (NULL);

Index: gcc/dbxout.c
===================================================================
--- gcc/dbxout.c	(revision 116135)
+++ gcc/dbxout.c	(working copy)
@@ -991,7 +991,7 @@
  tree syms = lang_hooks.decls.getdecls ();

  typevec_len = 100;
-  typevec = ggc_calloc (typevec_len, sizeof typevec[0]);
+  typevec = ggc_alloc_cleared_vec_typeinfo (typevec_len);

  /* stabstr_ob contains one string, which will be just fine with
     1-byte alignment.  */
@@ -1691,7 +1691,8 @@
      if (next_type_number == typevec_len)
	{
	  typevec
-	    = ggc_realloc (typevec, (typevec_len * 2 * sizeof typevec[0]));
+	    = ggc_realloc_atomic (typevec,
+				  typevec_len * 2 * sizeof typevec[0]);
	  memset (typevec + typevec_len, 0, typevec_len * sizeof typevec[0]);
	  typevec_len *= 2;
	}
Index: gcc/c-format.c
===================================================================
--- gcc/c-format.c	(revision 116135)
+++ gcc/c-format.c	(working copy)
@@ -250,7 +250,7 @@

/* Structure describing details of a type expected in format checking,
   and the type to check against it.  */
-typedef struct format_wanted_type
+typedef struct format_wanted_type GTY(())
{
  /* The type wanted.  */
  tree wanted_type;
@@ -2077,7 +2077,7 @@
	      fci = fci->chain;
	      if (fci)
		{
-		  wanted_type_ptr = GGC_NEW (format_wanted_type);
+		  wanted_type_ptr = ggc_alloc_format_wanted_type();
		  arg_num++;
		  wanted_type = *fci->types[length_chars_val].type;
		  wanted_type_name = fci->types[length_chars_val].name;
Index: gcc/tree-ssa-alias.c
===================================================================
--- gcc/tree-ssa-alias.c	(revision 116135)
+++ gcc/tree-ssa-alias.c	(working copy)
@@ -2451,7 +2451,7 @@
  pi = SSA_NAME_PTR_INFO (t);
  if (pi == NULL)
    {
-      pi = GGC_NEW (struct ptr_info_def);
+      pi = ggc_alloc_ptr_info_def();
      memset ((void *)pi, 0, sizeof (*pi));
      SSA_NAME_PTR_INFO (t) = pi;
    }
@@ -3001,7 +3001,7 @@
		  && fosize == lastfosize
		  && currfotype == lastfotype))
	    continue;
-	  sv = GGC_NEW (struct subvar);
+	  sv = ggc_alloc_subvar ();
	  sv->next = *subvars;
	  sv->var = create_sft (var, fo->type, fo->offset, fosize);

Index: gcc/dwarf2out.c
===================================================================
--- gcc/dwarf2out.c	(revision 116166)
+++ gcc/dwarf2out.c	(working copy)
@@ -2549,8 +2549,9 @@
  if (fde_table_in_use == fde_table_allocated)
    {
      fde_table_allocated += FDE_TABLE_INCREMENT;
-      fde_table = ggc_realloc (fde_table,
-			       fde_table_allocated * sizeof (dw_fde_node));
+      fde_table = ggc_realloc_atomic (fde_table,
+				      fde_table_allocated
+				      * sizeof (dw_fde_node));
      memset (fde_table + fde_table_in_use, 0,
	      FDE_TABLE_INCREMENT * sizeof (dw_fde_node));
    }
@@ -2609,7 +2610,8 @@
dwarf2out_frame_init (void)
{
  /* Allocate the initial hunk of the fde_table.  */
-  fde_table = ggc_alloc_cleared (FDE_TABLE_INCREMENT * sizeof (dw_fde_node));
+  fde_table = ggc_alloc_vec_atomic (sizeof (dw_fde_node),
+					   FDE_TABLE_INCREMENT);
  fde_table_allocated = FDE_TABLE_INCREMENT;
  fde_table_in_use = 0;

@@ -6504,8 +6506,9 @@
      if (abbrev_die_table_in_use >= abbrev_die_table_allocated)
	{
	  n_alloc = abbrev_die_table_allocated + ABBREV_DIE_TABLE_INCREMENT;
-	  abbrev_die_table = ggc_realloc (abbrev_die_table,
-					  sizeof (dw_die_ref) * n_alloc);
+	  abbrev_die_table = ggc_realloc_atomic (abbrev_die_table,
+						 sizeof (dw_die_ref)
+						 * n_alloc);

	  memset (&abbrev_die_table[abbrev_die_table_allocated], 0,
		 (n_alloc - abbrev_die_table_allocated) * sizeof (dw_die_ref));
@@ -7254,8 +7257,9 @@
    {
      pubname_table_allocated += PUBNAME_TABLE_INCREMENT;
      pubname_table
-	= ggc_realloc (pubname_table,
-		       (pubname_table_allocated * sizeof (pubname_entry)));
+	= ggc_realloc_atomic (pubname_table,
+			      (pubname_table_allocated
+			       * sizeof (pubname_entry)));
      memset (pubname_table + pubname_table_in_use, 0,
	      PUBNAME_TABLE_INCREMENT * sizeof (pubname_entry));
    }
@@ -7314,9 +7318,9 @@
  if (arange_table_in_use == arange_table_allocated)
    {
      arange_table_allocated += ARANGE_TABLE_INCREMENT;
-      arange_table = ggc_realloc (arange_table,
-				  (arange_table_allocated
-				   * sizeof (dw_die_ref)));
+      arange_table = ggc_realloc_atomic (arange_table,
+					 (arange_table_allocated
+					  * sizeof (dw_die_ref)));
      memset (arange_table + arange_table_in_use, 0,
	      ARANGE_TABLE_INCREMENT * sizeof (dw_die_ref));
    }
@@ -7420,8 +7424,9 @@
    {
      ranges_table_allocated += RANGES_TABLE_INCREMENT;
      ranges_table
-	= ggc_realloc (ranges_table, (ranges_table_allocated
-				      * sizeof (struct dw_ranges_struct)));
+	= ggc_realloc_atomic (ranges_table,
+			      (ranges_table_allocated
+			       * sizeof (struct dw_ranges_struct)));
      memset (ranges_table + ranges_table_in_use, 0,
	      RANGES_TABLE_INCREMENT * sizeof (struct dw_ranges_struct));
    }
@@ -9783,7 +9788,7 @@
	if (SCALAR_FLOAT_MODE_P (mode))
	  {
	    unsigned int length = GET_MODE_SIZE (mode);
-	    unsigned char *array = ggc_alloc (length);
+	    unsigned char *array = ggc_alloc_atomic (length);

	    insert_float (rtl, array);
	    add_AT_vec (die, DW_AT_const_value, length / 4, 4, array);
@@ -9804,7 +9809,7 @@
	enum machine_mode mode = GET_MODE (rtl);
	unsigned int elt_size = GET_MODE_UNIT_SIZE (mode);
	unsigned int length = CONST_VECTOR_NUNITS (rtl);
-	unsigned char *array = ggc_alloc (length * elt_size);
+	unsigned char *array = ggc_alloc_vec_atomic (length, elt_size);
	unsigned int i;
	unsigned char *p;

@@ -13608,9 +13613,9 @@
	    {
	      separate_line_info_table_allocated += LINE_INFO_TABLE_INCREMENT;
	      separate_line_info_table
-		= ggc_realloc (separate_line_info_table,
-			       separate_line_info_table_allocated
-			       * sizeof (dw_separate_line_info_entry));
+		= ggc_realloc_atomic (separate_line_info_table,
+				      separate_line_info_table_allocated
+				      * sizeof (dw_separate_line_info_entry));
	      memset (separate_line_info_table
		       + separate_line_info_table_in_use,
		      0,
@@ -13637,9 +13642,9 @@
	    {
	      line_info_table_allocated += LINE_INFO_TABLE_INCREMENT;
	      line_info_table
-		= ggc_realloc (line_info_table,
-			       (line_info_table_allocated
-				* sizeof (dw_line_info_entry)));
+		= ggc_realloc_atomic (line_info_table,
+				      (line_info_table_allocated
+				       * sizeof (dw_line_info_entry)));
	      memset (line_info_table + line_info_table_in_use, 0,
		      LINE_INFO_TABLE_INCREMENT * sizeof (dw_line_info_entry));
	    }
@@ -13749,15 +13754,14 @@
  decl_scope_table = VEC_alloc (tree, gc, 256);

  /* Allocate the initial hunk of the abbrev_die_table.  */
-  abbrev_die_table = ggc_alloc_cleared (ABBREV_DIE_TABLE_INCREMENT
-					* sizeof (dw_die_ref));
+  abbrev_die_table = ggc_alloc_cleared_vec_atomic (sizeof(dw_die_ref),
+						   ABBREV_DIE_TABLE_INCREMENT);
  abbrev_die_table_allocated = ABBREV_DIE_TABLE_INCREMENT;
  /* Zero-th entry is allocated, but unused.  */
  abbrev_die_table_in_use = 1;

  /* Allocate the initial hunk of the line_info_table.  */
-  line_info_table = ggc_alloc_cleared (LINE_INFO_TABLE_INCREMENT
-				       * sizeof (dw_line_info_entry));
+  line_info_table = ggc_alloc_cleared_vec_dw_line_info_struct
(LINE_INFO_TABLE_INCREMENT);
  line_info_table_allocated = LINE_INFO_TABLE_INCREMENT;

  /* Zero-th entry is allocated, but unused.  */
Index: gcc/c-decl.c
===================================================================
--- gcc/c-decl.c	(revision 116135)
+++ gcc/c-decl.c	(working copy)
@@ -489,7 +489,7 @@
      binding_freelist = b->prev;
    }
  else
-    b = GGC_NEW (struct c_binding);
+    b = ggc_alloc_c_binding();

  b->shadowed = 0;
  b->decl = decl;
@@ -659,7 +659,7 @@
	  scope_freelist = scope->outer;
	}
      else
-	scope = GGC_CNEW (struct c_scope);
+	scope = ggc_alloc_cleared_c_scope ();

      scope->keep          = keep_next_level_flag;
      scope->outer         = current_scope;
@@ -2038,7 +2038,7 @@

  /* Functions need the lang_decl data.  */
  if (TREE_CODE (x) == FUNCTION_DECL && !DECL_LANG_SPECIFIC (x))
-    DECL_LANG_SPECIFIC (x) = GGC_CNEW (struct lang_decl);
+    DECL_LANG_SPECIFIC (x) = ggc_alloc_cleared_lang_decl ();

  /* Must set DECL_CONTEXT for everything not at file scope or
     DECL_FILE_SCOPE_P won't work.  Local externs don't count
@@ -2815,7 +2815,7 @@
  tree decl = build_decl (FUNCTION_DECL, id, type);
  TREE_PUBLIC (decl) = 1;
  DECL_EXTERNAL (decl) = 1;
-  DECL_LANG_SPECIFIC (decl) = GGC_CNEW (struct lang_decl);
+  DECL_LANG_SPECIFIC (decl) = ggc_alloc_cleared_lang_decl ();
  DECL_BUILT_IN_CLASS (decl) = cl;
  DECL_FUNCTION_CODE (decl) = function_code;
  C_DECL_BUILTIN_PROTOTYPE (decl) = (TYPE_ARG_TYPES (type) != 0);
@@ -4670,7 +4670,7 @@
	decl = build_decl (FUNCTION_DECL, declarator->u.id, type);
	decl = build_decl_attribute_variant (decl, decl_attr);

-	DECL_LANG_SPECIFIC (decl) = GGC_CNEW (struct lang_decl);
+	DECL_LANG_SPECIFIC (decl) = ggc_alloc_cleared_lang_decl ();

	if (pedantic && type_quals && !DECL_IN_SYSTEM_HEADER (decl))
	  pedwarn ("ISO C forbids qualified function types");
@@ -5546,9 +5546,9 @@
	  ensure that this lives as long as the rest of the struct decl.
	  All decls in an inline function need to be saved.  */

-	space = GGC_CNEW (struct lang_type);
-	space2 = GGC_NEWVAR (struct sorted_fields_type,
-			     sizeof (struct sorted_fields_type) + len * sizeof (tree));
+	space = ggc_alloc_cleared_lang_type ();
+	space2 = ggc_alloc_sorted_fields_type (sizeof (struct sorted_fields_type)
+					       + len * sizeof (tree));

	len = 0;
	space->s = space2;
@@ -5794,7 +5794,7 @@

  /* Record the min/max values so that we can warn about bit-field
     enumerations that are too small for the values.  */
-  lt = GGC_CNEW (struct lang_type);
+  lt = ggc_alloc_cleared_lang_type ();
  lt->enum_min = minnode;
  lt->enum_max = maxnode;
  TYPE_LANG_SPECIFIC (enumtype) = lt;
@@ -6837,7 +6837,7 @@
c_push_function_context (struct function *f)
{
  struct language_function *p;
-  p = GGC_NEW (struct language_function);
+  p = ggc_alloc_language_function();
  f->language = p;

  p->base.x_stmt_tree = c_stmt_tree;
@@ -6893,7 +6893,7 @@
  if (!DECL_LANG_SPECIFIC (decl))
    return;

-  ld = GGC_NEW (struct lang_decl);
+  ld = ggc_alloc_lang_decl();
  memcpy (ld, DECL_LANG_SPECIFIC (decl), sizeof (struct lang_decl));
  DECL_LANG_SPECIFIC (decl) = ld;
}
Index: gcc/tree-eh.c
===================================================================
--- gcc/tree-eh.c	(revision 116135)
+++ gcc/tree-eh.c	(working copy)
@@ -100,7 +100,7 @@
  gcc_assert (num >= 0);
  gcc_assert (TREE_CODE (t) != RESX_EXPR);

-  n = GGC_NEW (struct throw_stmt_node);
+  n = ggc_alloc_throw_stmt_node();
  n->stmt = t;
  n->region_nr = num;

Index: gcc/lambda-trans.c
===================================================================
--- gcc/lambda-trans.c	(revision 116166)
+++ gcc/lambda-trans.c	(working copy)
@@ -35,7 +35,7 @@
{
  lambda_trans_matrix ret;

-  ret = ggc_alloc (sizeof (struct lambda_trans_matrix_def));
+  ret = ggc_alloc_atomic (sizeof (*ret));
  LTM_MATRIX (ret) = lambda_matrix_new (rowsize, colsize);
  LTM_ROWSIZE (ret) = rowsize;
  LTM_COLSIZE (ret) = colsize;
Index: gcc/local-alloc.c
===================================================================
--- gcc/local-alloc.c	(revision 116135)
+++ gcc/local-alloc.c	(working copy)
@@ -801,7 +801,7 @@

  reg_equiv = XCNEWVEC (struct equivalence, max_regno);
  INIT_REG_SET (&cleared_regs);
-  reg_equiv_init = ggc_alloc_cleared (max_regno * sizeof (rtx));
+  reg_equiv_init = ggc_alloc_cleared_vec_atomic (sizeof (rtx), max_regno);
  reg_equiv_init_size = max_regno;

  init_alias_analysis ();
Index: gcc/alias.c
===================================================================
--- gcc/alias.c	(revision 116135)
+++ gcc/alias.c	(working copy)
@@ -2421,7 +2421,8 @@
  timevar_push (TV_ALIAS_ANALYSIS);

  reg_known_value_size = maxreg - FIRST_PSEUDO_REGISTER;
-  reg_known_value = ggc_calloc (reg_known_value_size, sizeof (rtx));
+  reg_known_value = ggc_alloc_cleared_vec_atomic (reg_known_value_size,
+						  sizeof (rtx));
  reg_known_equiv_p = xcalloc (reg_known_value_size, sizeof (bool));

  /* If we have memory allocated from the previous run, use it.  */
Index: gcc/ggc.h
===================================================================
--- gcc/ggc.h	(revision 116165)
+++ gcc/ggc.h	(working copy)
@@ -202,54 +202,76 @@
extern bool ggc_force_collect;

/* The internal primitive.  */
-extern void *ggc_alloc_stat (size_t MEM_STAT_DECL);
-#define ggc_alloc(s) ggc_alloc_stat (s MEM_STAT_INFO)
+extern void *ggc_internal_alloc_stat (size_t MEM_STAT_DECL);
+#define ggc_internal_alloc(s) ggc_internal_alloc_stat (s MEM_STAT_INFO)
+
/* Allocate an object of the specified type and size.  */
extern void *ggc_alloc_typed_stat (enum gt_types_enum, size_t MEM_STAT_DECL);
#define ggc_alloc_typed(s,z) ggc_alloc_typed_stat (s,z MEM_STAT_INFO)
+#define ggc_alloc_vec_typed(s, z) ggc_alloc_typed_stat (s,z MEM_STAT_INFO)
+
/* Like ggc_alloc, but allocates cleared memory.  */
-extern void *ggc_alloc_cleared_stat (size_t MEM_STAT_DECL);
+extern void *ggc_internal_alloc_cleared_stat (size_t MEM_STAT_DECL);
extern void *ggc_alloc_cleared_typed_stat (enum gt_types_enum,
					   size_t MEM_STAT_DECL);
-#define ggc_alloc_cleared_typed(s, z)
ggc_alloc_cleared_typed_stat(s,z MEM_STAT_INFO)
-#define ggc_alloc_cleared(s) ggc_alloc_cleared_stat (s MEM_STAT_INFO)
+#define ggc_alloc_cleared_typed(s, z)		\
+  ggc_alloc_cleared_typed_stat(s,z MEM_STAT_INFO)
+
+#define ggc_alloc_cleared_vec_typed(s, z)		\
+  ggc_alloc_cleared_typed_stat(s,z MEM_STAT_INFO)
+
+#define ggc_internal_alloc_cleared(s)			\
+  ggc_internal_alloc_cleared_stat (s MEM_STAT_INFO)
+
+extern void *ggc_alloc_atomic_stat (size_t MEM_STAT_DECL);
+#define ggc_alloc_atomic(s) ggc_alloc_atomic_stat (s MEM_STAT_INFO)
+
+extern void *ggc_alloc_cleared_atomic_stat (size_t MEM_STAT_DECL);
+#define ggc_alloc_cleared_atomic(s) ggc_alloc_cleared_atomic_stat (s
MEM_STAT_INFO)
+#define ggc_alloc_vec_atomic(s, n) ggc_alloc_atomic((n) * (s))
+#define ggc_alloc_cleared_vec_atomic(s, n) ggc_alloc_cleared_atomic((n) * (s))
+
/* Resize a block.  */
-extern void *ggc_realloc_stat (void *, size_t MEM_STAT_DECL);
-#define ggc_realloc(s,z) ggc_realloc_stat (s,z MEM_STAT_INFO)
-/* Like ggc_alloc_cleared, but performs a multiplication.  */
-extern void *ggc_calloc (size_t, size_t);
+extern void *ggc_realloc_atomic_stat (void *, size_t MEM_STAT_DECL);
+#define ggc_realloc_atomic(s,z) ggc_realloc_atomic_stat (s,z MEM_STAT_INFO)
+extern void *ggc_calloc_atomic (size_t, size_t);
/* Free a block.  To be used when known for certain it's not reachable.  */
extern void ggc_free (void *);
-
+
extern void ggc_record_overhead (size_t, size_t, void * MEM_STAT_DECL);
extern void ggc_free_overhead (void *);
extern void ggc_prune_overhead_list (void);

extern void dump_ggc_loc_statistics (void);

-/* Type-safe, C++-friendly versions of ggc_alloc() and gcc_calloc().  */
-#define GGC_NEW(T)		((T *) ggc_alloc (sizeof (T)))
-#define GGC_CNEW(T)		((T *) ggc_alloc_cleared (sizeof (T)))
-#define GGC_NEWVEC(T, N)	((T *) ggc_alloc ((N) * sizeof(T)))
-#define GGC_CNEWVEC(T, N)	((T *) ggc_alloc_cleared ((N) * sizeof(T)))
-#define GGC_NEWVAR(T, S)	((T *) ggc_alloc ((S)))
-#define GGC_CNEWVAR(T, S)	((T *) ggc_alloc_cleared ((S)))
-#define GGC_RESIZEVEC(T, P, N)  ((T *) ggc_realloc ((P), (N) * sizeof (T)))
+/* Type-safe, C++-friendly versions of ggc_alloc() and gcc_calloc() for atomic
+   data structures.  */
+#define GGC_NEW_ATOMIC(T)       ((T *) ggc_alloc_atomic (sizeof (T)))
+#define GGC_CNEW_ATOMIC(T)	((T *) ggc_alloc_cleared_atomic (sizeof (T)))
+#define GGC_NEWVEC_ATOMIC(T, N)	((T *) ggc_alloc_vec_atomic (sizeof(T), (N)))
+#define GGC_CNEWVEC_ATOMIC(T, N) ((T *) ggc_alloc_cleared_vec_atomic
(sizeof(T), (N)))
+#define GGC_NEWVAR_ATOMIC(T, S)	 ((T *) ggc_alloc_atomic ((S)))
+#define GGC_CNEWVAR_ATOMIC(T, S) ((T *) ggc_alloc_cleared_atomic ((S)))
+#define GGC_RESIZEVEC_ATOMIC(T, P, N)   ((T *) ggc_realloc_atomic
((P), (N) * sizeof (T)))

#define ggc_alloc_rtvec(NELT)						 \
-  ((rtvec) ggc_alloc_zone (sizeof (struct rtvec_def) + ((NELT) - 1)	 \
-			   * sizeof (rtx), &rtl_zone))
+  ((rtvec) ggc_alloc_rtvec_def (sizeof (struct rtvec_def) + ((NELT) - 1) \
+				* sizeof (rtx))) /* TODO: rtl_zone */

-#define ggc_alloc_tree(LENGTH) ((tree) ggc_alloc_zone (LENGTH, &tree_zone))
+#define ggc_alloc_tree(LENGTH) ((tree) ggc_alloc_tree_node (LENGTH))
/* TODO: tree_zone */

#define htab_create_ggc(SIZE, HASH, EQ, DEL) \
-  htab_create_alloc (SIZE, HASH, EQ, DEL, ggc_calloc, NULL)
+  htab_create_alloc (SIZE, HASH, EQ, DEL, ggc_calloc_atomic, NULL)

-#define splay_tree_new_ggc(COMPARE)					 \
-  splay_tree_new_with_allocator (COMPARE, NULL, NULL,			 \
-                                 &ggc_splay_alloc, &ggc_splay_dont_free, \
+#define splay_tree_new_ggc(COMPARE)				       \
+  splay_tree_new_with_allocator (COMPARE, NULL, NULL,		       \
+				 &ggc_splay_alloc_tree,		       \
+				 &ggc_splay_alloc_tree_node,	       \
+				 &ggc_splay_dont_free,		       \
				 NULL)
-extern void *ggc_splay_alloc (int, void *);
+
+extern void *ggc_splay_alloc_tree (int, void *);
+extern void *ggc_splay_alloc_tree_node (int, void *);
extern void ggc_splay_dont_free (void *, void *);

/* Allocate a gc-able string, and fill it with LENGTH bytes from CONTENTS.
@@ -307,13 +329,19 @@
extern struct alloc_zone tree_id_zone;

/* Allocate an object into the specified allocation zone.  */
-extern void *ggc_alloc_zone_stat (size_t, struct alloc_zone * MEM_STAT_DECL);
-# define ggc_alloc_zone(s,z) ggc_alloc_zone_stat (s,z MEM_STAT_INFO)
-# define ggc_alloc_zone_pass_stat(s,z) ggc_alloc_zone_stat (s,z PASS_MEM_STAT)
+extern void *ggc_internal_alloc_zone_stat (size_t,
+					   struct alloc_zone * MEM_STAT_DECL);
+# define ggc_internal_alloc_zone(s,z)			\
+  ggc_internal_alloc_zone_stat (s,z MEM_STAT_INFO)
+
+# define ggc_internal_alloc_zone_pass_stat(s,z) \
+  ggc_internal_alloc_zone_stat (s,z PASS_MEM_STAT)
+
#else

-# define ggc_alloc_zone(s, z) ggc_alloc (s)
-# define ggc_alloc_zone_pass_stat(s, z) ggc_alloc_stat (s PASS_MEM_STAT)
+# define ggc_intenal_alloc_zone(s, z) ggc_internal_alloc (s)
+# define ggc_internal_alloc_zone_pass_stat(s, z)	\
+  ggc_internal_alloc_stat (s PASS_MEM_STAT)

#endif

Index: gcc/c-typeck.c
===================================================================
--- gcc/c-typeck.c	(revision 116135)
+++ gcc/c-typeck.c	(working copy)
@@ -4846,7 +4846,7 @@

struct constructor_range_stack;

-struct constructor_stack
+struct constructor_stack GTY(())
{
  struct constructor_stack *next;
  tree type;
@@ -5538,7 +5538,7 @@
{
  struct constructor_range_stack *p;

-  p = GGC_NEW (struct constructor_range_stack);
+  p = ggc_alloc_constructor_range_stack();
  p->prev = constructor_range_stack;
  p->next = 0;
  p->fields = constructor_fields;
@@ -5703,7 +5703,7 @@
	}
    }

-  r = GGC_NEW (struct init_node);
+  r = ggc_alloc_init_node();
  r->purpose = purpose;
  r->value = value;

Index: gcc/treelang/parse.y
===================================================================
--- gcc/treelang/parse.y	(revision 116135)
+++ gcc/treelang/parse.y	(working copy)
@@ -38,6 +38,7 @@
#include "config.h"
#include "system.h"
#include "coretypes.h"
+#include "ggc.h"
#include "tm.h"
#include "timevar.h"
#include "tree.h"
@@ -300,7 +301,7 @@
      gcc_assert (this_parm_var->category == production_category);
      gcc_assert (this_parm_var->tp.pro.main_token);

-      this_parms = my_malloc (sizeof (struct prod_token_parm_item));
+      this_parms = ggc_alloc_cleared_prod_token_parm_item ();

      this_parms->tp.par.variable_name =
	this_parm_var->tp.pro.main_token->tp.tok.chars;
Index: gcc/treelang/lex.l
===================================================================
--- gcc/treelang/lex.l	(revision 116135)
+++ gcc/treelang/lex.l	(working copy)
@@ -36,6 +36,7 @@
#include "system.h"
#include "coretypes.h"
#include "tm.h"
+#include "ggc.h"
#include "input.h"
#include "tree.h"

@@ -76,7 +77,7 @@

 {
   /* ??? Should really allocate only what we need.  */
-   yylval = my_malloc (sizeof (struct prod_token_parm_item));
+   yylval = ggc_alloc_cleared_prod_token_parm_item ();
   LINEMAP_POSITION_FOR_COLUMN (input_location, &line_table,
				next_tree_charno);
   ((struct prod_token_parm_item *)yylval)->tp.tok.location = input_location;
Index: gcc/treelang/treelang.h
===================================================================
--- gcc/treelang/treelang.h	(revision 116135)
+++ gcc/treelang/treelang.h	(working copy)
@@ -1,4 +1,4 @@
-/*
+/*

TREELANG Compiler common definitions (treelang.h)

@@ -146,7 +146,6 @@
   union. */
#define YYSTYPE void *

-void *my_malloc (size_t size);
int insert_tree_name (struct prod_token_parm_item *prod);
struct prod_token_parm_item *lookup_tree_name (struct
prod_token_parm_item *prod);
struct prod_token_parm_item *make_production (int type, struct
prod_token_parm_item *main_tok);
Index: gcc/treelang/tree1.c
===================================================================
--- gcc/treelang/tree1.c	(revision 116135)
+++ gcc/treelang/tree1.c	(working copy)
@@ -207,23 +207,6 @@
  cgraph_optimize ();
}

-/* Allocate SIZE bytes and clear them.  Not to be used for strings
-   which must go in stringpool.  */
-
-void *
-my_malloc (size_t size)
-{
-  void *mem;
-  mem = ggc_alloc (size);
-  if (!mem)
-    {
-      fprintf (stderr, "\nOut of memory\n");
-      abort ();
-    }
-  memset (mem, 0, size);
-  return mem;
-}
-
/* Look up a name in PROD->SYMBOL_TABLE_NAME in the symbol table;
   return the symbol table entry from the symbol table if found there,
   else 0.  */
@@ -291,12 +274,12 @@
make_production (int type, struct prod_token_parm_item *main_tok)
{
  struct prod_token_parm_item *prod;
-  prod = my_malloc (sizeof (struct prod_token_parm_item));
+  prod = ggc_alloc_cleared_prod_token_parm_item ();
  prod->category = production_category;
  prod->type = type;
  prod->tp.pro.main_token = main_tok;
  return prod;
-}
+}

/* Abort if ITEM is not a valid structure, based on 'category'. */

Index: gcc/c-pragma.c
===================================================================
--- gcc/c-pragma.c	(revision 116135)
+++ gcc/c-pragma.c	(working copy)
@@ -76,7 +76,7 @@
{
  align_stack * entry;

-  entry = GGC_NEW (align_stack);
+  entry = ggc_alloc_align_stack();

  entry->alignment  = alignment;
  entry->id	    = id;
Index: gcc/ggc-common.c
===================================================================
--- gcc/ggc-common.c	(revision 116135)
+++ gcc/ggc-common.c	(working copy)
@@ -26,6 +26,7 @@
#include "system.h"
#include "coretypes.h"
#include "hashtab.h"
+#include "splay-tree.h"
#include "ggc.h"
#include "toplev.h"
#include "params.h"
@@ -133,28 +134,34 @@

/* Allocate a block of memory, then clear it.  */
void *
-ggc_alloc_cleared_stat (size_t size MEM_STAT_DECL)
+ggc_internal_alloc_cleared_stat (size_t size MEM_STAT_DECL)
{
-  void *buf = ggc_alloc_stat (size PASS_MEM_STAT);
+  void *buf = ggc_internal_alloc_stat (size PASS_MEM_STAT);
  memset (buf, 0, size);
  return buf;
}

-/* Like ggc_alloc_cleared, but performs a multiplication.  */
void *
-ggc_calloc (size_t s1, size_t s2)
+ggc_calloc_atomic (size_t s, size_t n)
{
-  return ggc_alloc_cleared (s1 * s2);
+  return ggc_alloc_vec_atomic(s, n);
}

/* These are for splay_tree_new_ggc.  */
void *
-ggc_splay_alloc (int sz, void *nl)
+ggc_splay_alloc_tree (int sz ATTRIBUTE_UNUSED, void *nl)
{
  gcc_assert (!nl);
-  return ggc_alloc (sz);
+  return ggc_alloc_splay_tree_s();
}

+void *
+ggc_splay_alloc_tree_node (int sz ATTRIBUTE_UNUSED, void *nl)
+{
+  gcc_assert (!nl);
+  return ggc_alloc_splay_tree_node_s();
+}
+
void
ggc_splay_dont_free (void * x ATTRIBUTE_UNUSED, void *nl)
{
Index: gcc/tree-dfa.c
===================================================================
--- gcc/tree-dfa.c	(revision 116166)
+++ gcc/tree-dfa.c	(working copy)
@@ -142,7 +142,7 @@
  gcc_assert (DECL_P (t));
  gcc_assert (!t->common.ann || t->common.ann->common.type == VAR_ANN);

-  ann = GGC_NEW (struct var_ann_d);
+  ann = ggc_alloc_var_ann_d();
  memset ((void *) ann, 0, sizeof (*ann));

  ann->common.type = VAR_ANN;
@@ -183,7 +183,7 @@
  gcc_assert (is_gimple_stmt (t));
  gcc_assert (!t->common.ann || t->common.ann->common.type == STMT_ANN);

-  ann = GGC_NEW (struct stmt_ann_d);
+  ann = ggc_alloc_stmt_ann_d();
  memset ((void *) ann, 0, sizeof (*ann));

  ann->common.type = STMT_ANN;
@@ -206,7 +206,7 @@
  gcc_assert (t);
  gcc_assert (!t->common.ann || t->common.ann->common.type == TREE_ANN_COMMON);

-  ann = GGC_NEW (union tree_ann_d);
+  ann = ggc_alloc_tree_ann_d();
  memset ((void *) ann, 0, sizeof (*ann));

  ann->common.type = TREE_ANN_COMMON;
@@ -643,7 +643,7 @@
      return false;
    }

-  h = GGC_NEW (struct int_tree_map);
+  h = ggc_alloc_int_tree_map();
  h->uid = uid;
  h->to = to;
  loc = htab_find_slot_with_hash (referenced_vars, h, uid, INSERT);
@@ -689,7 +689,7 @@
  /* Default definition might be changed by tail call optimization.  */
  if (!*loc)
    {
-      h = GGC_NEW (struct int_tree_map);
+      h = ggc_alloc_int_tree_map();
      h->uid = DECL_UID (var);
      h->to = def;
      *(struct int_tree_map **)  loc = h;
Index: gcc/except.c
===================================================================
--- gcc/except.c	(revision 116166)
+++ gcc/except.c	(working copy)
@@ -3238,7 +3238,7 @@
  if (used >= size)
    {
      size = (size ? size * 2 : 64);
-      data = ggc_realloc (data, sizeof (*data) * size);
+      data = ggc_realloc_atomic (data, sizeof (*data) * size);
      cfun->eh->call_site_data = data;
      cfun->eh->call_site_data_size = size;
    }
Index: gcc/emit-rtl.c
===================================================================
--- gcc/emit-rtl.c	(revision 116166)
+++ gcc/emit-rtl.c	(working copy)
@@ -796,12 +796,12 @@
      char *new;
      rtx *new1;

-      new = ggc_realloc (f->emit->regno_pointer_align, old_size * 2);
+      new = ggc_realloc_atomic (f->emit->regno_pointer_align, old_size * 2);
      memset (new + old_size, 0, old_size);
      f->emit->regno_pointer_align = (unsigned char *) new;

-      new1 = ggc_realloc (f->emit->x_regno_reg_rtx,
-			  old_size * 2 * sizeof (rtx));
+      new1 = ggc_realloc_atomic (f->emit->x_regno_reg_rtx,
+				 old_size * 2 * sizeof (rtx));
      memset (new1 + old_size, 0, old_size * sizeof (rtx));
      regno_reg_rtx = new1;

@@ -4980,11 +4980,11 @@
  f->emit->regno_pointer_align_length = LAST_VIRTUAL_REGISTER + 101;

  f->emit->regno_pointer_align
-    = ggc_alloc_cleared (f->emit->regno_pointer_align_length
-			 * sizeof (unsigned char));
+    = ggc_alloc_cleared_vec_atomic (f->emit->regno_pointer_align_length,
+				    sizeof (unsigned char));

  regno_reg_rtx
-    = ggc_alloc (f->emit->regno_pointer_align_length * sizeof (rtx));
+    = ggc_alloc_vec_atomic (f->emit->regno_pointer_align_length, sizeof(rtx));

  /* Put copies of all the hard registers into regno_reg_rtx.  */
  memcpy (regno_reg_rtx,
Index: gcc/stringpool.c
===================================================================
--- gcc/stringpool.c	(revision 116135)
+++ gcc/stringpool.c	(working copy)
@@ -59,7 +59,7 @@
static void *
stringpool_ggc_alloc (size_t x)
{
-  return ggc_alloc (x); /* TODO: specialized alloc for no pointers inside? */
+  return ggc_alloc_atomic (x);
}

/* Initialize the string pool.  */
@@ -213,7 +213,7 @@

struct string_pool_data GTY(())
{
-  struct ht_identifier * *
+  struct ht_identifier * *
    GTY((length ("%h.nslots"),
	 nested_ptr (union tree_node, "%h ? GCC_IDENT_TO_HT_IDENT (%h) : NULL",
		     "%h ? HT_IDENT_TO_GCC_IDENT (%h) : NULL")))
@@ -229,10 +229,10 @@
void
gt_pch_save_stringpool (void)
{
-  spd = ggc_alloc (sizeof (*spd));
+  spd = ggc_alloc_string_pool_data ();
  spd->nslots = ident_hash->nslots;
  spd->nelements = ident_hash->nelements;
-  spd->entries = ggc_alloc (sizeof (spd->entries[0]) * spd->nslots);
+  spd->entries = ggc_alloc_vec_atomic (sizeof (spd->entries[0]), spd->nslots);
  memcpy (spd->entries, ident_hash->entries,
	  spd->nslots * sizeof (spd->entries[0]));
}
Index: gcc/lambda.h
===================================================================
--- gcc/lambda.h	(revision 116135)
+++ gcc/lambda.h	(working copy)
@@ -145,7 +145,7 @@
bool perfect_nest_p (struct loop *);
void print_lambda_loopnest (FILE *, lambda_loopnest, char);

-#define lambda_loop_new() (lambda_loop) ggc_alloc_cleared (sizeof
(struct lambda_loop_s))
+#define lambda_loop_new() (lambda_loop) ggc_alloc_cleared_atomic
(sizeof (struct lambda_loop_s))

void print_lambda_loop (FILE *, lambda_loop, int, int, char);

@@ -224,7 +224,7 @@
static inline lambda_vector
lambda_vector_new (int size)
{
-  return GGC_CNEWVEC (int, size);
+  return GGC_CNEWVEC_ATOMIC (int, size);
}


Index: gcc/varasm.c =================================================================== --- gcc/varasm.c (revision 116166) +++ gcc/varasm.c (working copy) @@ -254,7 +254,7 @@ { section *sect;

-  sect = ggc_alloc_unnamed_section();
+  sect = ggc_alloc_section();
  sect->unnamed.common.flags = flags | SECTION_UNNAMED;
  sect->unnamed.callback = callback;
  sect->unnamed.data = data;
@@ -271,7 +271,7 @@
{
  section *sect;

-  sect = ggc_alloc_unnamed_section();
+  sect = ggc_alloc_section();
  sect->noswitch.common.flags = flags | SECTION_NOSWITCH;
  sect->noswitch.callback = callback;

@@ -292,7 +292,7 @@
  flags |= SECTION_NAMED;
  if (*slot == NULL)
    {
-      sect = ggc_alloc_named_section();
+      sect = ggc_alloc_section();
      sect->named.common.flags = flags;
      sect->named.name = ggc_strdup (name);
      sect->named.decl = decl;
@@ -361,7 +361,7 @@

  /* Create the extended SYMBOL_REF.  */
  size = RTX_HDR_SIZE + sizeof (struct block_symbol);
-  symbol = ggc_alloc_zone (size, &rtl_zone);
+  symbol = ggc_alloc_rtx_def (size);

  /* Initialize the normal SYMBOL_REF fields.  */
  memset (symbol, 0, size);
Index: gcc/tree-nested.c
===================================================================
--- gcc/tree-nested.c	(revision 116166)
+++ gcc/tree-nested.c	(working copy)
@@ -300,7 +300,7 @@

insert_field_into_struct (get_frame_type (info), field);

-      elt = GGC_NEW (struct var_map_elt);
+      elt = ggc_alloc_var_map_elt();
      elt->old = decl;
      elt->new = field;
      *slot = elt;
@@ -486,7 +486,7 @@

insert_field_into_struct (get_frame_type (info), field);

-      elt = GGC_NEW (struct var_map_elt);
+      elt = ggc_alloc_var_map_elt();
      elt->old = decl;
      elt->new = field;
      *slot = elt;
@@ -717,7 +717,7 @@
static struct nesting_info *
create_nesting_tree (struct cgraph_node *cgn)
{
-  struct nesting_info *info = GGC_CNEW (struct nesting_info);
+  struct nesting_info *info = ggc_alloc_cleared_nesting_info ();
  info->field_map = htab_create_ggc (7, var_map_hash, var_map_eq, ggc_free);
  info->var_map = htab_create_ggc (7, var_map_hash, var_map_eq, ggc_free);
  info->suppress_expansion = BITMAP_GGC_ALLOC ();
@@ -1472,14 +1472,14 @@
      new_label = create_artificial_label ();
      DECL_NONLOCAL (new_label) = 1;

-      elt = GGC_NEW (struct var_map_elt);
+      elt = ggc_alloc_var_map_elt();
      elt->old = label;
      elt->new = new_label;
      *slot = elt;
    }
  else
    new_label = elt->new;
-
+
  /* Build: __builtin_nl_goto(new_label, &chain->nl_goto_field).  */
  field = get_nl_goto_field (i);
  x = get_frame_field (info, target_context, field, &wi->tsi);
Index: gcc/lambda-code.c
===================================================================
--- gcc/lambda-code.c	(revision 116135)
+++ gcc/lambda-code.c	(working copy)
@@ -156,7 +156,7 @@
{
  lambda_body_vector ret;

-  ret = ggc_alloc (sizeof (*ret));
+  ret = ggc_alloc_atomic (sizeof (*ret));
  LBV_COEFFICIENTS (ret) = lambda_vector_new (size);
  LBV_SIZE (ret) = size;
  LBV_DENOMINATOR (ret) = 1;
@@ -228,7 +228,7 @@
{
  lambda_linear_expression ret;

-  ret = ggc_alloc_cleared (sizeof (*ret));
+  ret = ggc_alloc_cleared_atomic (sizeof (*ret));

  LLE_COEFFICIENTS (ret) = lambda_vector_new (dim);
  LLE_CONSTANT (ret) = 0;
@@ -329,9 +329,9 @@
lambda_loopnest_new (int depth, int invariants)
{
  lambda_loopnest ret;
-  ret = ggc_alloc (sizeof (*ret));
+  ret = ggc_alloc_atomic (sizeof (*ret));

-  LN_LOOPS (ret) = ggc_alloc_cleared (depth * sizeof (lambda_loop));
+  LN_LOOPS (ret) = ggc_alloc_cleared_vec_atomic (depth, sizeof (lambda_loop));
  LN_DEPTH (ret) = depth;
  LN_INVARIANTS (ret) = invariants;

@@ -361,7 +361,7 @@
lambda_lattice_new (int depth, int invariants)
{
  lambda_lattice ret;
-  ret = ggc_alloc (sizeof (*ret));
+  ret = ggc_alloc_atomic (sizeof (*ret));
  LATTICE_BASE (ret) = lambda_matrix_new (depth, depth);
  LATTICE_ORIGIN (ret) = lambda_vector_new (depth);
  LATTICE_ORIGIN_INVARIANTS (ret) = lambda_matrix_new (depth, invariants);
Index: gcc/rtl.c
===================================================================
--- gcc/rtl.c	(revision 116135)
+++ gcc/rtl.c	(working copy)
@@ -188,7 +188,7 @@
{
  rtx rt;

-  rt = (rtx) ggc_alloc_zone_pass_stat (RTX_CODE_SIZE (code), &rtl_zone);
+  rt = ggc_alloc_rtx_def (RTX_CODE_SIZE (code)); /* TODO: rtl_zone */

  /* We want to clear everything up to the FLD array.  Normally, this
     is one int, but we don't want to assume that and it isn't very
@@ -313,13 +313,13 @@
/* Create a new copy of an rtx.  Only copy just one level.  */

rtx
-shallow_copy_rtx_stat (rtx orig MEM_STAT_DECL)
+shallow_copy_rtx_stat (rtx orig MEM_STAT_DECL) /* TODO: broken MEM_STAT */
{
  unsigned int size;
  rtx copy;

  size = rtx_size (orig);
-  copy = (rtx) ggc_alloc_zone_pass_stat (size, &rtl_zone);
+  copy = ggc_alloc_rtx_def (size); /* TODO: rtl_zone */
  memcpy (copy, orig, size);
  return copy;
}
Index: gcc/rtl.h
===================================================================
--- gcc/rtl.h	(revision 116135)
+++ gcc/rtl.h	(working copy)
@@ -346,7 +346,7 @@
   for a variable number of things.  The principle use is inside
   PARALLEL expressions.  */

-struct rtvec_def GTY(()) {
+struct rtvec_def GTY((size_not_fixed(""))) {
  int num_elem;		/* number of elements */
  rtx GTY ((length ("%h.num_elem"))) elem[1];
};
Index: gcc/integrate.c
===================================================================
--- gcc/integrate.c	(revision 116166)
+++ gcc/integrate.c	(working copy)
@@ -240,16 +240,16 @@
      ivs = ggc_alloc_initial_value_struct();
      ivs->num_entries = 0;
      ivs->max_entries = 5;
-      ivs->entries = ggc_alloc (5 * sizeof (initial_value_pair));
+      ivs->entries = ggc_alloc_vec_initial_value_pair (5);
      cfun->hard_reg_initial_vals = ivs;
    }

  if (ivs->num_entries >= ivs->max_entries)
    {
      ivs->max_entries += 5;
-      ivs->entries = ggc_realloc (ivs->entries,
-				  ivs->max_entries
-				  * sizeof (initial_value_pair));
+      ivs->entries = ggc_realloc_atomic (ivs->entries,
+					 ivs->max_entries
+					 * sizeof (initial_value_pair));
    }

  ivs->entries[ivs->num_entries].hard_reg = gen_rtx_REG (mode, regno);
Index: gcc/ggc-none.c
===================================================================
--- gcc/ggc-none.c	(revision 116135)
+++ gcc/ggc-none.c	(working copy)
@@ -41,19 +41,19 @@
}

void *
-ggc_alloc_stat (size_t size MEM_STAT_DECL)
+ggc_internal_alloc_stat (size_t size MEM_STAT_DECL)
{
  return xmalloc (size);
}

void *
-ggc_alloc_cleared_stat (size_t size MEM_STAT_DECL)
+ggc_internal_alloc_cleared_stat (size_t size MEM_STAT_DECL)
{
  return xcalloc (size, 1);
}

void *
-ggc_realloc_stat (void *x, size_t size MEM_STAT_DECL)
+ggc_realloc_atomic_stat (void *x, size_t size MEM_STAT_DECL)
{
  return xrealloc (x, size);
}
Index: gcc/c-common.h
===================================================================
--- gcc/c-common.h	(revision 116135)
+++ gcc/c-common.h	(working copy)
@@ -212,7 +212,7 @@

/* In a RECORD_TYPE, a sorted array of the fields of the type, not a
   tree for size reasons.  */
-struct sorted_fields_type GTY(())
+struct sorted_fields_type GTY((size_not_fixed ("")))
{
  int len;
  tree GTY((length ("%h.len"))) elts[1];
Index: gcc/Makefile.in
===================================================================
--- gcc/Makefile.in	(revision 116166)
+++ gcc/Makefile.in	(working copy)
@@ -2843,9 +2843,9 @@
  $(srcdir)/cselib.h $(srcdir)/basic-block.h  $(srcdir)/cgraph.h \
  $(srcdir)/c-common.h $(srcdir)/c-tree.h $(srcdir)/reload.h \
  $(srcdir)/alias.c $(srcdir)/bitmap.c $(srcdir)/cselib.c $(srcdir)/cgraph.c \
-  $(srcdir)/ipa-prop.c $(srcdir)/ipa-cp.c\
+  $(srcdir)/ipa-prop.c $(srcdir)/ipa-cp.c $(srcdir)/c-typeck.c \
  $(srcdir)/dbxout.c $(srcdir)/dwarf2out.c $(srcdir)/dwarf2asm.c \
-  $(srcdir)/dojump.c $(srcdir)/tree-profile.c \
+  $(srcdir)/dojump.c $(srcdir)/tree-profile.c $(srcdir)/c-format.c \
  $(srcdir)/emit-rtl.c $(srcdir)/except.c $(srcdir)/explow.c $(srcdir)/expr.c \
  $(srcdir)/function.c $(srcdir)/except.h \
  $(srcdir)/gcse.c $(srcdir)/integrate.c $(srcdir)/lists.c $(srcdir)/optabs.c \
Index: gcc/tree-cfg.c
===================================================================
--- gcc/tree-cfg.c	(revision 116135)
+++ gcc/tree-cfg.c	(working copy)
@@ -380,9 +380,7 @@

gcc_assert (!e);

-  /* Create and initialize a new basic block.  Since alloc_block uses
-     ggc_alloc_cleared to allocate a basic block, we do not have to
-     clear the newly allocated basic block here.  */
+  /* Create and initialize a new cleared basic block.  */
  bb = alloc_block ();

  bb->index = last_basic_block;
Index: gcc/c-parser.c
===================================================================
--- gcc/c-parser.c	(revision 116135)
+++ gcc/c-parser.c	(working copy)
@@ -235,7 +235,7 @@
  if (!c_dialect_objc ())
     mask |= D_OBJC;

-  ridpointers = GGC_CNEWVEC (tree, (int) RID_MAX);
+  ridpointers = GGC_CNEWVEC_ATOMIC (tree, (int) RID_MAX);
  for (i = 0; i < N_reswords; i++)
    {
      /* If a keyword is disabled, do not enter it into the table
@@ -7830,7 +7830,7 @@
  if (c_parser_peek_token (&tparser)->pragma_kind == PRAGMA_GCC_PCH_PREPROCESS)
    c_parser_pragma_pch_preprocess (&tparser);

-  the_parser = GGC_NEW (c_parser);
+  the_parser = ggc_alloc_c_parser();
  *the_parser = tparser;

  c_parser_translation_unit (the_parser);
Index: gcc/config/alpha/alpha.c
===================================================================
--- gcc/config/alpha/alpha.c	(revision 116135)
+++ gcc/config/alpha/alpha.c	(working copy)
@@ -4835,8 +4835,7 @@
static struct machine_function *
alpha_init_machine_status (void)
{
-  return ((struct machine_function *)
-		ggc_alloc_cleared (sizeof (struct machine_function)));
+  return ggc_alloc_cleared_machine_function ();
}

/* Functions to save and restore alpha_return_addr_rtx.  */
@@ -9492,7 +9491,7 @@
        alpha_funcs_tree = splay_tree_new_ggc ((splay_tree_compare_fn)
					       splay_tree_compare_pointers);

-      cfaf = (struct alpha_funcs *) ggc_alloc (sizeof (struct alpha_funcs));
+      cfaf = ggc_alloc_alpha_funcs ();

      cfaf->links = 0;
      cfaf->num = ++alpha_funcs_num;
@@ -9528,7 +9527,7 @@
  else
    alpha_links_tree = splay_tree_new_ggc ((splay_tree_compare_fn) strcmp);

-  al = (struct alpha_links *) ggc_alloc (sizeof (struct alpha_links));
+  al = ggc_alloc_alpha_links ();
  name = ggc_strdup (name);

  /* Assume external if no definition.  */
@@ -9595,7 +9594,7 @@

name_len = strlen (name);

-      al = (struct alpha_links *) ggc_alloc (sizeof (struct alpha_links));
+      al = ggc_alloc_alpha_links ();
      al->num = cfaf->num;

      node = splay_tree_lookup (alpha_links_tree, (splay_tree_key) name);
Index: gcc/config/frv/frv.c
===================================================================
--- gcc/config/frv/frv.c	(revision 116135)
+++ gcc/config/frv/frv.c	(working copy)
@@ -6947,7 +6947,7 @@
static struct machine_function *
frv_init_machine_status (void)
{
-  return ggc_alloc_cleared (sizeof (struct machine_function));
+  return ggc_alloc_cleared_machine_function ();
}

/* Implement TARGET_SCHED_ISSUE_RATE.  */
Index: gcc/config/s390/s390.c
===================================================================
--- gcc/config/s390/s390.c	(revision 116135)
+++ gcc/config/s390/s390.c	(working copy)
@@ -1273,7 +1273,7 @@
static struct machine_function *
s390_init_machine_status (void)
{
-  return ggc_alloc_cleared (sizeof (struct machine_function));
+  return ggc_alloc_cleared_machine_function ();
}

/* Change optimizations to be performed, depending on the
Index: gcc/config/m32c/m32c.c
===================================================================
--- gcc/config/m32c/m32c.c	(revision 116135)
+++ gcc/config/m32c/m32c.c	(working copy)
@@ -422,8 +422,7 @@
m32c_init_machine_status (void)
{
  struct machine_function *machine;
-  machine =
-    (machine_function *) ggc_alloc_cleared (sizeof (machine_function));
+  machine = ggc_alloc_cleared_machine_function ();

  return machine;
}
Index: gcc/config/sparc/sparc.c
===================================================================
--- gcc/config/sparc/sparc.c	(revision 116135)
+++ gcc/config/sparc/sparc.c	(working copy)
@@ -8743,7 +8743,7 @@
static struct machine_function *
sparc_init_machine_status (void)
{
-  return ggc_alloc_cleared (sizeof (struct machine_function));
+  return ggc_alloc_cleared_machine_function ();
}

/* Locate some local-dynamic symbol still in use by this function
Index: gcc/config/i386/winnt.c
===================================================================
--- gcc/config/i386/winnt.c	(revision 116135)
+++ gcc/config/i386/winnt.c	(working copy)
@@ -638,7 +638,7 @@
{
  struct extern_list *p;

-  p = (struct extern_list *) ggc_alloc (sizeof *p);
+  p = ggc_alloc_extern_list();
  p->next = extern_head;
  p->decl = decl;
  p->name = name;
@@ -667,7 +667,7 @@
{
  struct export_list *p;

-  p = (struct export_list *) ggc_alloc (sizeof *p);
+  p = ggc_alloc_export_list ();
  p->next = export_head;
  p->name = name;
  p->is_data = is_data;
Index: gcc/config/i386/i386.c
===================================================================
--- gcc/config/i386/i386.c	(revision 116135)
+++ gcc/config/i386/i386.c	(working copy)
@@ -13285,7 +13285,7 @@
{
  struct machine_function *f;

-  f = ggc_alloc_cleared (sizeof (struct machine_function));
+  f = ggc_alloc_cleared_machine_function ();
  f->use_fast_prologue_epilogue_nregs = -1;
  f->tls_descriptor_call_expanded_p = 0;

@@ -13309,8 +13309,7 @@
    if (s->mode == mode && s->n == n)
      return s->rtl;

-  s = (struct stack_local_entry *)
-    ggc_alloc (sizeof (struct stack_local_entry));
+  s = ggc_alloc_stack_local_entry();
  s->n = n;
  s->mode = mode;
  s->rtl = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
Index: gcc/config/xtensa/xtensa.c
===================================================================
--- gcc/config/xtensa/xtensa.c	(revision 116135)
+++ gcc/config/xtensa/xtensa.c	(working copy)
@@ -1290,7 +1290,7 @@
static struct machine_function *
xtensa_init_machine_status (void)
{
-  return ggc_alloc_cleared (sizeof (struct machine_function));
+  return ggc_alloc_cleared_machine_function ();
}


Index: gcc/config/cris/cris.c =================================================================== --- gcc/config/cris/cris.c (revision 116135) +++ gcc/config/cris/cris.c (working copy) @@ -2286,7 +2286,7 @@ static struct machine_function * cris_init_machine_status (void) { - return ggc_alloc_cleared (sizeof (struct machine_function)); + return ggc_alloc_cleared_machine_function (); }

/* Split a 2 word move (DI or presumably DF) into component parts.
Index: gcc/config/iq2000/iq2000.c
===================================================================
--- gcc/config/iq2000/iq2000.c	(revision 116135)
+++ gcc/config/iq2000/iq2000.c	(working copy)
@@ -1387,7 +1387,7 @@
{
  struct machine_function *f;

-  f = ggc_alloc_cleared (sizeof (struct machine_function));
+  f = ggc_alloc_cleared_machine_function ();

  return f;
}
Index: gcc/config/mt/mt.c
===================================================================
--- gcc/config/mt/mt.c	(revision 116135)
+++ gcc/config/mt/mt.c	(working copy)
@@ -782,7 +782,7 @@
{
  struct machine_function *f;

-  f = ggc_alloc_cleared (sizeof (struct machine_function));
+  f = ggc_alloc_cleared_machine_function ();

  return f;
}
Index: gcc/config/ia64/ia64.c
===================================================================
--- gcc/config/ia64/ia64.c	(revision 116135)
+++ gcc/config/ia64/ia64.c	(working copy)
@@ -5179,7 +5179,7 @@
static struct machine_function *
ia64_init_machine_status (void)
{
-  return ggc_alloc_cleared (sizeof (struct machine_function));
+  return ggc_alloc_cleared_machine_function ();
}

static enum attr_itanium_class ia64_safe_itanium_class (rtx);
@@ -9164,7 +9164,7 @@
static void
ia64_hpux_add_extern_decl (tree decl)
{
-  struct extern_func_list *p = ggc_alloc (sizeof (struct extern_func_list));
+  struct extern_func_list *p = ggc_alloc_extern_func_list();

  p->decl = decl;
  p->next = extern_func_head;
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	(revision 116135)
+++ gcc/config/rs6000/rs6000.c	(working copy)
@@ -10061,7 +10061,7 @@
static struct machine_function *
rs6000_init_machine_status (void)
{
-  return ggc_alloc_cleared (sizeof (machine_function));
+  return ggc_alloc_cleared_machine_function ();
}

/* These macros test for integers and extract the low-order bits.  */
@@ -15841,7 +15841,7 @@
	toc_hash_table = htab_create_ggc (1021, toc_hash_function,
					  toc_hash_eq, NULL);

-      h = ggc_alloc (sizeof (*h));
+      h = ggc_alloc_toc_hash_struct ();
      h->key = x;
      h->key_mode = mode;
      h->labelno = labelno;
Index: gcc/config/darwin.c
===================================================================
--- gcc/config/darwin.c	(revision 116135)
+++ gcc/config/darwin.c	(working copy)
@@ -443,7 +443,7 @@
    }
  else
    {
-      p = (machopic_indirection *) ggc_alloc (sizeof (machopic_indirection));
+      p = ggc_alloc_machopic_indirection();
      p->symbol = sym_ref;
      p->ptr_name = xstrdup (buffer);
      p->stub_p = stub_p;
Index: gcc/config/arm/arm.c
===================================================================
--- gcc/config/arm/arm.c	(revision 116135)
+++ gcc/config/arm/arm.c	(working copy)
@@ -13538,7 +13538,7 @@
arm_init_machine_status (void)
{
  struct machine_function *machine;
-  machine = (machine_function *) ggc_alloc_cleared (sizeof (machine_function));
+  machine = ggc_alloc_cleared_machine_function ();

#if ARM_FT_UNKNOWN != 0
  machine->func_type = ARM_FT_UNKNOWN;
Index: gcc/config/pa/pa.c
===================================================================
--- gcc/config/pa/pa.c	(revision 116135)
+++ gcc/config/pa/pa.c	(working copy)
@@ -189,7 +189,7 @@

/* Variables to handle plabels that we discover are necessary at assembly
   output time.  They are output after the current function.  */
-struct deferred_plabel GTY(())
+struct deferred_plabel GTY((size_not_fixed("")))
{
  rtx internal_label;
  rtx symbol;
@@ -521,7 +521,7 @@
static struct machine_function *
pa_init_machine_status (void)
{
-  return ggc_alloc_cleared (sizeof (machine_function));
+  return ggc_alloc_cleared_machine_function ();
}

/* If FROM is a probable pointer register, mark TO as a probable
@@ -5295,12 +5295,13 @@

      if (deferred_plabels == 0)
	deferred_plabels = (struct deferred_plabel *)
-	  ggc_alloc (sizeof (struct deferred_plabel));
+	  ggc_alloc_deferred_plabel ();
      else
+	/* TODO: is wrong and *will* cause error very soon. */
	deferred_plabels = (struct deferred_plabel *)
-	  ggc_realloc (deferred_plabels,
-		       ((n_deferred_plabels + 1)
-			* sizeof (struct deferred_plabel)));
+	  ggc_realloc_atomic (deferred_plabels,
+			      ((n_deferred_plabels + 1)
+			       * sizeof (struct deferred_plabel)));

      i = n_deferred_plabels++;
      deferred_plabels[i].internal_label = gen_label_rtx ();
Index: gcc/config/mips/mips.c
===================================================================
--- gcc/config/mips/mips.c	(revision 116135)
+++ gcc/config/mips/mips.c	(working copy)
@@ -5196,7 +5196,7 @@
mips_init_machine_status (void)
{
  return ((struct machine_function *)
-	  ggc_alloc_cleared (sizeof (struct machine_function)));
+	  ggc_alloc_cleared_machine_function ());
}

/* On the mips16, we want to allocate $24 (T_REG) before other
@@ -5678,7 +5678,7 @@

  if (!TARGET_EXPLICIT_RELOCS && mips_in_small_data_p (decl))
    {
-      p = (struct extern_list *) ggc_alloc (sizeof (struct extern_list));
+      p = ggc_alloc_extern_list ();
      p->next = extern_head;
      p->name = name;
      p->size = int_size_in_bytes (TREE_TYPE (decl));
@@ -5687,7 +5687,7 @@

  if (TARGET_IRIX && mips_abi == ABI_32 && TREE_CODE (decl) == FUNCTION_DECL)
    {
-      p = (struct extern_list *) ggc_alloc (sizeof (struct extern_list));
+      p = ggc_alloc_extern_list ();
      p->next = extern_head;
      p->name = name;
      p->size = -1;
@@ -5705,7 +5705,7 @@

  if (mips_abi == ABI_32)
    {
-      p = (struct extern_list *) ggc_alloc (sizeof (struct extern_list));
+      p = ggc_alloc_extern_list ();
      p->next = extern_head;
      p->name = XSTR (fun, 0);
      p->size = -1;
Index: gcc/config/mmix/mmix.c
===================================================================
--- gcc/config/mmix/mmix.c	(revision 116135)
+++ gcc/config/mmix/mmix.c	(working copy)
@@ -242,7 +242,7 @@
static struct machine_function *
mmix_init_machine_status (void)
{
-  return ggc_alloc_cleared (sizeof (struct machine_function));
+  return ggc_alloc_cleared_machine_function ();
}

/* DATA_ALIGNMENT.
Index: gcc/config/bfin/bfin.c
===================================================================
--- gcc/config/bfin/bfin.c	(revision 116135)
+++ gcc/config/bfin/bfin.c	(working copy)
@@ -1970,7 +1970,7 @@
{
  struct machine_function *f;

-  f = ggc_alloc_cleared (sizeof (struct machine_function));
+  f = ggc_alloc_cleared_machine_function ();

  return f;
}
Index: gcc/varray.c
===================================================================
--- gcc/varray.c	(revision 116135)
+++ gcc/varray.c	(working copy)
@@ -127,7 +127,7 @@
  desc->allocated += data_size + VARRAY_HDR_SIZE;
#endif
  if (element[element_kind].uses_ggc)
-    ptr = ggc_alloc_cleared (VARRAY_HDR_SIZE + data_size);
+    ptr = ggc_alloc_cleared_atomic (VARRAY_HDR_SIZE + data_size);
  else
    ptr = xcalloc (VARRAY_HDR_SIZE + data_size, 1);

@@ -160,7 +160,7 @@


if (element[va->type].uses_ggc) - va = ggc_realloc (va, VARRAY_HDR_SIZE + data_size); + va = ggc_realloc_atomic (va, VARRAY_HDR_SIZE + data_size); else va = xrealloc (va, VARRAY_HDR_SIZE + data_size); va->num_elements = n; Index: gcc/cfgrtl.c =================================================================== --- gcc/cfgrtl.c (revision 116135) +++ gcc/cfgrtl.c (working copy) @@ -2895,7 +2895,7 @@ init_rtl_bb_info (basic_block bb) { gcc_assert (!bb->il.rtl); - bb->il.rtl = ggc_alloc_cleared (sizeof (struct rtl_bb_info)); + bb->il.rtl = ggc_alloc_cleared_rtl_bb_info (); }


Index: gcc/tree-ssa-operands.c =================================================================== --- gcc/tree-ssa-operands.c (revision 116135) +++ gcc/tree-ssa-operands.c (working copy) @@ -314,7 +314,7 @@ if (operand_memory_index + size >= SSA_OPERAND_MEMORY_SIZE) { struct ssa_operand_memory_d *ptr; - ptr = GGC_NEW (struct ssa_operand_memory_d); + ptr = ggc_alloc_ssa_operand_memory_d (); ptr->next = operand_memory; operand_memory = ptr; operand_memory_index = 0; Index: include/splay-tree.h =================================================================== --- include/splay-tree.h (revision 116135) +++ include/splay-tree.h (working copy) @@ -1,9 +1,9 @@ -/* A splay-tree datatype. +/* A splay-tree datatype. Copyright 1998, 1999, 2000, 2002 Free Software Foundation, Inc. Contributed by Mark Mitchell (mark@markmitchell.com).

This file is part of GCC.
-
+
GCC is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
@@ -22,7 +22,7 @@
/* For an easily readable description of splay-trees, see:

     Lewis, Harry R. and Denenberg, Larry.  Data Structures and Their
-     Algorithms.  Harper-Collins, Inc.  1991.
+     Algorithms.  Harper-Collins, Inc.  1991.

   The major feature of splay trees is that all basic tree operations
   are amortized O(log n) time for a tree with n nodes.  */
@@ -107,7 +107,8 @@
  splay_tree_delete_value_fn delete_value;

  /* Allocate/free functions, and a data pointer to pass to them.  */
-  splay_tree_allocate_fn allocate;
+  splay_tree_allocate_fn allocate_tree_node;
+
  splay_tree_deallocate_fn deallocate;
  void * GTY((skip)) allocate_data;

@@ -121,6 +122,7 @@
                                                 splay_tree_delete_key_fn,
					        splay_tree_delete_value_fn,
                                                 splay_tree_allocate_fn,
+						 splay_tree_allocate_fn,
                                                 splay_tree_deallocate_fn,
                                                 void *);
extern void splay_tree_delete           (splay_tree);
Index: libiberty/splay-tree.c
===================================================================
--- libiberty/splay-tree.c	(revision 116135)
+++ libiberty/splay-tree.c	(working copy)
@@ -3,7 +3,7 @@
   Contributed by Mark Mitchell (mark@markmitchell.com).

This file is part of GNU CC.
-
+
GNU CC is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
@@ -249,7 +249,8 @@
{
  return (splay_tree_new_with_allocator
          (compare_fn, delete_key_fn, delete_value_fn,
-           splay_tree_xmalloc_allocate, splay_tree_xmalloc_deallocate, 0));
+	   splay_tree_xmalloc_allocate, splay_tree_xmalloc_allocate,
+	   splay_tree_xmalloc_deallocate, 0));
}


@@ -261,17 +262,18 @@ splay_tree_new_with_allocator (splay_tree_compare_fn compare_fn, splay_tree_delete_key_fn delete_key_fn, splay_tree_delete_value_fn delete_value_fn, - splay_tree_allocate_fn allocate_fn, + splay_tree_allocate_fn allocate_tree_fn, + splay_tree_allocate_fn allocate_tree_node_fn, splay_tree_deallocate_fn deallocate_fn, void *allocate_data) { - splay_tree sp = (splay_tree) (*allocate_fn) (sizeof (struct splay_tree_s), - allocate_data); + splay_tree sp = (splay_tree) + (*allocate_tree_fn) (sizeof (struct splay_tree_s), allocate_data); sp->root = 0; sp->comp = compare_fn; sp->delete_key = delete_key_fn; sp->delete_value = delete_value_fn; - sp->allocate = allocate_fn; + sp->allocate_tree_node = allocate_tree_node_fn; sp->deallocate = deallocate_fn; sp->allocate_data = allocate_data;

@@ -280,7 +282,7 @@

/* Deallocate SP. */

-void
+void
splay_tree_delete (splay_tree sp)
{
  splay_tree_delete_helper (sp, sp->root);
@@ -308,18 +310,18 @@
      if (sp->delete_value)
	(*sp->delete_value)(sp->root->value);
      sp->root->value = value;
-    }
-  else
+    }
+  else
    {
      /* Create a new node, and insert it at the root.  */
      splay_tree_node node;
-
+
      node = ((splay_tree_node)
-              (*sp->allocate) (sizeof (struct splay_tree_node_s),
+              (*sp->allocate_tree_node) (sizeof (struct splay_tree_node_s),
                               sp->allocate_data));
      node->key = key;
      node->value = value;
-
+
      if (!sp->root)
	node->left = node->right = 0;
      else if (comparison < 0)
@@ -521,6 +523,6 @@
    return -1;
  else if ((char*) k1 > (char*) k2)
    return 1;
-  else
+  else
    return 0;
}


-- Laurynas


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