Commit cb2ec151 by Richard Henderson Committed by Richard Henderson

ggc-common.c: Update pre-function commentary.

	* ggc-common.c: Update pre-function commentary.
	* ggc-page.c: Likewise.
	(poison): Remove.
	(poison_pages): Use memset directly.
	(ggc_alloc_obj): Likewise.  Use a different pattern than poison_pages.
	(ggc_collect): Poison before sweeping.
	* ggc-simple.c: Update pre-function commentary.
	(ggc_alloc_obj): Poison non-zeroed memory.

From-SVN: r30275
parent e225758a
Sat Oct 30 14:31:48 1999 Richard Henderson <rth@cygnus.com>
* ggc-common.c: Update pre-function commentary.
* ggc-page.c: Likewise.
(poison): Remove.
(poison_pages): Use memset directly.
(ggc_alloc_obj): Likewise. Use a different pattern than poison_pages.
(ggc_collect): Poison before sweeping.
* ggc-simple.c: Update pre-function commentary.
(ggc_alloc_obj): Poison non-zeroed memory.
Sat Oct 30 14:28:52 1999 Mark Mitchell <mark@codesourcery.com> Sat Oct 30 14:28:52 1999 Mark Mitchell <mark@codesourcery.com>
* ggc-common.c (ggc_print_statistics): Make arguments to fprintf * ggc-common.c (ggc_print_statistics): Make arguments to fprintf
......
...@@ -97,6 +97,9 @@ ggc_mark_tree_hash_table_ptr (elt) ...@@ -97,6 +97,9 @@ ggc_mark_tree_hash_table_ptr (elt)
ggc_mark_tree_hash_table (*(struct hash_table **) elt); ggc_mark_tree_hash_table (*(struct hash_table **) elt);
} }
/* Type-correct function to pass to ggc_add_root. It just forwards
ELT (which is really a char **) to ggc_mark_string. */
static void static void
ggc_mark_string_ptr (elt) ggc_mark_string_ptr (elt)
void *elt; void *elt;
...@@ -104,6 +107,12 @@ ggc_mark_string_ptr (elt) ...@@ -104,6 +107,12 @@ ggc_mark_string_ptr (elt)
ggc_mark_string (*(char **)elt); ggc_mark_string (*(char **)elt);
} }
/* Add BASE as a new garbage collection root. It is an array of
length NELT with each element SIZE bytes long. CB is a
function that will be called with a pointer to each element
of the array; it is the intention that CB call the appropriate
routine to mark gc-able memory for that element. */
void void
ggc_add_root (base, nelt, size, cb) ggc_add_root (base, nelt, size, cb)
void *base; void *base;
...@@ -121,6 +130,8 @@ ggc_add_root (base, nelt, size, cb) ...@@ -121,6 +130,8 @@ ggc_add_root (base, nelt, size, cb)
roots = x; roots = x;
} }
/* Register an array of rtx as a GC root. */
void void
ggc_add_rtx_root (base, nelt) ggc_add_rtx_root (base, nelt)
rtx *base; rtx *base;
...@@ -129,6 +140,8 @@ ggc_add_rtx_root (base, nelt) ...@@ -129,6 +140,8 @@ ggc_add_rtx_root (base, nelt)
ggc_add_root (base, nelt, sizeof(rtx), ggc_mark_rtx_ptr); ggc_add_root (base, nelt, sizeof(rtx), ggc_mark_rtx_ptr);
} }
/* Register an array of trees as a GC root. */
void void
ggc_add_tree_root (base, nelt) ggc_add_tree_root (base, nelt)
tree *base; tree *base;
...@@ -137,7 +150,7 @@ ggc_add_tree_root (base, nelt) ...@@ -137,7 +150,7 @@ ggc_add_tree_root (base, nelt)
ggc_add_root (base, nelt, sizeof(tree), ggc_mark_tree_ptr); ggc_add_root (base, nelt, sizeof(tree), ggc_mark_tree_ptr);
} }
/* Add V (a varray full of trees) to the list of GC roots. */ /* Register a varray of trees as a GC root. */
void void
ggc_add_tree_varray_root (base, nelt) ggc_add_tree_varray_root (base, nelt)
...@@ -148,8 +161,7 @@ ggc_add_tree_varray_root (base, nelt) ...@@ -148,8 +161,7 @@ ggc_add_tree_varray_root (base, nelt)
ggc_mark_tree_varray_ptr); ggc_mark_tree_varray_ptr);
} }
/* Add HT (a hash-table where ever key is a tree) to the list of GC /* Register a hash table of trees as a GC root. */
roots. */
void void
ggc_add_tree_hash_table_root (base, nelt) ggc_add_tree_hash_table_root (base, nelt)
...@@ -160,6 +172,8 @@ ggc_add_tree_hash_table_root (base, nelt) ...@@ -160,6 +172,8 @@ ggc_add_tree_hash_table_root (base, nelt)
ggc_mark_tree_hash_table_ptr); ggc_mark_tree_hash_table_ptr);
} }
/* Register an array of strings as a GC root. */
void void
ggc_add_string_root (base, nelt) ggc_add_string_root (base, nelt)
char **base; char **base;
...@@ -168,6 +182,7 @@ ggc_add_string_root (base, nelt) ...@@ -168,6 +182,7 @@ ggc_add_string_root (base, nelt)
ggc_add_root (base, nelt, sizeof (char *), ggc_mark_string_ptr); ggc_add_root (base, nelt, sizeof (char *), ggc_mark_string_ptr);
} }
/* Remove the previously registered GC root at BASE. */
void void
ggc_del_root (base) ggc_del_root (base)
...@@ -191,6 +206,8 @@ ggc_del_root (base) ...@@ -191,6 +206,8 @@ ggc_del_root (base)
abort(); abort();
} }
/* Iterate through all registered roots and mark each element. */
void void
ggc_mark_roots () ggc_mark_roots ()
{ {
...@@ -208,6 +225,9 @@ ggc_mark_roots () ...@@ -208,6 +225,9 @@ ggc_mark_roots ()
} }
} }
/* R had not been previously marked, but has now been marked via
ggc_set_mark. Now recurse and process the children. */
void void
ggc_mark_rtx_children (r) ggc_mark_rtx_children (r)
rtx r; rtx r;
...@@ -285,6 +305,9 @@ ggc_mark_rtx_children (r) ...@@ -285,6 +305,9 @@ ggc_mark_rtx_children (r)
} }
} }
/* V had not been previously marked, but has now been marked via
ggc_set_mark. Now recurse and process the children. */
void void
ggc_mark_rtvec_children (v) ggc_mark_rtvec_children (v)
rtvec v; rtvec v;
...@@ -296,6 +319,9 @@ ggc_mark_rtvec_children (v) ...@@ -296,6 +319,9 @@ ggc_mark_rtvec_children (v)
ggc_mark_rtx (RTVEC_ELT (v, i)); ggc_mark_rtx (RTVEC_ELT (v, i));
} }
/* T had not been previously marked, but has now been marked via
ggc_set_mark. Now recurse and process the children. */
void void
ggc_mark_tree_children (t) ggc_mark_tree_children (t)
tree t; tree t;
...@@ -466,7 +492,10 @@ ggc_mark_tree_hash_table (ht) ...@@ -466,7 +492,10 @@ ggc_mark_tree_hash_table (ht)
hash_traverse (ht, ggc_mark_tree_hash_table_entry, /*info=*/0); hash_traverse (ht, ggc_mark_tree_hash_table_entry, /*info=*/0);
} }
/* Allocation wrappers. */ /* Allocate a gc-able string. If CONTENTS is null, then the memory will
be uninitialized. If LENGTH is -1, then CONTENTS is assumed to be a
null-terminated string and the memory sized accordingly. Otherwise,
the memory is filled with LENGTH bytes from CONTENTS. */
char * char *
ggc_alloc_string (contents, length) ggc_alloc_string (contents, length)
......
...@@ -281,7 +281,6 @@ static void clear_marks PROTO ((void)); ...@@ -281,7 +281,6 @@ static void clear_marks PROTO ((void));
static void sweep_pages PROTO ((void)); static void sweep_pages PROTO ((void));
#ifdef GGC_POISON #ifdef GGC_POISON
static void poison PROTO ((void *, size_t));
static void poison_pages PROTO ((void)); static void poison_pages PROTO ((void));
#endif #endif
...@@ -346,8 +345,8 @@ lookup_page_table_entry(p) ...@@ -346,8 +345,8 @@ lookup_page_table_entry(p)
return base[L1][L2]; return base[L1][L2];
} }
/* Set the page table entry for a page. */ /* Set the page table entry for a page. */
static void static void
set_page_table_entry(p, entry) set_page_table_entry(p, entry)
void *p; void *p;
...@@ -384,8 +383,8 @@ found: ...@@ -384,8 +383,8 @@ found:
base[L1][L2] = entry; base[L1][L2] = entry;
} }
/* Prints the page-entry for object size ORDER, for debugging. */ /* Prints the page-entry for object size ORDER, for debugging. */
void void
debug_print_page_list (order) debug_print_page_list (order)
int order; int order;
...@@ -402,20 +401,9 @@ debug_print_page_list (order) ...@@ -402,20 +401,9 @@ debug_print_page_list (order)
fflush (stdout); fflush (stdout);
} }
#ifdef GGC_POISON
/* `Poisons' the region of memory starting at START and extending for
LEN bytes. */
static inline void
poison (start, len)
void *start;
size_t len;
{
memset (start, 0xa5, len);
}
#endif
/* Allocate SIZE bytes of anonymous memory, preferably near PREF, /* Allocate SIZE bytes of anonymous memory, preferably near PREF,
(if non-null). */ (if non-null). */
static inline char * static inline char *
alloc_anon (pref, size) alloc_anon (pref, size)
char *pref ATTRIBUTE_UNUSED; char *pref ATTRIBUTE_UNUSED;
...@@ -456,6 +444,7 @@ alloc_anon (pref, size) ...@@ -456,6 +444,7 @@ alloc_anon (pref, size)
/* Allocate a new page for allocating objects of size 2^ORDER, /* Allocate a new page for allocating objects of size 2^ORDER,
and return an entry for it. The entry is not added to the and return an entry for it. The entry is not added to the
appropriate page_table list. */ appropriate page_table list. */
static inline struct page_entry * static inline struct page_entry *
alloc_page (order) alloc_page (order)
unsigned order; unsigned order;
...@@ -496,7 +485,7 @@ alloc_page (order) ...@@ -496,7 +485,7 @@ alloc_page (order)
} }
else else
{ {
/* Actually allocate the memory, using mmap. */ /* Actually allocate the memory. */
page = alloc_anon (NULL, entry_size); page = alloc_anon (NULL, entry_size);
} }
...@@ -525,8 +514,8 @@ alloc_page (order) ...@@ -525,8 +514,8 @@ alloc_page (order)
return entry; return entry;
} }
/* For a page that is no longer needed, put it on the free page list. */
/* Free a page when it's no longer needed. */
static inline void static inline void
free_page (entry) free_page (entry)
page_entry *entry; page_entry *entry;
...@@ -542,8 +531,8 @@ free_page (entry) ...@@ -542,8 +531,8 @@ free_page (entry)
G.free_pages = entry; G.free_pages = entry;
} }
/* Release the free page cache to the system. */
/* Release the page cache to the system. */
static inline void static inline void
release_pages () release_pages ()
{ {
...@@ -598,9 +587,9 @@ release_pages () ...@@ -598,9 +587,9 @@ release_pages ()
G.free_pages = NULL; G.free_pages = NULL;
} }
/* This table provides a fast way to determine ceil(log_2(size)) for /* This table provides a fast way to determine ceil(log_2(size)) for
allocation requests. The minimum allocation size is four bytes. */ allocation requests. The minimum allocation size is four bytes. */
static unsigned char const size_lookup[257] = static unsigned char const size_lookup[257] =
{ {
2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4,
...@@ -624,6 +613,7 @@ static unsigned char const size_lookup[257] = ...@@ -624,6 +613,7 @@ static unsigned char const size_lookup[257] =
/* Allocate a chunk of memory of SIZE bytes. If ZERO is non-zero, the /* Allocate a chunk of memory of SIZE bytes. If ZERO is non-zero, the
memory is zeroed; otherwise, its contents are undefined. */ memory is zeroed; otherwise, its contents are undefined. */
void * void *
ggc_alloc_obj (size, zero) ggc_alloc_obj (size, zero)
size_t size; size_t size;
...@@ -721,8 +711,9 @@ ggc_alloc_obj (size, zero) ...@@ -721,8 +711,9 @@ ggc_alloc_obj (size, zero)
#ifdef GGC_POISON #ifdef GGC_POISON
/* `Poison' the entire allocated object before zeroing the requested area, /* `Poison' the entire allocated object before zeroing the requested area,
so that bytes beyond the end, if any, will not necessarily be zero. */ so that bytes beyond the end, if any, will not necessarily be zero. */
poison (result, 1 << order); memset (result, 0xaf, 1 << order);
#endif #endif
if (zero) if (zero)
memset (result, 0, size); memset (result, 0, size);
...@@ -738,10 +729,10 @@ ggc_alloc_obj (size, zero) ...@@ -738,10 +729,10 @@ ggc_alloc_obj (size, zero)
return result; return result;
} }
/* If P is not marked, marks it and return false. Otherwise return true.
/* If P is not marked, marks it and returns 0. Otherwise returns 1.
P must have been allocated by the GC allocator; it mustn't point to P must have been allocated by the GC allocator; it mustn't point to
static objects, stack variables, or memory allocated with malloc. */ static objects, stack variables, or memory allocated with malloc. */
int int
ggc_set_mark (p) ggc_set_mark (p)
void *p; void *p;
...@@ -780,6 +771,8 @@ ggc_set_mark (p) ...@@ -780,6 +771,8 @@ ggc_set_mark (p)
return 0; return 0;
} }
/* Mark P, but check first that it was allocated by the collector. */
void void
ggc_mark_if_gcable (p) ggc_mark_if_gcable (p)
void *p; void *p;
...@@ -788,6 +781,8 @@ ggc_mark_if_gcable (p) ...@@ -788,6 +781,8 @@ ggc_mark_if_gcable (p)
ggc_set_mark (p); ggc_set_mark (p);
} }
/* Return the size of the gc-able object P. */
size_t size_t
ggc_get_size (p) ggc_get_size (p)
void *p; void *p;
...@@ -797,6 +792,7 @@ ggc_get_size (p) ...@@ -797,6 +792,7 @@ ggc_get_size (p)
} }
/* Initialize the ggc-mmap allocator. */ /* Initialize the ggc-mmap allocator. */
void void
init_ggc () init_ggc ()
{ {
...@@ -841,6 +837,8 @@ init_ggc () ...@@ -841,6 +837,8 @@ init_ggc ()
ggc_add_string_root (&empty_string, 1); ggc_add_string_root (&empty_string, 1);
} }
/* Increment the `GC context'. Objects allocated in an outer context
are never freed, eliminating the need to register their roots. */
void void
ggc_push_context () ggc_push_context ()
...@@ -852,6 +850,8 @@ ggc_push_context () ...@@ -852,6 +850,8 @@ ggc_push_context ()
abort (); abort ();
} }
/* Decrement the `GC context'. All objects allocated since the
previous ggc_push_context are migrated to the outer context. */
void void
ggc_pop_context () ggc_pop_context ()
...@@ -890,6 +890,8 @@ ggc_pop_context () ...@@ -890,6 +890,8 @@ ggc_pop_context ()
} }
} }
/* Unmark all objects. */
static inline void static inline void
clear_marks () clear_marks ()
{ {
...@@ -932,6 +934,9 @@ clear_marks () ...@@ -932,6 +934,9 @@ clear_marks ()
} }
} }
/* Free all empty pages. Partially empty pages need no attention
because the `mark' bit doubles as an `unused' bit. */
static inline void static inline void
sweep_pages () sweep_pages ()
{ {
...@@ -1024,6 +1029,8 @@ sweep_pages () ...@@ -1024,6 +1029,8 @@ sweep_pages ()
} }
#ifdef GGC_POISON #ifdef GGC_POISON
/* Clobber all free objects. */
static inline void static inline void
poison_pages () poison_pages ()
{ {
...@@ -1052,13 +1059,15 @@ poison_pages () ...@@ -1052,13 +1059,15 @@ poison_pages ()
word = i / HOST_BITS_PER_LONG; word = i / HOST_BITS_PER_LONG;
bit = i % HOST_BITS_PER_LONG; bit = i % HOST_BITS_PER_LONG;
if (((p->in_use_p[word] >> bit) & 1) == 0) if (((p->in_use_p[word] >> bit) & 1) == 0)
poison (p->page + i * size, size); memset (p->page + i * size, 0xa5, size);
} }
} }
} }
} }
#endif #endif
/* Top level mark-and-sweep routine. */
void void
ggc_collect () ggc_collect ()
{ {
...@@ -1086,12 +1095,13 @@ ggc_collect () ...@@ -1086,12 +1095,13 @@ ggc_collect ()
clear_marks (); clear_marks ();
ggc_mark_roots (); ggc_mark_roots ();
sweep_pages ();
#ifdef GGC_POISON #ifdef GGC_POISON
poison_pages (); poison_pages ();
#endif #endif
sweep_pages ();
G.allocated_last_gc = G.allocated; G.allocated_last_gc = G.allocated;
if (G.allocated_last_gc < GGC_MIN_LAST_ALLOCATED) if (G.allocated_last_gc < GGC_MIN_LAST_ALLOCATED)
G.allocated_last_gc = GGC_MIN_LAST_ALLOCATED; G.allocated_last_gc = GGC_MIN_LAST_ALLOCATED;
......
...@@ -200,6 +200,10 @@ ggc_alloc_obj (size, zero) ...@@ -200,6 +200,10 @@ ggc_alloc_obj (size, zero)
if (zero) if (zero)
memset (&x->u, 0, size); memset (&x->u, 0, size);
#ifdef GGC_POISON
else
memset (&x->u, 0xaf, size);
#endif
tree_insert (x); tree_insert (x);
G.allocated += size; G.allocated += size;
...@@ -232,6 +236,8 @@ ggc_set_mark (p) ...@@ -232,6 +236,8 @@ ggc_set_mark (p)
return 0; return 0;
} }
/* Mark a node, but check first to see that it's really gc-able memory. */
void void
ggc_mark_if_gcable (p) ggc_mark_if_gcable (p)
void *p; void *p;
...@@ -253,6 +259,8 @@ ggc_mark_if_gcable (p) ...@@ -253,6 +259,8 @@ ggc_mark_if_gcable (p)
G.objects += 1; G.objects += 1;
} }
/* Return the size of the gc-able object P. */
size_t size_t
ggc_get_size (p) ggc_get_size (p)
void *p; void *p;
...@@ -262,6 +270,8 @@ ggc_get_size (p) ...@@ -262,6 +270,8 @@ ggc_get_size (p)
return x->size; return x->size;
} }
/* Unmark all objects. */
static void static void
clear_marks (x) clear_marks (x)
struct ggc_mem *x; struct ggc_mem *x;
...@@ -273,6 +283,8 @@ clear_marks (x) ...@@ -273,6 +283,8 @@ clear_marks (x)
clear_marks (x->sub[1]); clear_marks (x->sub[1]);
} }
/* Free all objects in the current context that are not marked. */
static void static void
sweep_objs (root) sweep_objs (root)
struct ggc_mem **root; struct ggc_mem **root;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment