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]

[PCH] GCable hash tables



This patch adds gcability to the 'htab_t' hash tables.  (My next patch
will nuke the 'struct hashtable' hash tables.)

I deleted htab_try_create because I couldn't find any reference to it
in the two source trees.  The functionality is still available,
as 'htab_create_alloc (..., calloc, free)', and I'd have a left a
#define just-in-case but that causes the #pragma poison stuff to stop
the build.

Bootstrapped & tested on x86-linux with gcac checking.

-- 
Geoff Keating <geoffk@redhat.com>

===File ~/patches/pchbranch-htabtggc.patch==================
Index: libiberty/ChangeLog
2002-05-10  Geoffrey Keating  <geoffk@redhat.com>

	* hashtab.c (htab_create): Delete.
	(htab_try_create): Delete.
	(htab_create_alloc): New.
	(htab_delete): Support user-specified memory allocation.
	(htab_expand): Likewise.

Index: gcc/ChangeLog
2002-05-10  Geoffrey Keating  <geoffk@redhat.com>

	* varasm.c (mark_const_str_htab_1): Delete.
	(mark_const_str_htab): Delete.
	(const_str_htab_del): Delete.
	(const_str_htab): Use gengtype to mark.
	(init_varasm_once): Use gengtype to mark hashtables.  Use GC to
	allocate them.
	* tree.c (mark_tree_hashtable_entry): Delete.
	(mark_tree_hashtable): Delete.
	* tree.h (mark_tree_hashtable): Delete prototype.
	* ggc.h (ggc_test_and_set_mark): Treat (void *)1 like NULL.
	(ggc_mark): Likewise.
	(ggc_calloc): New.
	(htab_create_ggc): New.
	* ggc-common.c (ggc_calloc): New.
	* gengtype.h (enum typekind): Add TYPE_PARAM_STRUCT.
	(struct type): Add param_struct structure.
	* gengtype.c (param_structs): New.
	(adjust_field_type): Handle param_is option.
	(set_gc_used_type): Handle TYPE_PARAM_STRUCT.
	(get_output_file_with_visibility): Include hashtab.h in gtype-desc.c.
	(write_gc_structure_fields): Add new PARAM parameter.  Update
	callers.  Handle use_param option.  Handle TYPE_PARAM_STRUCT.
	(write_gc_marker_routine_for_structure): Add new PARAM parameter.
	Use it to generate function name.  Update callers.
	(write_gc_types): Add new PARAM_STRUCTS parameter.  Update callers.
	Process them.
	(write_gc_roots): Handle TYPE_PARAM_STRUCT.  Allow param_is
	option.
	(main): Define PTR as pointer-to-scalar.  Don't specially
	mark deferred_string or ehl_map_entry.
	* gengtype-yacc.y (PARAM_IS): Add new token.
	(externstatic): Use adjust_field_type.
	(type_option): Add PARAM_IS.
	* gengtype-lex.l: Add rule for typedef of function pointers.
	Add rule for PARAM_IS.
	(IWORD): Add size_t.
	* except.c (exception_handler_label_map): Use gengtype to mark.
	(type_to_runtime_map): Likewise.
	(mark_ehl_map_entry): Delete.
	(mark_ehl_map): Delete.
	(init_eh): Use gengtype for roots; use GC to allocate hash tables.
	(t2r_mark_1): Delete.
	(t2r_mark): Delete.
	* Makefile.in (gtype-desc.o): Correct dependencies.
	(GTFILES): Add hashtab.h.
	(genautomata.o): Actually uses hashtab.h.

Index: gcc/cp/ChangeLog
2002-05-10  Geoffrey Keating  <geoffk@redhat.com>

	* Make-lang.in (gt-cp-tree.h): New rule.
	(cp/tree.o): Depend on gt-cp-tree.h.
	* config-lang.in (gtfiles): Add cp/tree.c.
	* tree.c: Include gt-cp-tree.h.
	(list_hash_table): Use gengtype to mark.
	(init_tree): Use gengtype to mark trees.

Index: include/ChangeLog
2002-05-10  Geoffrey Keating  <geoffk@redhat.com>

	* hashtab.h (GTY): Define if undefined.
	(htab_alloc): New typedef.
	(htab_free): New typedef.
	(struct htab): Support gengtype; allow user-specified memory
	allocation.
	(htab_create_alloc): New.
	(htab_create): Replace with #define.
	(htab_try_create): Delete.

Index: libiberty/hashtab.c
===================================================================
RCS file: /cvs/gcc/gcc/libiberty/hashtab.c,v
retrieving revision 1.25.6.1
diff -p -u -p -r1.25.6.1 hashtab.c
--- libiberty/hashtab.c	6 May 2002 18:54:48 -0000	1.25.6.1
+++ libiberty/hashtab.c	10 May 2002 08:50:25 -0000
@@ -158,59 +158,36 @@ eq_pointer (p1, p2)
 /* This function creates table with length slightly longer than given
    source length.  Created hash table is initiated as empty (all the
    hash table entries are EMPTY_ENTRY).  The function returns the
-   created hash table.  Memory allocation must not fail.  */
+   created hash table, or NULL if memory allocation fails.  */
 
 htab_t
-htab_create (size, hash_f, eq_f, del_f)
+htab_create_alloc (size, hash_f, eq_f, del_f, alloc_f, free_f)
      size_t size;
      htab_hash hash_f;
      htab_eq eq_f;
      htab_del del_f;
+     htab_alloc alloc_f;
+     htab_free free_f;
 {
   htab_t result;
 
   size = higher_prime_number (size);
-  result = (htab_t) xcalloc (1, sizeof (struct htab));
-  result->entries = (PTR *) xcalloc (size, sizeof (PTR));
-  result->size = size;
-  result->hash_f = hash_f;
-  result->eq_f = eq_f;
-  result->del_f = del_f;
-  result->return_allocation_failure = 0;
-  return result;
-}
-
-/* This function creates table with length slightly longer than given
-   source length.  The created hash table is initiated as empty (all the
-   hash table entries are EMPTY_ENTRY).  The function returns the created
-   hash table.  Memory allocation may fail; it may return NULL.  */
-
-htab_t
-htab_try_create (size, hash_f, eq_f, del_f)
-     size_t size;
-     htab_hash hash_f;
-     htab_eq eq_f;
-     htab_del del_f;
-{
-  htab_t result;
-
-  size = higher_prime_number (size);
-  result = (htab_t) calloc (1, sizeof (struct htab));
+  result = (htab_t) (*alloc_f) (1, sizeof (struct htab));
   if (result == NULL)
     return NULL;
-
-  result->entries = (PTR *) calloc (size, sizeof (PTR));
+  result->entries = (PTR *) (*alloc_f) (size, sizeof (PTR));
   if (result->entries == NULL)
     {
-      free (result);
+      if (free_f != NULL)
+	(*free_f) (result);
       return NULL;
     }
-
   result->size = size;
   result->hash_f = hash_f;
   result->eq_f = eq_f;
   result->del_f = del_f;
-  result->return_allocation_failure = 1;
+  result->alloc_f = alloc_f;
+  result->free_f = free_f;
   return result;
 }
 
