ggc.h (ggc_push_context): Fix comment.
* ggc.h (ggc_push_context): Fix comment. (ggc_pop_context): Likewise. (mark_string_if_gcable): Likewise. * ggc-common.c (ggc_mark_rtx_children): Use ggc_mark_string_if_gcable. * ggc-page.c (ggc_lookup_page_table): New function. (ggc_allocated_p): Likewise. (mark_obj): Fix formatting. (ggc_mark_string_if_gcable): New function. * ggc-simple.c (ggc_allocated_strings): New variable. (ggc_strings_used): Likewise. (ggc_compare_addresses): New function. (ggc_pop_context): Pop the `any' memory too. (ggc_mark_string_if_gcable): New function. (ggc_collect): Initialize and tear down ggc_allocated_strings. From-SVN: r29897
This commit is contained in:
parent
f9562f27ff
commit
74c937ca61
@ -1,3 +1,21 @@
|
|||||||
|
Sun Oct 10 18:27:27 1999 Mark Mitchell <mark@codesourcery.com>
|
||||||
|
|
||||||
|
* ggc.h (ggc_push_context): Fix comment.
|
||||||
|
(ggc_pop_context): Likewise.
|
||||||
|
(mark_string_if_gcable): Likewise.
|
||||||
|
* ggc-common.c (ggc_mark_rtx_children): Use
|
||||||
|
ggc_mark_string_if_gcable.
|
||||||
|
* ggc-page.c (ggc_lookup_page_table): New function.
|
||||||
|
(ggc_allocated_p): Likewise.
|
||||||
|
(mark_obj): Fix formatting.
|
||||||
|
(ggc_mark_string_if_gcable): New function.
|
||||||
|
* ggc-simple.c (ggc_allocated_strings): New variable.
|
||||||
|
(ggc_strings_used): Likewise.
|
||||||
|
(ggc_compare_addresses): New function.
|
||||||
|
(ggc_pop_context): Pop the `any' memory too.
|
||||||
|
(ggc_mark_string_if_gcable): New function.
|
||||||
|
(ggc_collect): Initialize and tear down ggc_allocated_strings.
|
||||||
|
|
||||||
Sun Oct 10 20:05:21 1999 David Edelsohn <edelsohn@gnu.org>
|
Sun Oct 10 20:05:21 1999 David Edelsohn <edelsohn@gnu.org>
|
||||||
|
|
||||||
* rs6000.md (movstrsi_?reg): Use preferred rD/rS = r5 form.
|
* rs6000.md (movstrsi_?reg): Use preferred rD/rS = r5 form.
|
||||||
|
@ -268,7 +268,7 @@ ggc_mark_rtx_children (r)
|
|||||||
ggc_mark_rtvec (XVEC (r, i));
|
ggc_mark_rtvec (XVEC (r, i));
|
||||||
break;
|
break;
|
||||||
case 'S': case 's':
|
case 'S': case 's':
|
||||||
ggc_mark_string (XSTR (r, i));
|
ggc_mark_string_if_gcable (XSTR (r, i));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -258,6 +258,8 @@ static struct globals
|
|||||||
#define GGC_MIN_LAST_ALLOCATED (4 * 1024 * 1024)
|
#define GGC_MIN_LAST_ALLOCATED (4 * 1024 * 1024)
|
||||||
|
|
||||||
|
|
||||||
|
static page_entry *** ggc_lookup_page_table PROTO ((void));
|
||||||
|
static int ggc_allocated_p PROTO ((const void *));
|
||||||
static page_entry *lookup_page_table_entry PROTO ((void *));
|
static page_entry *lookup_page_table_entry PROTO ((void *));
|
||||||
static void set_page_table_entry PROTO ((void *, page_entry *));
|
static void set_page_table_entry PROTO ((void *, page_entry *));
|
||||||
static char *alloc_anon PROTO ((char *, size_t));
|
static char *alloc_anon PROTO ((char *, size_t));
|
||||||
@ -276,15 +278,12 @@ static void poison_pages PROTO ((void));
|
|||||||
|
|
||||||
void debug_print_page_list PROTO ((int));
|
void debug_print_page_list PROTO ((int));
|
||||||
|
|
||||||
/* Traverse the page table and find the entry for a page.
|
/* Returns the lookup table appropriate for looking up P. */
|
||||||
Die (probably) if the object wasn't allocated via GC. */
|
|
||||||
|
|
||||||
static inline page_entry *
|
static inline page_entry ***
|
||||||
lookup_page_table_entry(p)
|
ggc_lookup_page_table ()
|
||||||
void *p;
|
|
||||||
{
|
{
|
||||||
page_entry ***base;
|
page_entry ***base;
|
||||||
size_t L1, L2;
|
|
||||||
|
|
||||||
#if HOST_BITS_PER_PTR <= 32
|
#if HOST_BITS_PER_PTR <= 32
|
||||||
base = &G.lookup[0];
|
base = &G.lookup[0];
|
||||||
@ -296,6 +295,39 @@ lookup_page_table_entry(p)
|
|||||||
base = &table->table[0];
|
base = &table->table[0];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns non-zero if P was allocated in GC'able memory. */
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
ggc_allocated_p (p)
|
||||||
|
const void *p;
|
||||||
|
{
|
||||||
|
page_entry ***base;
|
||||||
|
size_t L1, L2;
|
||||||
|
|
||||||
|
base = ggc_lookup_page_table ();
|
||||||
|
|
||||||
|
/* Extract the level 1 and 2 indicies. */
|
||||||
|
L1 = LOOKUP_L1 (p);
|
||||||
|
L2 = LOOKUP_L2 (p);
|
||||||
|
|
||||||
|
return base[L1] && base[L1][L2];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Traverse the page table and find the entry for a page.
|
||||||
|
Die (probably) if the object wasn't allocated via GC. */
|
||||||
|
|
||||||
|
static inline page_entry *
|
||||||
|
lookup_page_table_entry(p)
|
||||||
|
void *p;
|
||||||
|
{
|
||||||
|
page_entry ***base;
|
||||||
|
size_t L1, L2;
|
||||||
|
|
||||||
|
base = ggc_lookup_page_table ();
|
||||||
|
|
||||||
/* Extract the level 1 and 2 indicies. */
|
/* Extract the level 1 and 2 indicies. */
|
||||||
L1 = LOOKUP_L1 (p);
|
L1 = LOOKUP_L1 (p);
|
||||||
L2 = LOOKUP_L2 (p);
|
L2 = LOOKUP_L2 (p);
|
||||||
@ -678,7 +710,7 @@ mark_obj (p)
|
|||||||
|
|
||||||
/* Look up the page on which the object is alloced. If the object
|
/* Look up the page on which the object is alloced. If the object
|
||||||
wasn't allocated by the collector, we'll probably die. */
|
wasn't allocated by the collector, we'll probably die. */
|
||||||
entry = lookup_page_table_entry(p);
|
entry = lookup_page_table_entry (p);
|
||||||
#ifdef ENABLE_CHECKING
|
#ifdef ENABLE_CHECKING
|
||||||
if (entry == NULL)
|
if (entry == NULL)
|
||||||
abort ();
|
abort ();
|
||||||
@ -1076,6 +1108,14 @@ ggc_mark_string (s)
|
|||||||
mark_obj (s);
|
mark_obj (s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ggc_mark_string_if_gcable (s)
|
||||||
|
char *s;
|
||||||
|
{
|
||||||
|
if (s && ggc_allocated_p (s))
|
||||||
|
mark_obj (s);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ggc_mark (p)
|
ggc_mark (p)
|
||||||
void *p;
|
void *p;
|
||||||
|
@ -114,6 +114,10 @@ struct ggc_status
|
|||||||
front of the chain. */
|
front of the chain. */
|
||||||
static struct ggc_status *ggc_chain;
|
static struct ggc_status *ggc_chain;
|
||||||
|
|
||||||
|
/* The table of all allocated strings. Only valid during collection. */
|
||||||
|
static varray_type ggc_allocated_strings;
|
||||||
|
static size_t ggc_strings_used;
|
||||||
|
|
||||||
/* Some statistics. */
|
/* Some statistics. */
|
||||||
|
|
||||||
static int n_rtxs_collected;
|
static int n_rtxs_collected;
|
||||||
@ -134,6 +138,7 @@ static void ggc_free_rtvec PROTO ((struct ggc_rtvec *v));
|
|||||||
static void ggc_free_tree PROTO ((struct ggc_tree *t));
|
static void ggc_free_tree PROTO ((struct ggc_tree *t));
|
||||||
static void ggc_free_string PROTO ((struct ggc_string *s));
|
static void ggc_free_string PROTO ((struct ggc_string *s));
|
||||||
static void ggc_free_any PROTO ((struct ggc_any *a));
|
static void ggc_free_any PROTO ((struct ggc_any *a));
|
||||||
|
static int ggc_compare_addresses PROTO ((const void *, const void *));
|
||||||
|
|
||||||
/* Called once to initialize the garbage collector. */
|
/* Called once to initialize the garbage collector. */
|
||||||
|
|
||||||
@ -173,6 +178,7 @@ ggc_pop_context PROTO ((void))
|
|||||||
struct ggc_rtvec *v;
|
struct ggc_rtvec *v;
|
||||||
struct ggc_tree *t;
|
struct ggc_tree *t;
|
||||||
struct ggc_string *s;
|
struct ggc_string *s;
|
||||||
|
struct ggc_any *a;
|
||||||
struct ggc_status *gs;
|
struct ggc_status *gs;
|
||||||
|
|
||||||
gs = ggc_chain;
|
gs = ggc_chain;
|
||||||
@ -213,6 +219,15 @@ ggc_pop_context PROTO ((void))
|
|||||||
gs->next->strings = gs->strings;
|
gs->next->strings = gs->strings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a = gs->anys;
|
||||||
|
if (a)
|
||||||
|
{
|
||||||
|
while (a->chain)
|
||||||
|
a = a->chain;
|
||||||
|
a->chain = gs->next->anys;
|
||||||
|
gs->next->anys = gs->anys;
|
||||||
|
}
|
||||||
|
|
||||||
gs->next->bytes_alloced_since_gc += gs->bytes_alloced_since_gc;
|
gs->next->bytes_alloced_since_gc += gs->bytes_alloced_since_gc;
|
||||||
|
|
||||||
ggc_chain = gs->next;
|
ggc_chain = gs->next;
|
||||||
@ -455,6 +470,25 @@ ggc_set_mark_tree (t)
|
|||||||
return marked;
|
return marked;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Compare the pointers pointed to by A1 and A2. Used as a callback
|
||||||
|
for qsort/bsearch. */
|
||||||
|
|
||||||
|
static int
|
||||||
|
ggc_compare_addresses (a1, a2)
|
||||||
|
const void *a1;
|
||||||
|
const void *a2;
|
||||||
|
{
|
||||||
|
const char *c1 = *((const char **) a1);
|
||||||
|
const char *c2 = *((const char **) a2);
|
||||||
|
|
||||||
|
if (c1 < c2)
|
||||||
|
return -1;
|
||||||
|
else if (c1 > c2)
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ggc_mark_string (s)
|
ggc_mark_string (s)
|
||||||
char *s;
|
char *s;
|
||||||
@ -471,6 +505,21 @@ ggc_mark_string (s)
|
|||||||
gs->magic_mark = GGC_STRING_MAGIC_MARK;
|
gs->magic_mark = GGC_STRING_MAGIC_MARK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ggc_mark_string_if_gcable (s)
|
||||||
|
char *s;
|
||||||
|
{
|
||||||
|
if (s && !bsearch (&s,
|
||||||
|
&VARRAY_CHAR_PTR (ggc_allocated_strings, 0),
|
||||||
|
ggc_strings_used, sizeof (char *),
|
||||||
|
ggc_compare_addresses))
|
||||||
|
return;
|
||||||
|
|
||||||
|
ggc_mark_string (s);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Mark P, allocated with ggc_alloc. */
|
/* Mark P, allocated with ggc_alloc. */
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -513,6 +562,10 @@ ggc_collect ()
|
|||||||
|
|
||||||
time = get_run_time ();
|
time = get_run_time ();
|
||||||
|
|
||||||
|
/* Set up the table of allocated strings. */
|
||||||
|
VARRAY_CHAR_PTR_INIT (ggc_allocated_strings, 1024, "allocated strings");
|
||||||
|
ggc_strings_used = 0;
|
||||||
|
|
||||||
/* Clean out all of the GC marks. */
|
/* Clean out all of the GC marks. */
|
||||||
for (gs = ggc_chain; gs; gs = gs->next)
|
for (gs = ggc_chain; gs; gs = gs->next)
|
||||||
{
|
{
|
||||||
@ -523,13 +576,28 @@ ggc_collect ()
|
|||||||
for (t = gs->trees; t != NULL; t = t->chain)
|
for (t = gs->trees; t != NULL; t = t->chain)
|
||||||
t->tree.common.gc_mark = 0;
|
t->tree.common.gc_mark = 0;
|
||||||
for (s = gs->strings; s != NULL; s = s->chain)
|
for (s = gs->strings; s != NULL; s = s->chain)
|
||||||
s->magic_mark = GGC_STRING_MAGIC;
|
{
|
||||||
|
s->magic_mark = GGC_STRING_MAGIC;
|
||||||
|
if (ggc_strings_used == ggc_allocated_strings->num_elements)
|
||||||
|
VARRAY_GROW (ggc_allocated_strings, 2 * ggc_strings_used);
|
||||||
|
VARRAY_CHAR_PTR (ggc_allocated_strings, ggc_strings_used)
|
||||||
|
= &s->string[0];
|
||||||
|
++ggc_strings_used;
|
||||||
|
}
|
||||||
for (a = gs->anys; a != NULL; a = a->chain)
|
for (a = gs->anys; a != NULL; a = a->chain)
|
||||||
a->magic_mark = GGC_ANY_MAGIC;
|
a->magic_mark = GGC_ANY_MAGIC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Sort the allocated string table. */
|
||||||
|
qsort (&VARRAY_CHAR_PTR (ggc_allocated_strings, 0),
|
||||||
|
ggc_strings_used, sizeof (char *),
|
||||||
|
ggc_compare_addresses);
|
||||||
|
|
||||||
ggc_mark_roots ();
|
ggc_mark_roots ();
|
||||||
|
|
||||||
|
/* Free the string table. */
|
||||||
|
VARRAY_FREE (ggc_allocated_strings);
|
||||||
|
|
||||||
/* Sweep the resulting dead nodes. */
|
/* Sweep the resulting dead nodes. */
|
||||||
|
|
||||||
/* The RTXs. */
|
/* The RTXs. */
|
||||||
|
@ -66,6 +66,10 @@ extern void ggc_mark_roots PROTO((void));
|
|||||||
extern void ggc_mark_rtx_children PROTO ((struct rtx_def *));
|
extern void ggc_mark_rtx_children PROTO ((struct rtx_def *));
|
||||||
extern void ggc_mark_tree_children PROTO ((union tree_node *));
|
extern void ggc_mark_tree_children PROTO ((union tree_node *));
|
||||||
|
|
||||||
|
/* Mark the string, but only if it was allocated in collectable
|
||||||
|
memory. */
|
||||||
|
extern void ggc_mark_string_if_gcable PROTO ((char *));
|
||||||
|
|
||||||
#define ggc_mark_rtx(RTX_EXPR) \
|
#define ggc_mark_rtx(RTX_EXPR) \
|
||||||
do { \
|
do { \
|
||||||
rtx r__ = (RTX_EXPR); \
|
rtx r__ = (RTX_EXPR); \
|
||||||
@ -87,11 +91,11 @@ extern void init_ggc PROTO ((void));
|
|||||||
|
|
||||||
/* Start a new GGC context. Memory allocated in previous contexts
|
/* Start a new GGC context. Memory allocated in previous contexts
|
||||||
will not be collected while the new context is active. */
|
will not be collected while the new context is active. */
|
||||||
extern void ggc_pop_context PROTO ((void));
|
extern void ggc_push_context PROTO ((void));
|
||||||
|
|
||||||
/* Finish a GC context. Any uncollected memory in the new context
|
/* Finish a GC context. Any uncollected memory in the new context
|
||||||
will be merged with the old context. */
|
will be merged with the old context. */
|
||||||
extern void ggc_push_context PROTO ((void));
|
extern void ggc_pop_context PROTO ((void));
|
||||||
|
|
||||||
/* Allocation. */
|
/* Allocation. */
|
||||||
struct rtx_def *ggc_alloc_rtx PROTO ((int nslots));
|
struct rtx_def *ggc_alloc_rtx PROTO ((int nslots));
|
||||||
@ -113,7 +117,6 @@ int ggc_set_mark_rtx PROTO ((struct rtx_def *));
|
|||||||
int ggc_set_mark_rtvec PROTO ((struct rtvec_def *));
|
int ggc_set_mark_rtvec PROTO ((struct rtvec_def *));
|
||||||
int ggc_set_mark_tree PROTO ((union tree_node *));
|
int ggc_set_mark_tree PROTO ((union tree_node *));
|
||||||
|
|
||||||
|
|
||||||
/* Callbacks to the languages. */
|
/* Callbacks to the languages. */
|
||||||
|
|
||||||
/* This is the language's opportunity to mark nodes held through
|
/* This is the language's opportunity to mark nodes held through
|
||||||
|
Loading…
Reference in New Issue
Block a user