summaryrefslogtreecommitdiff
path: root/gcc/ggc-zone.c
diff options
context:
space:
mode:
authorsteven <steven@138bc75d-0d04-0410-961f-82ee72b054a4>2003-12-01 22:59:30 +0000
committersteven <steven@138bc75d-0d04-0410-961f-82ee72b054a4>2003-12-01 22:59:30 +0000
commit867d54fa17b07a131758adc8b0ce1e81d263fe86 (patch)
tree828e8c449db658913176f3c52668d0d0325b655d /gcc/ggc-zone.c
parent72983aaaa3107d9c4d65eb1e00da7021ecc0a8c2 (diff)
downloadgcc-867d54fa17b07a131758adc8b0ce1e81d263fe86.tar.gz
* 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@74132 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ggc-zone.c')
-rw-r--r--gcc/ggc-zone.c123
1 files changed, 74 insertions, 49 deletions
diff --git a/gcc/ggc-zone.c b/gcc/ggc-zone.c
index d9c82e6c696..4aee63852b2 100644
--- a/gcc/ggc-zone.c
+++ b/gcc/ggc-zone.c
@@ -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)
- {
- 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)
+ for (zone = G.zones; zone; zone = zone->next_zone)
{
- 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. */