ggc.h (struct alloc_zone): Move forward declaration up.

* ggc.h (struct alloc_zone): Move forward declaration up.
	(new_ggc_zone): New function prototype.
	(destroy_ggc_zone): Ditto.
	* ggc-simple.c (new_ggc_zone): New function, does nothing.
	(destroy_ggc_zone): Ditto.
	* ggc-page.c (new_ggc_zone): New function, does nothing.
	(destroy_ggc_zone): Ditto.
	* ggc-zone.c (struct page_entry): Fix comment.
	(ggc_alloc_typed): Use a switch statement instead of ifs.
	(new_ggc_zone): New function to set up a new GC zone.
	(destroy_ggc_zone): New function to remove a GC zone.
	init_ggc): Use new_ggc_zone to set up the default zones.
	(ggc_collect): Walk a list of zones, instead of just the
	default zones.  Report statistics using the zone name.

From-SVN: r74132
This commit is contained in:
Steven Bosscher 2003-12-01 22:59:30 +00:00 committed by Steven Bosscher
parent f26deb3d44
commit 47aeffac9c
5 changed files with 128 additions and 51 deletions

View File

@ -1,3 +1,20 @@
2003-12-01 Steven Bosscher <stevenb@suse.de>
* ggc.h (struct alloc_zone): Move forward declaration up.
(new_ggc_zone): New function prototype.
(destroy_ggc_zone): Ditto.
* ggc-simple.c (new_ggc_zone): New function, does nothing.
(destroy_ggc_zone): Ditto.
* ggc-page.c (new_ggc_zone): New function, does nothing.
(destroy_ggc_zone): Ditto.
* ggc-zone.c (struct page_entry): Fix comment.
(ggc_alloc_typed): Use a switch statement instead of ifs.
(new_ggc_zone): New function to set up a new GC zone.
(destroy_ggc_zone): New function to remove a GC zone.
init_ggc): Use new_ggc_zone to set up the default zones.
(ggc_collect): Walk a list of zones, instead of just the
default zones. Report statistics using the zone name.
2003-12-01 Ulrich Weigand <uweigand@de.ibm.com>
* unroll.c (find_splittable_givs): Add missing extend_value_for_giv.

View File

@ -1401,6 +1401,20 @@ init_ggc (void)
G.save_in_use = xmalloc (G.by_depth_max * sizeof (unsigned long *));
}
/* Start a new GGC zone. */
struct alloc_zone *
new_ggc_zone (const char *name ATTRIBUTE_UNUSED)
{
return NULL;
}
/* Destroy a GGC zone. */
void
destroy_ggc_zone (struct alloc_zone *zone ATTRIBUTE_UNUSED)
{
}
/* Increment the `GC context'. Objects allocated in an outer context
are never freed, eliminating the need to register their roots. */

View File

@ -344,6 +344,20 @@ init_ggc (void)
{
}
/* Start a new GGC zone. */
struct alloc_zone *
new_ggc_zone (const char *name ATTRIBUTE_UNUSED)
{
return NULL;
}
/* Destroy a GGC zone. */
void
destroy_ggc_zone (struct alloc_zone *zone ATTRIBUTE_UNUSED)
{
}
/* Start a new GGC context. Memory allocated in previous contexts
will not be collected while the new context is active. */

View File