@@ -229,8 +206,11 @@ htab_delete (htab)
 	  && htab->entries[i] != DELETED_ENTRY)
 	(*htab->del_f) (htab->entries[i]);
 
-  free (htab->entries);
-  free (htab);
+  if (htab->free_f != NULL)
+    {
+      (*htab->free_f) (htab->entries);
+      (*htab->free_f) (htab);
+    }
 }
 
 /* This function clears all entries in the given hash table.  */
@@ -302,21 +282,17 @@ htab_expand (htab)
   PTR *oentries;
   PTR *olimit;
   PTR *p;
+  PTR *nentries;
 
   oentries = htab->entries;
   olimit = oentries + htab->size;
 
   htab->size = higher_prime_number (htab->size * 2);
 
-  if (htab->return_allocation_failure)
-    {
-      PTR *nentries = (PTR *) calloc (htab->size, sizeof (PTR *));
-      if (nentries == NULL)
-	return 0;
-      htab->entries = nentries;
-    }
-  else
-    htab->entries = (PTR *) xcalloc (htab->size, sizeof (PTR *));
+  nentries = (PTR *) (*htab->alloc_f) (htab->size, sizeof (PTR *));
+  if (nentries == NULL)
+    return 0;
+  htab->entries = nentries;
 
   htab->n_elements -= htab->n_deleted;
   htab->n_deleted = 0;
@@ -337,7 +313,8 @@ htab_expand (htab)
     }
   while (p < olimit);
 
-  free (oentries);
+  if (htab->free_f != NULL)
+    (*htab->free_f) (oentries);
   return 1;
 }
 
Index: gcc/Makefile.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Makefile.in,v
retrieving revision 1.822.2.13
diff -p -u -p -r1.822.2.13 Makefile.in
--- gcc/Makefile.in	8 May 2002 22:38:11 -0000	1.822.2.13
+++ gcc/Makefile.in	10 May 2002 08:50:27 -0000
@@ -1329,9 +1329,9 @@ dumpvers: dumpvers.c
 
 version.o: version.c version.h
 
-gtype-desc.o: gtype-desc.c $(CONFIG_H) $(SYSTEM_H) varray.h $(TREE_H) \
-	$(RTL_H) function.h insn-config.h expr.h $(OPTABS_H) $(GGC_H) \
-	libfuncs.h
+gtype-desc.o: gtype-desc.c $(CONFIG_H) $(SYSTEM_H) varray.h $(HASHTAB_H) \
+	$(TREE_H) $(RTL_H) function.h insn-config.h expr.h $(OPTABS_H) \
+	libfuncs.h debug.h $(GGC_H)
 
 ggc-common.o: ggc-common.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) \
 	flags.h $(GGC_H) varray.h hash.h $(HASHTAB_H) $(TM_P_H) langhooks.h
