/* "Bag-of-pages" garbage collector for the GNU compiler.
Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
#include "config.h"
#include "system.h"
1: GC statistics only.
2: Page-entry allocations/deallocations as well.
3: Object allocations as well.
- 4: Object marks as well. */
+ 4: Object marks as well. */
#define GGC_DEBUG_LEVEL (0)
\f
#ifndef HOST_BITS_PER_PTR
free list. This cannot be larger than HOST_BITS_PER_INT for the
in_use bitmask for page_group. */
#define GGC_QUIRE_SIZE 16
-
\f
static int ggc_allocated_p PARAMS ((const void *));
static page_entry *lookup_page_table_entry PARAMS ((const void *));
if (page == (char *) MAP_FAILED)
{
- fputs ("Virtual memory exhausted!\n", stderr);
- exit(1);
+ perror ("Virtual memory exhausted");
+ exit (FATAL_EXIT_CODE);
}
/* Remember that we allocated this memory. */
page = NULL;
/* Check the list of free pages for one we can use. */
- for (pp = &G.free_pages, p = *pp; p ; pp = &p->next, p = *pp)
+ for (pp = &G.free_pages, p = *pp; p; pp = &p->next, p = *pp)
if (p->bytes == entry_size)
break;
if (p != NULL)
{
- /* Recycle the allocated memory from this page ... */
+ /* Recycle the allocated memory from this page ... */
*pp = p->next;
page = p->page;
+
#ifdef USING_MALLOC_PAGE_GROUPS
group = p->group;
#endif
+
/* ... and, if possible, the page entry itself. */
if (p->order == order)
{
int i;
page = alloc_anon (NULL, G.pagesize * GGC_QUIRE_SIZE);
+
/* This loop counts down so that the chain will be in ascending
memory order. */
for (i = GGC_QUIRE_SIZE - 1; i >= 1; i--)
e->next = f;
f = e;
}
+
G.free_pages = f;
}
else
if (GGC_DEBUG_LEVEL >= 2)
fprintf (G.debug_file,
- "Allocating page at %p, object size=%d, data %p-%p\n",
- (PTR) entry, OBJECT_SIZE (order), page, page + entry_size - 1);
+ "Allocating page at %p, object size=%ld, data %p-%p\n",
+ (PTR) entry, (long) OBJECT_SIZE (order), page,
+ page + entry_size - 1);
return entry;
}
}
/* 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 eight bytes. */
static unsigned char size_lookup[257] =
-{
- 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4,
+{
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4,
4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
if (GGC_DEBUG_LEVEL >= 3)
fprintf (G.debug_file,
- "Allocating object, requested size=%d, actual=%d at %p on %p\n",
- (int) size, OBJECT_SIZE (order), result, (PTR) entry);
+ "Allocating object, requested size=%ld, actual=%ld at %p on %p\n",
+ (long) size, (long) OBJECT_SIZE (order), result, (PTR) entry);
return result;
}
word = bit / HOST_BITS_PER_LONG;
mask = (unsigned long) 1 << (bit % HOST_BITS_PER_LONG);
- /* If the bit was previously set, skip it. */
+ /* If the bit was previously set, skip it. */
if (entry->in_use_p[word] & mask)
return 1;
return 0;
}
-/* Mark P, but check first that it was allocated by the collector. */
+/* Return 1 if P has been marked, zero otherwise.
+ P must have been allocated by the GC allocator; it mustn't point to
+ static objects, stack variables, or memory allocated with malloc. */
-void
-ggc_mark_if_gcable (p)
+int
+ggc_marked_p (p)
const void *p;
{
- if (p && ggc_allocated_p (p))
- ggc_set_mark (p);
+ page_entry *entry;
+ unsigned bit, word;
+ unsigned long mask;
+
+ /* Look up the page on which the object is alloced. If the object
+ wasn't allocated by the collector, we'll probably die. */
+ entry = lookup_page_table_entry (p);
+#ifdef ENABLE_CHECKING
+ if (entry == NULL)
+ abort ();
+#endif
+
+ /* Calculate the index of the object on the page; this is its bit
+ position in the in_use_p bitmap. */
+ bit = (((const char *) p) - entry->page) / OBJECT_SIZE (entry->order);
+ word = bit / HOST_BITS_PER_LONG;
+ mask = (unsigned long) 1 << (bit % HOST_BITS_PER_LONG);
+
+ return (entry->in_use_p[word] & mask) != 0;
}
/* Return the size of the gc-able object P. */
abort ();
}
- /* We have a good page, might as well hold onto it... */
+ /* We have a good page, might as well hold onto it... */
e = (struct page_entry *) xcalloc (1, sizeof (struct page_entry));
e->bytes = G.pagesize;
e->page = p;
/* Collect some information about the various sizes of
allocation. */
fprintf (stderr, "\n%-5s %10s %10s %10s\n",
- "Log", "Allocated", "Used", "Overhead");
+ "Size", "Allocated", "Used", "Overhead");
for (i = 0; i < NUM_ORDERS; ++i)
{
page_entry *p;
overhead += (sizeof (page_entry) - sizeof (long)
+ BITMAP_SIZE (OBJECTS_PER_PAGE (i) + 1));
}
- fprintf (stderr, "%-5d %10ld%c %10ld%c %10ld%c\n", i,
+ fprintf (stderr, "%-5d %10ld%c %10ld%c %10ld%c\n", OBJECT_SIZE (i),
SCALE (allocated), LABEL (allocated),
SCALE (in_use), LABEL (in_use),
SCALE (overhead), LABEL (overhead));