@ -277,6 +277,7 @@ typedef struct page_entry
/* Does this page contain small objects, or one large object? */
bool large_p;
/* The zone that this page entry belongs to. */
struct alloc_zone *zone;
} page_entry;
@ -1007,14 +1008,20 @@ ggc_alloc_zone_1 (size_t size, struct alloc_zone *zone, short type)
void *
ggc_alloc_typed (enum gt_types_enum gte, size_t size)
{
if (gte == gt_ggc_e_14lang_tree_node)
return ggc_alloc_zone_1 (size, tree_zone, gte);
else if (gte == gt_ggc_e_7rtx_def)
return ggc_alloc_zone_1 (size, rtl_zone, gte);
else if (gte == gt_ggc_e_9rtvec_def)
return ggc_alloc_zone_1 (size, rtl_zone, gte);
else
return ggc_alloc_zone_1 (size, &main_zone, gte);
switch (gte)
{
case gt_ggc_e_14lang_tree_node:
return ggc_alloc_zone_1 (size, tree_zone, gte);
case gt_ggc_e_7rtx_def:
return ggc_alloc_zone_1 (size, rtl_zone, gte);
case gt_ggc_e_9rtvec_def:
return ggc_alloc_zone_1 (size, rtl_zone, gte);
default:
return ggc_alloc_zone_1 (size, &main_zone, gte);
}
}
/* Normal ggc_alloc simply allocates into the main zone. */
@ -1135,24 +1142,14 @@ ggc_get_size (const void *p)
void
init_ggc (void)
{
/* Create the zones. */
/* Set up the main zone by hand. */
main_zone.name = "Main zone";
G.zones = &main_zone;
rtl_zone = xcalloc (1, sizeof (struct alloc_zone));
rtl_zone->name = "RTL zone";
/* The main zone's connected to the ... rtl_zone */
G.zones->next_zone = rtl_zone;
garbage_zone = xcalloc (1, sizeof (struct alloc_zone));
garbage_zone->name = "Garbage zone";
/* The rtl zone's connected to the ... garbage zone */
rtl_zone->next_zone = garbage_zone;
tree_zone = xcalloc (1, sizeof (struct alloc_zone));
tree_zone->name = "Tree zone";
/* The garbage zone's connected to ... the tree zone */
garbage_zone->next_zone = tree_zone;
/* Allocate the default zones. */
rtl_zone = new_ggc_zone ("RTL zone");
tree_zone = new_ggc_zone ("Tree zone");
garbage_zone = new_ggc_zone ("Garbage zone");
G.pagesize = getpagesize();
G.lg_pagesize = exact_log2 (G.pagesize);
@ -1197,6 +1194,40 @@ init_ggc (void)
#endif
}
/* Start a new GGC zone. */
struct alloc_zone *
new_ggc_zone (const char * name)
{
struct alloc_zone *new_zone = xcalloc (1, sizeof (struct alloc_zone));
new_zone->name = name;
new_zone->next_zone = G.zones->next_zone;
G.zones->next_zone = new_zone;
return new_zone;
}
/* Destroy a GGC zone. */
void
destroy_ggc_zone (struct alloc_zone * dead_zone)
{
struct alloc_zone *z;
for (z = G.zones; z && z->next_zone != dead_zone; z = z->next_zone)
/* Just find that zone. */ ;
/* We should have found the zone in the list. Anything else is
fatal.
If we did find the zone, we expect this zone to be empty.
A ggc_collect should have emptied it before we can destroy it. */
if (!z || dead_zone->allocated != 0)
abort ();
/* Unchain the dead zone, release all its pages and free it. */
z->next_zone = z->next_zone->next_zone;
release_pages (dead_zone);
free (dead_zone);
}
/* Increment the `GC context'. Objects allocated in an outer context
are never freed, eliminating the need to register their roots. */
@ -1234,9 +1265,9 @@ ggc_pop_context_1 (struct alloc_zone *zone)
/* Any remaining pages in the popped context are lowered to the new
current context; i.e. objects allocated in the popped context and
left over are imported into the previous context. */
for (p = zone->pages; p != NULL; p = p->next)
if (p->context_depth > depth)
p->context_depth = depth;
for (p = zone->pages; p != NULL; p = p->next)
if (p->context_depth > depth)
p->context_depth = depth;
}
/* Pop all the zone contexts. */
@ -1478,6 +1509,7 @@ ggc_collect (void)
/* Start by possibly collecting the main zone. */
main_zone.was_collected = false;
marked |= ggc_collect_1 (&main_zone, true);
/* In order to keep the number of collections down, we don't
collect other zones unless we are collecting the main zone. This
gives us roughly the same number of collections as we used to
@ -1489,36 +1521,30 @@ ggc_collect (void)
if (main_zone.was_collected)
{
check_cookies ();
rtl_zone->was_collected = false;
marked |= ggc_collect_1 (rtl_zone, !marked);
check_cookies ();
tree_zone->was_collected = false;
marked |= ggc_collect_1 (tree_zone, !marked);
check_cookies ();
garbage_zone->was_collected = false;
marked |= ggc_collect_1 (garbage_zone, !marked);
struct alloc_zone *zone;
for (zone = main_zone.next_zone; zone; zone = zone->next_zone)
{
check_cookies ();
zone->was_collected = false;
marked |= ggc_collect_1 (zone, !marked);
}
}
/* Print page survival stats, if someone wants them. */
if (GGC_DEBUG_LEVEL >= 2)
{
if (rtl_zone->was_collected)
for (zone = G.zones; zone; zone = zone->next_zone)
{
f = calculate_average_page_survival (rtl_zone);
printf ("Average RTL page survival is %f\n", f);
}
if (main_zone.was_collected)
{
f = calculate_average_page_survival (&main_zone);
printf ("Average main page survival is %f\n", f);
}
if (tree_zone->was_collected)
{
f = calculate_average_page_survival (tree_zone);
printf ("Average tree page survival is %f\n", f);
if (zone->was_collected)
{
f = calculate_average_page_survival (zone);
printf ("Average page survival in zone `%s' is %f\n",
zone->name, f);
}
}
}
/* Since we don't mark zone at a time right now, marking in any
zone means marking in every zone. So we have to clear all the
marks in all the zones that weren't collected already. */
@ -1578,7 +1604,6 @@ struct ggc_pch_data
} d;
size_t base;
size_t written;
};
/* Initialize the PCH datastructure. */

View File

@ -141,9 +141,18 @@ extern void init_stringpool (void);
/* A GC implementation must provide these functions. They are internal
to the GC system. */
/* Forward declare the zone structure. Only ggc_zone implements this. */
struct alloc_zone;
/* Initialize the garbage collector. */
extern void init_ggc (void);
/* Start a new GGC zone. */
extern struct alloc_zone *new_ggc_zone (const char *);
/* Free a complete GGC zone, destroying everything in it. */
extern void destroy_ggc_zone (struct alloc_zone *);
/* Start a new GGC context. Memory allocated in previous contexts
will not be collected while the new context is active. */
extern void ggc_push_context (void);
@ -193,8 +202,6 @@ extern void ggc_pch_read (FILE *, void *);
/* Allocation. */
/* Zone structure. */
struct alloc_zone;
/* For single pass garbage. */
extern struct alloc_zone *garbage_zone;
/* For regular rtl allocations. */