aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurynas Biveinis <laurynas.biveinis@gmail.com>2006-08-13 15:05:15 +0000
committerLaurynas Biveinis <laurynas.biveinis@gmail.com>2006-08-13 15:05:15 +0000
commit34e84bae5f33a172e2627c11f3e3d050511e0e6f (patch)
treeec08d93ac592020373a1f7ccd3cb828ecbc24072
parentf68455dc292bbcdf411da364bbe1da7e60bca3bc (diff)
Add type tag to type-allocated objects
git-svn-id: https://gcc.gnu.org/svn/gcc/branches/boehms-gc@116110 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/alias.c2
-rw-r--r--gcc/gengtype.c72
-rwxr-xr-xgcc/ggc-boehm.c48
-rw-r--r--gcc/rtl.h3
-rw-r--r--gcc/tree.h3
5 files changed, 122 insertions, 6 deletions
diff --git a/gcc/alias.c b/gcc/alias.c
index 7c51ad79dd6..22ac07654ed 100644
--- a/gcc/alias.c
+++ b/gcc/alias.c
@@ -670,7 +670,7 @@ record_alias_subset (HOST_WIDE_INT superset, HOST_WIDE_INT subset)
{
/* Create an entry for the SUPERSET, so that we have a place to
attach the SUBSET. */
- superset_entry = ggc_alloc (sizeof (struct alias_set_entry));
+ superset_entry = ggc_alloc_alias_set_entry();
superset_entry->alias_set = superset;
superset_entry->children
= splay_tree_new_ggc (splay_tree_compare_ints);
diff --git a/gcc/gengtype.c b/gcc/gengtype.c
index 2ca4ac7af36..a0124c1dd79 100644
--- a/gcc/gengtype.c
+++ b/gcc/gengtype.c
@@ -1545,6 +1545,8 @@ walk_type (type_p t, struct walk_type_data *d)
use_param_num = oo->name[9] == '\0' ? 0 : oo->name[9] - '0';
else if (strcmp (oo->name, "use_params") == 0)
use_params_p = 1;
+ else if (strcmp (oo->name, "size_not_fixed") == 0)
+ ;
else if (strcmp (oo->name, "desc") == 0)
desc = oo->info;
else if (strcmp (oo->name, "nested_ptr") == 0)
@@ -2436,7 +2438,7 @@ write_enum_defn (type_p structures, type_p param_structs)
{
type_p s;
- oprintf (header_file, "\n/* Enumeration of types known. */\n");
+ oprintf (header_file, "\n/* Enumeration of known types. */\n");
oprintf (header_file, "enum gt_types_enum {\n");
for (s = structures; s; s = s->next)
if (s->gc_used == GC_POINTED_TO
@@ -2450,6 +2452,7 @@ write_enum_defn (type_p structures, type_p param_structs)
output_mangled_typename (header_file, s);
oprintf (header_file, ", \n");
}
+
for (s = param_structs; s; s = s->next)
if (s->gc_used == GC_POINTED_TO)
{
@@ -2457,10 +2460,76 @@ write_enum_defn (type_p structures, type_p param_structs)
output_mangled_typename (header_file, s);
oprintf (header_file, ", \n");
}
+
oprintf (header_file, " gt_types_enum_last\n");
oprintf (header_file, "};\n");
}
+/* Write out a macro for typed allocations for each known struct or union. */
+
+static void
+write_typed_alloc_defns (type_p structures)
+{
+ type_p s;
+ pair_p p;
+
+ oprintf (header_file,
+ "\n/* Typed allocation for known structs and unions. */\n");
+ for (s = structures; s; s = s->next)
+ if (s->gc_used == GC_POINTED_TO
+ || (s->gc_used == GC_MAYBE_POINTED_TO && s->u.s.line.file != NULL))
+ {
+ options_p o;
+ int have_size = 0;
+ const char *type_kind;
+
+ for (o = s->u.s.opt; o; o = o->next)
+ if (strcmp (o->name, "size_not_fixed") == 0)
+ have_size = 1;
+
+ if (s->kind == TYPE_STRUCT)
+ type_kind = "struct ";
+ else if (s->kind == TYPE_UNION)
+ type_kind = "union ";
+ else
+ type_kind = "";
+
+ oprintf (header_file, "#define ggc_alloc_%s(%s) \\\n",
+ s->u.s.tag, (have_size ? "SIZE" : ""));
+ oprintf (header_file, " ggc_alloc_typed(gt_ggc_e_");
+ output_mangled_typename (header_file, s);
+ if (have_size)
+ oprintf (header_file, ", SIZE)\n");
+ else
+ oprintf (header_file, ", sizeof (%s%s))\n",
+ type_kind, s->u.s.tag);
+ }
+
+ oprintf (header_file,
+ "\n/* Typed allocation for known typedefs. */\n");
+ for (p = typedefs; p != NULL; p = p->next)
+ {
+ s = p->type;
+ if (strcmp (p->name, s->u.s.tag) == 0)
+ continue;
+
+ if (s->gc_used == GC_POINTED_TO
+ || (s->gc_used == GC_MAYBE_POINTED_TO && s->u.s.line.file != NULL))
+ {
+ if (s->kind != TYPE_STRUCT
+ && s->kind != TYPE_UNION)
+ continue;
+
+ oprintf (header_file, "#define ggc_alloc_%s(%s) \\\n",
+ p->name, s->kind == TYPE_STRUCT ? "" : "__SIZE");
+ oprintf (header_file, " ggc_alloc_typed(gt_ggc_e_");
+ output_mangled_typename (header_file, s);
+ oprintf (header_file, ", sizeof (%s%s))\n",
+ s->kind == TYPE_STRUCT ? "struct " : "", s->u.s.tag);
+ }
+ }
+}
+
/* Might T contain any non-pointer elements? */
static int
@@ -3083,6 +3152,7 @@ main(int ARG_UNUSED (argc), char ** ARG_UNUSED (argv))
open_base_files ();
write_enum_defn (structures, param_structs);
+ write_typed_alloc_defns (structures);
write_types (structures, param_structs, &ggc_wtd);
write_types (structures, param_structs, &pch_wtd);
write_local (structures, param_structs);
diff --git a/gcc/ggc-boehm.c b/gcc/ggc-boehm.c
index 1de49592871..e9d7f4dead7 100755
--- a/gcc/ggc-boehm.c
+++ b/gcc/ggc-boehm.c
@@ -16,17 +16,25 @@ static int ggc_htab_register_weak_ptr(void **slot, void *info);
static int ggc_htab_unregister_weak_ptr(void **slot, void *info);
static void ggc_htab_delete_weak_ptr(void ** slot, void * object,
void * info);
+
static size_t get_used_heap_size(void);
static void register_gty_roots(void);
static void gc_warning_filter(char * msg, GC_word arg);
+
+static enum gt_types_enum *get_type_offset(void * block);
+static enum gt_types_enum get_block_type(void * block);
+
static void register_weak_pointers(void);
static void unregister_weak_pointers(void);
static size_t last_allocated = 0;
+static size_t type_overhead = 0;
static ggc_stringpool_roots stringpool_roots;
static GC_warn_proc default_warn_proc;
+#define OBJ_OVERHEAD sizeof(enum gt_types_enum)
+
void
init_ggc (void)
{
@@ -52,6 +60,38 @@ ggc_alloc_stat (size_t size MEM_STAT_DECL)
return result;
}
+enum gt_types_enum *
+get_type_offset(void * block)
+{
+ return (enum gt_types_enum *)((char *)block + GC_size(block) - OBJ_OVERHEAD);
+}
+
+void *
+ggc_alloc_typed_stat (enum gt_types_enum type, size_t size MEM_STAT_DECL)
+{
+ void * result = NULL;
+
+ size_t actual_obj_size;
+ const size_t obj_plus_info_size = size + OBJ_OVERHEAD;
+ type_overhead += obj_plus_info_size;
+
+ result = GC_malloc (obj_plus_info_size);
+ actual_obj_size = GC_size(result);
+
+ *(get_type_offset(result)) = type;
+
+ /* Verification */
+ gcc_assert (type == get_block_type (result));
+
+ return result;
+}
+
+enum gt_types_enum
+get_block_type(void * block)
+{
+ return *(get_type_offset(block));
+}
+
void *
ggc_realloc_stat (void *x, size_t size MEM_STAT_DECL)
{
@@ -177,8 +217,9 @@ ggc_free (void * block)
size_t
ggc_get_size (const void * block)
{
- return GC_size((void *)block); /* Note that GC_size may return a bit larger
- value than originally requested */
+ return GC_size((void *)block) - OBJ_OVERHEAD; /* Note that GC_size may return
+ a bit larger value than
+ originally requested */
}
int
@@ -267,6 +308,9 @@ ggc_print_statistics (void)
fprintf (stderr,
"Used bytes in the heap: %lu\n",
(unsigned long)get_used_heap_size());
+ fprintf (stderr,
+ "Local ggc-boehm overhead: %lu\n",
+ (unsigned long)type_overhead);
}
int
diff --git a/gcc/rtl.h b/gcc/rtl.h
index 42c4db6524a..8f6bb99e59c 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -232,7 +232,8 @@ struct object_block GTY(())
/* RTL expression ("rtx"). */
struct rtx_def GTY((chain_next ("RTX_NEXT (&%h)"),
- chain_prev ("RTX_PREV (&%h)")))
+ chain_prev ("RTX_PREV (&%h)"),
+ size_not_fixed ("")))
{
/* The kind of expression this is. */
ENUM_BITFIELD(rtx_code) code: 16;
diff --git a/gcc/tree.h b/gcc/tree.h
index 9c1181873f8..ea77424ad52 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -3143,7 +3143,8 @@ struct tree_value_handle GTY(())
for various types of node. */
union tree_node GTY ((ptr_alias (union lang_tree_node),
- desc ("tree_node_structure (&%h)")))
+ desc ("tree_node_structure (&%h)"),
+ size_not_fixed ("")))
{
struct tree_common GTY ((tag ("TS_COMMON"))) common;
struct tree_int_cst GTY ((tag ("TS_INT_CST"))) int_cst;