@@ -1822,6 +1822,7 @@ s-preds: genpreds$(build_exeext) $(srcdi
 	$(STAMP) s-preds
 
 GTFILES = $(GCONFIG_H) \
+  $(HASHTAB_H) \
   $(srcdir)/bitmap.h $(srcdir)/function.h  $(srcdir)/rtl.h $(srcdir)/optabs.h \
   $(srcdir)/tree.h $(srcdir)/libfuncs.h $(srcdir)/hashtable.h \
   $(srcdir)/c-common.h $(srcdir)/c-tree.h \
@@ -1952,7 +1953,7 @@ genattrtab.o : genattrtab.c $(RTL_H) $(O
 	$(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/genattrtab.c $(OUTPUT_OPTION)
 
 genautomata.o : genautomata.c $(RTL_H) $(OBSTACK_H) $(HCONFIG_H) \
-  $(SYSTEM_H) errors.h varray.h hash.h genattrtab.h
+  $(SYSTEM_H) errors.h varray.h hash.h genattrtab.h $(HASHTAB_H)
 	$(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/genautomata.c $(OUTPUT_OPTION)
 
 genoutput$(build_exeext) : genoutput.o $(HOST_RTL) $(HOST_PRINT) $(HOST_ERRORS) $(HOST_LIBDEPS)
Index: gcc/except.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/except.c,v
retrieving revision 1.210.2.7
diff -p -u -p -r1.210.2.7 except.c
--- gcc/except.c	6 May 2002 18:43:57 -0000	1.210.2.7
+++ gcc/except.c	10 May 2002 08:50:28 -0000
@@ -106,11 +106,13 @@ struct ehl_map_entry GTY(())
   struct eh_region *region;
 };
 
-static htab_t exception_handler_label_map;
+static GTY ((param_is (struct ehl_map_entry))) 
+  htab_t exception_handler_label_map;
 
 static int call_site_base;
 static unsigned int sjlj_funcdef_number;
-static htab_t type_to_runtime_map;
+static GTY ((param_is (union tree_node)))
+  htab_t type_to_runtime_map;
 
 /* Describe the SjLj_Function_Context structure.  */
 static GTY(()) tree sjlj_fc_type_node;
@@ -258,8 +260,6 @@ struct eh_status GTY(())
 static int t2r_eq				PARAMS ((const PTR,
 							 const PTR));
 static hashval_t t2r_hash			PARAMS ((const PTR));
-static int t2r_mark_1				PARAMS ((PTR *, PTR));
-static void t2r_mark				PARAMS ((PTR));
 static void add_type_for_runtime		PARAMS ((tree));
 static tree lookup_type_for_runtime		PARAMS ((tree));
 
@@ -380,37 +380,13 @@ doing_eh (do_warn)
 }
 
 
-static int mark_ehl_map_entry			PARAMS ((PTR *, PTR));
-static void mark_ehl_map			PARAMS ((void *));
-
-static int
-mark_ehl_map_entry (pentry, data)
-     PTR *pentry;
-     PTR data ATTRIBUTE_UNUSED;
-{
-  gt_ggc_m_ehl_map_entry (*pentry);
-  return 1;
-}
-
-static void
-mark_ehl_map (pp)
-    void *pp;
-{
-  htab_t map = *(htab_t *) pp;
-  if (map)
-    htab_traverse (map, mark_ehl_map_entry, NULL);
-}
-
 void
 init_eh ()
 {
-  ggc_add_root (&exception_handler_label_map, 1, 1, mark_ehl_map);
-
   if (! flag_exceptions)
     return;
 
-  type_to_runtime_map = htab_create (31, t2r_hash, t2r_eq, NULL);
-  ggc_add_root (&type_to_runtime_map, 1, sizeof (htab_t), t2r_mark);
+  type_to_runtime_map = htab_create_ggc (31, t2r_hash, t2r_eq, NULL);
 
   /* Create the SjLj_Function_Context structure.  This should match
      the definition in unwind-sjlj.c.  */
@@ -1252,8 +1228,8 @@ find_exception_handler_labels ()
       /* ??? The expansion factor here (3/2) must be greater than the htab
 	 occupancy factor (4/3) to avoid unnecessary resizing.  */
       exception_handler_label_map
-        = htab_create (cfun->eh->last_region_number * 3 / 2,
-		       ehl_hash, ehl_eq, ehl_free);
+        = htab_create_ggc (cfun->eh->last_region_number * 3 / 2,
+			   ehl_hash, ehl_eq, NULL);
     }
 
   if (cfun->eh->region_tree == NULL)
@@ -1468,23 +1444,6 @@ t2r_hash (pentry)
 {
   tree entry = (tree) pentry;
   return TYPE_HASH (TREE_PURPOSE (entry));
-}
-
-static int
-t2r_mark_1 (slot, data)
-     PTR *slot;
-     PTR data ATTRIBUTE_UNUSED;
-{
-  tree contents = (tree) *slot;
-  ggc_mark_tree (contents);
-  return 1;
-}
-
-static void
-t2r_mark (addr)
-     PTR addr;
-{
-  htab_traverse (*(htab_t *)addr, t2r_mark_1, NULL);
 }
 
 static void
Index: gcc/gengtype-lex.l
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/gengtype-lex.l,v
retrieving revision 1.1.2.7
diff -p -u -p -r1.1.2.7 gengtype-lex.l
--- gcc/gengtype-lex.l	8 May 2002 22:38:16 -0000	1.1.2.7
+++ gcc/gengtype-lex.l	10 May 2002 08:50:28 -0000
@@ -49,7 +49,7 @@ update_lineno (l, len)
 
 ID	[[:alpha:]][[:alnum:]_]*
 WS	[[:space:]]+
-IWORD	short|long|(un)?signed|char|int|HOST_WIDE_INT|bool
+IWORD	short|long|(un)?signed|char|int|HOST_WIDE_INT|bool|size_t
 ITYPE	{IWORD}({WS}{IWORD})*
 
 %x in_struct in_struct_comment in_comment in_yacc_escape
@@ -131,6 +131,21 @@ ITYPE	{IWORD}({WS}{IWORD})*
   do_typedef (xmemdup (namestart, namelen, namelen+1), t, &lexer_line);
   update_lineno (yytext, yyleng);
 }
+[^[:alnum:]_]typedef{WS}{ID}{WS}?"("{WS}?"*"{WS}?{ID}{WS}?")"{WS}?PARAMS {
+  char *namestart;
+  size_t namelen;
+  struct type *t;
+
+  for (namestart = yytext + yyleng - 7; !IDchar (*namestart); namestart--)
+    ;
+  for (namelen = 1; IDchar (namestart[-namelen]); namelen++)
+    ;
+  namestart -= namelen - 1;
+
+  t = create_scalar_type ("function type", sizeof ("function type")-1);
+  do_typedef (xmemdup (namestart, namelen, namelen+1), t, &lexer_line);
+  update_lineno (yytext, yyleng);
+}
 
 [^[:alnum:]_](typedef{WS})?(struct|union){WS}{ID}{WS}/"GTY" {
   char *tagstart;
@@ -188,6 +203,7 @@ ITYPE	{IWORD}({WS}{IWORD})*
 "struct"/[^[:alnum:]_]		{ return STRUCT; }
 "enum"/[^[:alnum:]_]		{ return ENUM; }
 "ptr_alias"/[^[:alnum:]_]	{ return ALIAS; }
+"param_is"/[^[:alnum:]_]	{ return PARAM_IS; }
 [0-9]+				{ return NUM; }
 
 {IWORD}({WS}{IWORD})*/[^[:alnum:]_]		|
Index: gcc/gengtype-yacc.y
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/gengtype-yacc.y,v
retrieving revision 1.1.2.8
diff -p -u -p -r1.1.2.8 gengtype-yacc.y
--- gcc/gengtype-yacc.y	8 May 2002 22:38:17 -0000	1.1.2.8
+++ gcc/gengtype-yacc.y	10 May 2002 08:50:28 -0000
@@ -42,6 +42,7 @@ Software Foundation, 59 Temple Place - S
 %token STRUCT "struct"
 %token ENUM "enum"
 %token ALIAS "ptr_alias"
+%token PARAM_IS "param_is"
 %token VARRAY_TYPE "varray_type"
 %token NUM
 %token PERCENTPERCENT "%%"
@@ -82,7 +83,8 @@ typedef_struct: ENT_TYPEDEF_STRUCT optio
 
 externstatic: ENT_EXTERNSTATIC options lasttype ID semiequal
 	         {
-	           note_variable ($4, $3, $2, &lexer_line);
+	           note_variable ($4, adjust_field_type ($3, $2), $2, 
+				  &lexer_line);
 	         }
 	      | ENT_EXTERNSTATIC options lasttype ID ARRAY semiequal
 	         {
@@ -260,6 +262,8 @@ type_option : VARRAY_TYPE
 	        { $$ = "varray_type"; }
 	      | ALIAS
 	        { $$ = "ptr_alias"; }
+	      | PARAM_IS
+	        { $$ = "param_is"; }
 
 option:	type_option '(' type ')'
 	   {
Index: gcc/gengtype.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/gengtype.c,v
retrieving revision 1.1.2.15
diff -p -u -p -r1.1.2.15 gengtype.c
--- gcc/gengtype.c	8 May 2002 22:38:17 -0000	1.1.2.15
+++ gcc/gengtype.c	10 May 2002 08:50:28 -0000
@@ -46,6 +46,7 @@ struct type string_type = {
 
 static pair_p typedefs;
 static type_p structures;
+static type_p param_structs;
 static type_p varrays;
 static pair_p variables;
 
@@ -245,18 +246,38 @@ adjust_field_type (t, opt)
      type_p t;
      options_p opt;
 {
-  if (t->kind == TYPE_POINTER
+  int length_p = 0;
+  const int pointer_p = t->kind == TYPE_POINTER;
+  
+  for (; opt; opt = opt->next)
+    if (strcmp (opt->name, "length") == 0)
+      length_p = 1;
+    else if (strcmp (opt->name, "param_is") == 0)
+      {
+	type_p realt;
+
+	if (pointer_p)
+	  t = t->u.p;
+	
+	for (realt = param_structs; realt; realt = realt->next)
+	  if (realt->u.param_struct.stru == t
+	      && realt->u.param_struct.param == (type_p) opt->info)
+	    return pointer_p ? create_pointer (realt) : realt;
+	realt = xcalloc (1, sizeof (*realt));
+	realt->kind = TYPE_PARAM_STRUCT;
+	realt->next = param_structs;
+	param_structs = realt;
+	realt->u.param_struct.stru = t;
+	realt->u.param_struct.param = (type_p) opt->info;
+	return pointer_p ? create_pointer (realt) : realt;
+      }
+  
+  if (! length_p
+      && pointer_p
       && t->u.p->kind == TYPE_SCALAR
       && (strcmp (t->u.p->u.sc, "char") == 0
 	  || strcmp (t->u.p->u.sc, "unsigned char") == 0))
-    {
-      while (opt != NULL)
-	if (strcmp (opt->name, "length") == 0)
-	  return t;
-	else
-	  opt = opt->next;
-      return &string_type;
-    }
+    return &string_type;
   return t;
 }
 
@@ -405,6 +426,12 @@ set_gc_used_type (t, level)
     case TYPE_LANG_STRUCT:
       for (t = t->u.s.lang_struct; t; t = t->next)
 	set_gc_used_type (t, level);
+      break;
+
+    case TYPE_PARAM_STRUCT:
+      set_gc_used_type (t->u.param_struct.param, GC_POINTED_TO);
+      set_gc_used_type (t->u.param_struct.stru, GC_USED);
+      break;
 
     default:
       break;
@@ -650,6 +677,7 @@ get_output_file_with_visibility (input_f
 	  fputs ("#include \"config.h\"\n", fm->output);
 	  fputs ("#include \"system.h\"\n", fm->output);
 	  fputs ("#include \"varray.h\"\n", fm->output);
+	  fputs ("#include \"hashtab.h\"\n", fm->output);
 	  fputs ("#include \"tree.h\"\n", fm->output);
 	  fputs ("#include \"rtl.h\"\n", fm->output);
 	  fputs ("#include \"function.h\"\n", fm->output);
@@ -747,9 +775,9 @@ close_output_files PARAMS ((void))
 
 static void write_gc_structure_fields 
   PARAMS ((FILE *, type_p, const char *, const char *, options_p, 
-	   int, struct fileloc *, lang_bitmap));
-static void write_gc_marker_routine_for_structure PARAMS ((type_p));
-static void write_gc_types PARAMS ((type_p structures));
+	   int, struct fileloc *, lang_bitmap, type_p));
+static void write_gc_marker_routine_for_structure PARAMS ((type_p, type_p));
+static void write_gc_types PARAMS ((type_p structures, type_p param_structs));
 static void put_mangled_filename PARAMS ((FILE *, const char *));
 static void write_gc_root PARAMS ((FILE *, pair_p, type_p, const char *, int,
 				   struct fileloc *));
@@ -758,7 +786,8 @@ static void write_gc_roots PARAMS ((pair
 static int gc_counter;
 
 static void
-write_gc_structure_fields (of, s, val, prev_val, opts, indent, line, bitmap)
+write_gc_structure_fields (of, s, val, prev_val, opts, indent, line, bitmap,
+			   param)
      FILE *of;
      type_p s;
      const char *val;
@@ -767,6 +796,7 @@ write_gc_structure_fields (of, s, val, p
      int indent;
      struct fileloc *line;
      lang_bitmap bitmap;
+     type_p param;
 {
   pair_p f;
   int tagcounter = -1;
@@ -844,9 +874,21 @@ write_gc_structure_fields (of, s, val, p
 	  always_p = 1;
 	else if (strcmp (oo->name, "desc") == 0 && UNION_P (t))
 	  ;
-	else if (strcmp (oo->name, "descbits") == 0 
-		 && t->kind == TYPE_UNION)
+	else if (strcmp (oo->name, "descbits") == 0 && UNION_P (t))
 	  ;
+	else if (strcmp (oo->name, "use_param") == 0)
+	  {
+	    if (param == NULL)
+	      error_at_line (&f->line, "no parameter defined");
+	    else
+	      {
+		type_p t1;
+		type_p nt = param;
+		for (t1 = t; t->kind == TYPE_POINTER; t = t->u.p)
+		  nt = create_pointer (nt);
+		t = nt;
+	      }
+	  }
 	else
 	  error_at_line (&f->line, "unknown field option `%s'\n", oo->name);
 
@@ -901,8 +943,8 @@ write_gc_structure_fields (of, s, val, p
 
 	    newval = xmalloc (strlen (val) + sizeof (".") + strlen (f->name));
 	    sprintf (newval, "%s.%s", val, f->name);
-	    write_gc_structure_fields (of, t, newval, val,
-				       f->opt, indent, &f->line, bitmap);
+	    write_gc_structure_fields (of, t, newval, val, f->opt, indent, 
+				       &f->line, bitmap, param);
 	    free (newval);
 	    break;
 	  }
@@ -919,6 +961,12 @@ write_gc_structure_fields (of, s, val, p
 		       || t->u.p->kind == TYPE_LANG_STRUCT)
 		fprintf (of, "%*sgt_ggc_m_%s (%s.%s);\n", indent, "", 
 			 t->u.p->u.s.tag, val, f->name);
+	      else if (t->u.p->kind == TYPE_PARAM_STRUCT)
+		fprintf (of, "%*sgt_ggc_mm_%d%s_%s (%s.%s);\n", indent, "",
+			 strlen (t->u.p->u.param_struct.param->u.s.tag),
+			 t->u.p->u.param_struct.param->u.s.tag,
+			 t->u.p->u.param_struct.stru->u.s.tag,
+			 val, f->name);
 	      else
 		error_at_line (&f->line, "field `%s' is pointer to scalar",
 			       f->name);
@@ -958,13 +1006,14 @@ write_gc_structure_fields (of, s, val, p
 		    sprintf (newval, "%s.%s[i%d]", val, f->name, loopcounter);
 		    write_gc_structure_fields (of, t->u.p, newval, val,
 					       f->opt, indent, &f->line,
-					       bitmap);
+					       bitmap, param);
 		    free (newval);
 		    break;
 		  }
 		case TYPE_POINTER:
 		  if (t->u.p->u.p->kind == TYPE_STRUCT
-		      || t->u.p->u.p->kind == TYPE_UNION)
+		      || t->u.p->u.p->kind == TYPE_UNION
+		      || t->u.p->u.p->kind == TYPE_LANG_STRUCT)
 		    fprintf (of, "%*sgt_ggc_m_%s (%s.%s[i%d]);\n", indent, "", 
 			     t->u.p->u.p->u.s.tag, val, f->name,
 			     loopcounter);
@@ -1106,7 +1155,8 @@ write_gc_structure_fields (of, s, val, p
 		  sprintf (newval + strlen (newval), "[i%d_%d]", 
 			   loopcounter, i);
 		write_gc_structure_fields (of, t->u.p, newval, val,
-					   f->opt, indent, &f->line, bitmap);
+					   f->opt, indent, &f->line, bitmap,
+					   param);
 		free (newval);
 	      }
 	    else
@@ -1157,14 +1207,19 @@ write_gc_structure_fields (of, s, val, p
 }
 
 static void
-write_gc_marker_routine_for_structure (s)
+write_gc_marker_routine_for_structure (s, param)
      type_p s;
+     type_p param;
 {
   FILE *f = get_output_file_with_visibility (s->u.s.line.file);
   
   fputc ('\n', f);
   fputs ("void\n", f);
-  fprintf (f, "gt_ggc_m_%s (x_p)\n", s->u.s.tag);
+  if (param == NULL)
+    fprintf (f, "gt_ggc_m_%s (x_p)\n", s->u.s.tag);
+  else
+    fprintf (f, "gt_ggc_mm_%d%s_%s (x_p)\n", strlen (param->u.s.tag),
+	     param->u.s.tag, s->u.s.tag);
   fputs ("      void *x_p;\n", f);
   fputs ("{\n", f);
   fprintf (f, "  %s %s * const x = (%s %s *)x_p;\n",
@@ -1175,15 +1230,17 @@ write_gc_marker_routine_for_structure (s
   
   gc_counter = 0;
   write_gc_structure_fields (f, s, "(*x)", "not valid postage",
-			     s->u.s.opt, 2, &s->u.s.line, s->u.s.bitmap);
+			     s->u.s.opt, 2, &s->u.s.line, s->u.s.bitmap,
+			     param);
   
   fputs ("}\n", f);
 }
      
 
 static void
-write_gc_types (structures)
+write_gc_types (structures, param_structs)
      type_p structures;
+     type_p param_structs;
 {
   type_p s;
   
@@ -1232,10 +1289,47 @@ write_gc_types (structures)
 	  {
 	    type_p ss;
 	    for (ss = s->u.s.lang_struct; ss; ss = ss->next)
-	      write_gc_marker_routine_for_structure (ss);
+	      write_gc_marker_routine_for_structure (ss, NULL);
 	  }
 	else
-	  write_gc_marker_routine_for_structure (s);
+	  write_gc_marker_routine_for_structure (s, NULL);
+      }
+
+  for (s = param_structs; s; s = s->next)
+    if (s->gc_used == GC_POINTED_TO)
+      {
+	type_p param = s->u.param_struct.param;
+	type_p stru = s->u.param_struct.stru;
+
+	if (param->kind != TYPE_STRUCT && param->kind != TYPE_UNION
+	    && param->kind != TYPE_LANG_STRUCT)
+	  {
+	    error_at_line (&s->u.param_struct.line,
+			   "unsupported parameter type");
+	    continue;
+	  }
+	
+	/* Declare the marker procedure.  */
+	fprintf (header_file, 
+		 "extern void gt_ggc_mm_%d%s_%s PARAMS ((void *));\n",
+		 strlen (param->u.s.tag), param->u.s.tag,
+		 stru->u.s.tag);
+  
+	if (stru->u.s.line.file == NULL)
+	  {
+	    fprintf (stderr, "warning: structure `%s' used but not defined\n", 
+		     s->u.s.tag);
+	    continue;
+	  }
+  
+	if (stru->kind == TYPE_LANG_STRUCT)
+	  {
+	    type_p ss;
+	    for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
+	      write_gc_marker_routine_for_structure (ss, param);
+	  }
+	else
+	  write_gc_marker_routine_for_structure (stru, param);
       }
 }
 
@@ -1445,6 +1539,13 @@ write_gc_root (f, v, type, name, has_len
 	  {
 	    fprintf (f, "    &gt_ggc_m_%s\n", tp->u.s.tag);
 	  }
+	else if (! has_length && tp->kind == TYPE_PARAM_STRUCT)
+	  {
+	    fprintf (f, "    &gt_ggc_mm_%d%s_%s\n",
+		     strlen (tp->u.param_struct.param->u.s.tag),
+		     tp->u.param_struct.param->u.s.tag,
+		     tp->u.param_struct.stru->u.s.tag);
+	  }
 	else if (has_length
 		 && tp->kind == TYPE_POINTER)
 	  {
@@ -1491,6 +1592,8 @@ write_gc_roots (variables)
 	  length = (const char *)o->info;
 	else if (strcmp (o->name, "deletable") == 0)
 	  deletable_p = 1;
+	else if (strcmp (o->name, "param_is") == 0)
+	  ;
 	else
 	  error_at_line (&v->line, 
 			 "global `%s' has unknown option `%s'",
@@ -1554,7 +1657,8 @@ write_gc_roots (variables)
 	      fprintf (f, "    for (i = 0; i < (%s); i++)\n", length);
 	      fputs ("      {\n", f);
 	      write_gc_structure_fields (f, s, "x[i]", "x[i]",
-					 v->opt, 8, &v->line, s->u.s.bitmap);
+					 v->opt, 8, &v->line, s->u.s.bitmap,
+					 NULL);
 	      fputs ("      }\n", f);
 	    }
 
@@ -1575,10 +1679,6 @@ write_gc_roots (variables)
 	  length = (const char *)o->info;
 	else if (strcmp (o->name, "deletable") == 0)
 	  deletable_p = 1;
-	else
-	  error_at_line (&v->line, 
-			 "global `%s' has unknown option `%s'",
-			 v->name, o->name);
 
       if (deletable_p)
 	continue;
@@ -1651,6 +1751,9 @@ main(argc, argv)
 	      create_scalar_type ("REAL_VALUE_TYPE", 
 				  strlen ("REAL_VALUE_TYPE")),
 	      &pos);
+  do_typedef ("PTR", create_pointer (create_scalar_type ("void",
+							 strlen ("void"))),
+	      &pos);
 
   for (i = 1; i < argc; i++)
     parse_file (argv[i]);
@@ -1661,11 +1764,9 @@ main(argc, argv)
   set_gc_used (variables);
   set_gc_used_type (find_structure ("mem_attrs", 0), GC_POINTED_TO);
   set_gc_used_type (find_structure ("type_hash", 0), GC_POINTED_TO);
-  set_gc_used_type (find_structure ("deferred_string", 0), GC_POINTED_TO);
-  set_gc_used_type (find_structure ("ehl_map_entry", 0), GC_POINTED_TO);
 
   open_base_files ();
-  write_gc_types (structures);
+  write_gc_types (structures, param_structs);
   write_gc_roots (variables);
   close_output_files ();
 
Index: gcc/gengtype.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/gengtype.h,v
retrieving revision 1.1.2.7
diff -p -u -p -r1.1.2.7 gengtype.h
--- gcc/gengtype.h	4 May 2002 17:26:47 -0000	1.1.2.7
+++ gcc/gengtype.h	10 May 2002 08:50:28 -0000
@@ -34,7 +34,8 @@ enum typekind {
   TYPE_POINTER,
   TYPE_VARRAY,
   TYPE_ARRAY,
-  TYPE_LANG_STRUCT
+  TYPE_LANG_STRUCT,
+  TYPE_PARAM_STRUCT
 };
 
 /* A way to pass data through to the output end.  */
@@ -83,6 +84,11 @@ struct type {
       type_p p;
       const char *len;
     } a;
+    struct {
+      type_p stru;
+      type_p param;
+      struct fileloc line;
+    } param_struct;
   } u;
 };
 
Index: gcc/ggc-common.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/ggc-common.c,v
retrieving revision 1.46.4.11
diff -p -u -p -r1.46.4.11 ggc-common.c
--- gcc/ggc-common.c	8 May 2002 22:38:17 -0000	1.46.4.11
+++ gcc/ggc-common.c	10 May 2002 08:50:28 -0000
@@ -465,6 +465,14 @@ ggc_realloc (x, size)
   return r;
 }
 
+/* Like ggc_alloc_cleared, but performs a multiplication.  */
+void *
+ggc_calloc (s1, s2)
+     size_t s1, s2;
+{
+  return ggc_alloc_cleared (s1 * s2);
+}
+
 /* Print statistics that are independent of the collector in use.  */
 #define SCALE(x) ((unsigned long) ((x) < 1024*10 \
 		  ? (x) \
Index: gcc/ggc.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/ggc.h,v
retrieving revision 1.39.6.12
diff -p -u -p -r1.39.6.12 ggc.h
--- gcc/ggc.h	8 May 2002 22:38:17 -0000	1.39.6.12
+++ gcc/ggc.h	10 May 2002 08:50:28 -0000
@@ -83,7 +83,7 @@ extern void ggc_mark_rtx_children	PARAMS
 /* If EXPR is not NULL and previously unmarked, mark it and evaluate
    to true.  Otherwise evaluate to false.  */
 #define ggc_test_and_set_mark(EXPR) \
-  ((EXPR) != NULL && ! ggc_set_mark (EXPR))
+  ((EXPR) != NULL && ((void *) (EXPR)) != (void *) 1 && ! ggc_set_mark (EXPR))
 
 #define ggc_mark_rtx(EXPR)                      \
   do {                                          \
@@ -97,7 +97,7 @@ extern void ggc_mark_rtx_children	PARAMS
 #define ggc_mark(EXPR)				\
   do {						\
     const void *const a__ = (EXPR);		\
-    if (a__ != NULL)				\
+    if (a__ != NULL && a__ != (void *) 1)	\
       ggc_set_mark (a__);			\
   } while (0)
 
@@ -123,6 +123,8 @@ extern void *ggc_alloc		PARAMS ((size_t)
 extern void *ggc_alloc_cleared	PARAMS ((size_t));
 /* Resize a block.  */
 extern void *ggc_realloc	PARAMS ((void *, size_t));
+/* Like ggc_alloc_cleared, but performs a multiplication.  */
+extern void *ggc_calloc		PARAMS ((size_t, size_t));
 
 #define ggc_alloc_rtx(NSLOTS)						  \
   ((struct rtx_def *) ggc_alloc (sizeof (struct rtx_def)		  \
@@ -133,6 +135,9 @@ extern void *ggc_realloc	PARAMS ((void *
 				   + ((NELT) - 1) * sizeof (rtx)))
 
 #define ggc_alloc_tree(LENGTH) ((union tree_node *) ggc_alloc (LENGTH))
+
+#define htab_create_ggc(SIZE, HASH, EQ, DEL) \
+  htab_create_alloc (SIZE, HASH, EQ, DEL, ggc_calloc, NULL)
 
 /* Allocate a gc-able string, and fill it with LENGTH bytes from CONTENTS.
    If LENGTH is -1, then CONTENTS is assumed to be a
Index: gcc/tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.c,v
retrieving revision 1.230.2.7
diff -p -u -p -r1.230.2.7 tree.c
--- gcc/tree.c	8 May 2002 22:38:18 -0000	1.230.2.7
+++ gcc/tree.c	10 May 2002 08:50:29 -0000
@@ -130,7 +130,6 @@ static void print_type_hash_statistics P
 static void finish_vector_type PARAMS((tree));
 static tree make_vector PARAMS ((enum machine_mode, tree, int));
 static int type_hash_marked_p PARAMS ((const void *));
-static int mark_tree_hashtable_entry PARAMS((void **, void *));
 
 tree global_trees[TI_MAX];
 tree integer_types[itk_none];
@@ -3064,29 +3063,6 @@ type_hash_marked_p (p)
   tree type = ((struct type_hash *) p)->type;
 
   return ggc_marked_p (type) || TYPE_SYMTAB_POINTER (type);
-}
-
-/* Mark the hashtable slot pointed to by ENTRY (which is really a
-   `tree**') for GC.  */
-
-static int
-mark_tree_hashtable_entry (entry, data)
-     void **entry;
-     void *data ATTRIBUTE_UNUSED;
-{
-  ggc_mark_tree ((tree) *entry);
-  return 1;
-}
-
-/* Mark ARG (which is really a htab_t whose slots are trees) for 
-   GC.  */
-
-void
-mark_tree_hashtable (arg)
-     void *arg;
-{
-  htab_t t = *(htab_t *) arg;
-  htab_traverse (t, mark_tree_hashtable_entry, 0);
 }
 
 static void
Index: gcc/tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.h,v
retrieving revision 1.299.2.9
diff -p -u -p -r1.299.2.9 tree.h
--- gcc/tree.h	8 May 2002 22:38:18 -0000	1.299.2.9
+++ gcc/tree.h	10 May 2002 08:50:29 -0000
@@ -2888,7 +2888,6 @@ extern void gcc_obstack_init		PARAMS ((s
 extern void init_obstacks		PARAMS ((void));
 extern void build_common_tree_nodes	PARAMS ((int));
 extern void build_common_tree_nodes_2	PARAMS ((int));
-extern void mark_tree_hashtable         PARAMS ((void *));
 
 /* In function.c */
 extern void setjmp_protect_args		PARAMS ((void));
Index: gcc/varasm.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/varasm.c,v
retrieving revision 1.243.2.12
diff -p -u -p -r1.243.2.12 varasm.c
--- gcc/varasm.c	6 May 2002 18:45:19 -0000	1.243.2.12
+++ gcc/varasm.c	10 May 2002 08:50:30 -0000
@@ -175,11 +175,8 @@ static void asm_output_aligned_bss	PARAM
 						 int, int));
 #endif
 #endif /* BSS_SECTION_ASM_OP */
-static int mark_const_str_htab_1	PARAMS ((void **, void *));
-static void mark_const_str_htab		PARAMS ((void *));
 static hashval_t const_str_htab_hash	PARAMS ((const void *x));
 static int const_str_htab_eq		PARAMS ((const void *x, const void *y));
-static void const_str_htab_del		PARAMS ((void *));
 static void asm_emit_uninitialised	PARAMS ((tree, const char*, int, int));
 static void resolve_unique_section	PARAMS ((tree, int));
 
@@ -2412,28 +2409,7 @@ struct deferred_string GTY(())
   int labelno;
 };
 
-static htab_t const_str_htab;
-
-/* Mark the hash-table element X (which is really a pointer to an
-   struct deferred_string *).  */
-
-static int
-mark_const_str_htab_1 (x, data)
-     void **x;
-     void *data ATTRIBUTE_UNUSED;
-{
-  gt_ggc_m_deferred_string (*x);
-  return 1;
-}
-
-/* Mark a const_str_htab for GC.  */
-
-static void
-mark_const_str_htab (htab)
-     void *htab;
-{
-  htab_traverse (*((htab_t *) htab), mark_const_str_htab_1, NULL);
-}
+static GTY ((param_is (struct deferred_string))) htab_t const_str_htab;
 
 /* Returns a hash code for X (which is a really a
    struct deferred_string *).  */
@@ -2457,15 +2433,6 @@ const_str_htab_eq (x, y)
   return (((const struct deferred_string *) x)->label == (const char *) y);
 }
 
-/* Delete the hash table entry dfsp.  */
-
-static void
-const_str_htab_del (dfsp)
-    void *dfsp;
-{
-  /* No-op.  */
-}
-
 /* Compute a hash code for a constant expression.  */
 
 static int
@@ -4866,13 +4833,10 @@ make_decl_one_only (decl)
 void
 init_varasm_once ()
 {
-  const_str_htab = htab_create (128, const_str_htab_hash, const_str_htab_eq,
-  				const_str_htab_del);
+  const_str_htab = htab_create_ggc (128, const_str_htab_hash, 
+				    const_str_htab_eq, NULL);
   in_named_htab = htab_create (31, in_named_entry_hash,
 			       in_named_entry_eq, NULL);
-
-  ggc_add_root (&const_str_htab, 1, sizeof const_str_htab,
-		mark_const_str_htab);
 
   const_alias_set = new_alias_set ();
 }
Index: gcc/cp/Make-lang.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/Make-lang.in,v
retrieving revision 1.103.6.7
diff -p -u -p -r1.103.6.7 Make-lang.in
--- gcc/cp/Make-lang.in	8 May 2002 22:38:33 -0000	1.103.6.7
+++ gcc/cp/Make-lang.in	10 May 2002 08:50:32 -0000
@@ -133,6 +133,7 @@ $(srcdir)/cp/parse.c: $(srcdir)/cp/parse
 
 gtype-cp.h gt-cp-call.h gt-cp-decl.h gt-cp-decl2.h : s-gtype; @true
 gt-cp-parse.h gt-cp-pt.h gt-cp-repo.h gt-cp-spew.h : s-gtype; @true
+gt-cp-tree.h : s-gtype; @true
 
 #
 # Build hooks:
@@ -278,7 +279,7 @@ cp/method.o: cp/method.c $(CXX_TREE_H) t
 cp/cvt.o: cp/cvt.c $(CXX_TREE_H) cp/decl.h flags.h toplev.h convert.h
 cp/search.o: cp/search.c $(CXX_TREE_H) stack.h flags.h toplev.h $(RTL_H)
 cp/tree.o: cp/tree.c $(CXX_TREE_H) flags.h toplev.h $(GGC_H) $(RTL_H) \
-  insn-config.h integrate.h tree-inline.h
+  insn-config.h integrate.h tree-inline.h gt-cp-tree.h
 cp/ptree.o: cp/ptree.c $(CXX_TREE_H) $(SYSTEM_H)
 cp/rtti.o: cp/rtti.c $(CXX_TREE_H) flags.h toplev.h
 cp/except.o: cp/except.c $(CXX_TREE_H) flags.h $(RTL_H) except.h toplev.h \
Index: gcc/cp/config-lang.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/config-lang.in,v
retrieving revision 1.10.6.2
diff -p -u -p -r1.10.6.2 config-lang.in
--- gcc/cp/config-lang.in	9 Apr 2002 21:57:09 -0000	1.10.6.2
+++ gcc/cp/config-lang.in	10 May 2002 08:50:32 -0000
@@ -34,4 +34,4 @@ stagestuff="g++\$(exeext) g++-cross\$(ex
 
 target_libs="${libstdcxx_version} target-gperf"
 
-gtfiles="\$(srcdir)/cp/cp-tree.h \$(srcdir)/cp/decl.h \$(srcdir)/cp/lex.h \$(srcdir)/cp/call.c \$(srcdir)/cp/decl.c \$(srcdir)/cp/decl2.c \$(srcdir)/cp/parse.y \$(srcdir)/cp/pt.c \$(srcdir)/cp/repo.c \$(srcdir)/cp/spew.c"
+gtfiles="\$(srcdir)/cp/cp-tree.h \$(srcdir)/cp/decl.h \$(srcdir)/cp/lex.h \$(srcdir)/cp/call.c \$(srcdir)/cp/decl.c \$(srcdir)/cp/decl2.c \$(srcdir)/cp/parse.y \$(srcdir)/cp/pt.c \$(srcdir)/cp/repo.c \$(srcdir)/cp/spew.c \$(srcdir)/cp/tree.c"
Index: gcc/cp/tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/tree.c,v
retrieving revision 1.264.6.5
diff -p -u -p -r1.264.6.5 tree.c
--- gcc/cp/tree.c	8 May 2002 22:38:39 -0000	1.264.6.5
+++ gcc/cp/tree.c	10 May 2002 08:50:32 -0000
@@ -707,7 +707,7 @@ unshare_base_binfos (binfo)
    While all these live in the same table, they are completely independent,
    and the hash code is computed differently for each of these.  */
 
-static htab_t list_hash_table;
+static GTY ((param_is (union tree_node))) htab_t list_hash_table;
 
 struct list_proxy 
 {
@@ -2292,10 +2292,7 @@ void
 init_tree ()
 {
   lang_statement_code_p = cp_statement_code_p;
-  list_hash_table = htab_create (31, list_hash, list_hash_eq, NULL);
-  ggc_add_root (&list_hash_table, 1, 
-		sizeof (list_hash_table),
-		mark_tree_hashtable);
+  list_hash_table = htab_create_ggc (31, list_hash, list_hash_eq, NULL);
 }
 
 /* Called via walk_tree.  If *TP points to a DECL_STMT for a local
@@ -2538,3 +2535,5 @@ lang_check_failed (file, line, function)
 		  function, trim_filename (file), line);
 }
 #endif /* ENABLE_TREE_CHECKING */
+
+#include "gt-cp-tree.h"
Index: include/hashtab.h
===================================================================
RCS file: /cvs/gcc/gcc/include/hashtab.h,v
retrieving revision 1.11
diff -p -u -p -r1.11 hashtab.h
--- include/hashtab.h	17 Aug 2001 01:54:01 -0000	1.11
+++ include/hashtab.h	10 May 2002 17:01:12 -0000
@@ -38,6 +38,10 @@ extern "C" {
 
 #include <ansidecl.h>
 
+#ifndef GTY
+#define GTY(X)
+#endif
+
 /* The type for a hash code.  */
 typedef unsigned int hashval_t;
 
@@ -63,12 +67,21 @@ typedef void (*htab_del) PARAMS ((void *
    htab_traverse.  Return 1 to continue scan, 0 to stop.  */
 typedef int (*htab_trav) PARAMS ((void **, void *));
 
+/* Memory-allocation function, with the same functionality as calloc().
+   Iff it returns NULL, the hash table implementation will pass an error
+   code back to the user, so if your code doesn't handle errors,
+   best if you use xcalloc instead.  */
+typedef PTR (*htab_alloc) PARAMS ((size_t, size_t));
+
+/* We also need a free() routine.  */
+typedef void (*htab_free) PARAMS ((PTR));
+
 /* Hash tables are of the following type.  The structure
    (implementation) of this type is not needed for using the hash
    tables.  All work with hash table should be executed only through
    functions mentioned below. */
 
-struct htab
+struct htab GTY(())
 {
   /* Pointer to hash function.  */
   htab_hash hash_f;
@@ -79,8 +92,12 @@ struct htab
   /* Pointer to cleanup function.  */
   htab_del del_f;
 
+  /* Pointers to allocate/free functions.  */
+  htab_alloc alloc_f;
+  htab_free free_f;
+  
   /* Table itself.  */
-  PTR *entries;
+  PTR * GTY ((use_param (""), length ("%.size"))) entries;
 
   /* Current size (in entries) of the hash table */
   size_t size;
@@ -98,10 +115,6 @@ struct htab
   /* The following member is used for debugging.  Its value is number
      of collisions fixed for time of work with the hash table. */
   unsigned int collisions;
-
-  /* This is non-zero if we are allowed to return NULL for function calls
-     that allocate memory.  */
-  int return_allocation_failure;
 };
 
 typedef struct htab *htab_t;
@@ -111,14 +124,14 @@ enum insert_option {NO_INSERT, INSERT};
 
 /* The prototypes of the package functions. */
 
-extern htab_t	htab_create	PARAMS ((size_t, htab_hash,
-					 htab_eq, htab_del));
+extern htab_t	htab_create_alloc	PARAMS ((size_t, htab_hash,
+						 htab_eq, htab_del,
+						 htab_alloc, htab_free));
+
+/* Provided for convenience... */
+#define htab_create(SIZE, HASH, EQ, DEL) \
+  htab_create_alloc (SIZE, HASH, EQ, DEL, xcalloc, free)
 
-/* This function is like htab_create, but may return NULL if memory
-   allocation fails, and also signals that htab_find_slot_with_hash and
-   htab_find_slot are allowed to return NULL when inserting.  */
-extern htab_t	htab_try_create	PARAMS ((size_t, htab_hash,
-					 htab_eq, htab_del));
 extern void	htab_delete	PARAMS ((htab_t));
 extern void	htab_empty	PARAMS ((htab_t));
 
============================================================


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