/* Simple garbage collection for the GNU compiler.
- Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
Free Software Foundation, Inc.
This file is part of GCC.
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
+Software Foundation; either version 3, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
for more details.
You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING. If not, write to the Free
-Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301, USA. */
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
/* Generic garbage collection (GC) functions and data, not specific to
any particular GC implementation. */
# define MAP_FAILED ((void *)-1)
#endif
-#ifdef ENABLE_VALGRIND_CHECKING
-# ifdef HAVE_VALGRIND_MEMCHECK_H
-# include <valgrind/memcheck.h>
-# elif defined HAVE_MEMCHECK_H
-# include <memcheck.h>
-# else
-# include <valgrind.h>
-# endif
-#else
-/* Avoid #ifdef:s when we can help it. */
-#define VALGRIND_DISCARD(x)
-#endif
-
/* When set, ggc_collect will do collection. */
bool ggc_force_collect;
+/* When true, protect the contents of the identifier hash table. */
+bool ggc_protect_identifiers = true;
+
/* Statistics about the allocation. */
static ggc_statistics *ggc_stats;
for (i = 0; i < rti->nelt; i++)
(*rti->cb)(*(void **)((char *)rti->base + rti->stride * i));
- ggc_mark_stringpool ();
+ if (ggc_protect_identifiers)
+ ggc_mark_stringpool ();
/* Now scan all hash tables that have objects which are to be deleted if
they are not already marked. */
if (*cti->base)
{
ggc_set_mark (*cti->base);
- htab_traverse_noresize (*cti->base, ggc_htab_delete, (void *) cti);
+ htab_traverse_noresize (*cti->base, ggc_htab_delete,
+ CONST_CAST (void *, (const void *)cti));
ggc_set_mark ((*cti->base)->entries);
}
+
+ if (! ggc_protect_identifiers)
+ ggc_purge_stringpool ();
}
/* Allocate a block of memory, then clear it. */
old_size as reachable, but that would lose tracking of writes
after the end of the object (by small offsets). Discard the
handle to avoid handle leak. */
- VALGRIND_DISCARD (VALGRIND_MAKE_NOACCESS ((char *) x + size,
- old_size - size));
- VALGRIND_DISCARD (VALGRIND_MAKE_READABLE (x, size));
+ VALGRIND_DISCARD (VALGRIND_MAKE_MEM_NOACCESS ((char *) x + size,
+ old_size - size));
+ VALGRIND_DISCARD (VALGRIND_MAKE_MEM_DEFINED (x, size));
return x;
}
individually allocated object, we'd access parts of the old object
that were marked invalid with the memcpy below. We lose a bit of the
initialization-tracking since some of it may be uninitialized. */
- VALGRIND_DISCARD (VALGRIND_MAKE_READABLE (x, old_size));
+ VALGRIND_DISCARD (VALGRIND_MAKE_MEM_DEFINED (x, old_size));
memcpy (r, x, old_size);
return 0;
}
- *slot = xcalloc (sizeof (struct ptr_data), 1);
+ *slot = XCNEW (struct ptr_data);
(*slot)->obj = obj;
(*slot)->note_ptr_fn = note_ptr_fn;
(*slot)->note_ptr_cookie = note_ptr_cookie;
if (note_ptr_fn == gt_pch_p_S)
- (*slot)->size = strlen (obj) + 1;
+ (*slot)->size = strlen ((const char *)obj) + 1;
else
(*slot)->size = ggc_get_size (obj);
(*slot)->type = type;
if (obj == NULL || obj == (void *) 1)
return;
- data = htab_find_with_hash (saving_htab, obj, POINTER_HASH (obj));
+ data = (struct ptr_data *)
+ htab_find_with_hash (saving_htab, obj, POINTER_HASH (obj));
gcc_assert (data && data->note_ptr_cookie == note_ptr_cookie);
data->reorder_fn = reorder_fn;
static int
compare_ptr_data (const void *p1_p, const void *p2_p)
{
- struct ptr_data *p1 = *(struct ptr_data *const *)p1_p;
- struct ptr_data *p2 = *(struct ptr_data *const *)p2_p;
+ const struct ptr_data *const p1 = *(const struct ptr_data *const *)p1_p;
+ const struct ptr_data *const p2 = *(const struct ptr_data *const *)p2_p;
return (((size_t)p1->new_addr > (size_t)p2->new_addr)
- ((size_t)p1->new_addr < (size_t)p2->new_addr));
}
if (*ptr == NULL || *ptr == (void *)1)
return;
- result = htab_find_with_hash (saving_htab, *ptr, POINTER_HASH (*ptr));
+ result = (struct ptr_data *)
+ htab_find_with_hash (saving_htab, *ptr, POINTER_HASH (*ptr));
gcc_assert (result);
*ptr = result->new_addr;
}
}
else
{
- new_ptr = htab_find_with_hash (saving_htab, ptr,
- POINTER_HASH (ptr));
+ new_ptr = (struct ptr_data *)
+ htab_find_with_hash (saving_htab, ptr, POINTER_HASH (ptr));
if (fwrite (&new_ptr->new_addr, sizeof (void *), 1, state->f)
!= 1)
fatal_error ("can't write PCH file: %m");
if (this_object_size < state.ptrs[i]->size)
{
this_object_size = state.ptrs[i]->size;
- this_object = xrealloc (this_object, this_object_size);
+ this_object = XRESIZEVAR (char, this_object, this_object_size);
}
memcpy (this_object, state.ptrs[i]->obj, state.ptrs[i]->size);
if (state.ptrs[i]->reorder_fn != NULL)
if (ret == (void *) MAP_FAILED)
ret = NULL;
else
- munmap (ret, size);
+ munmap ((caddr_t) ret, size);
return ret;
}
if (size == 0)
return -1;
- addr = mmap (base, size, PROT_READ | PROT_WRITE, MAP_PRIVATE,
+ addr = mmap ((caddr_t) base, size, PROT_READ | PROT_WRITE, MAP_PRIVATE,
fd, offset);
return addr == base ? 1 : -1;
static hashval_t
hash_descriptor (const void *p)
{
- const struct loc_descriptor *d = p;
+ const struct loc_descriptor *const d = (const struct loc_descriptor *) p;
return htab_hash_pointer (d->function) | d->line;
}
static int
eq_descriptor (const void *p1, const void *p2)
{
- const struct loc_descriptor *d = p1;
- const struct loc_descriptor *d2 = p2;
+ const struct loc_descriptor *const d = (const struct loc_descriptor *) p1;
+ const struct loc_descriptor *const d2 = (const struct loc_descriptor *) p2;
return (d->file == d2->file && d->line == d2->line
&& d->function == d2->function);
static hashval_t
hash_ptr (const void *p)
{
- const struct ptr_hash_entry *d = p;
+ const struct ptr_hash_entry *const d = (const struct ptr_hash_entry *) p;
return htab_hash_pointer (d->ptr);
}
static int
eq_ptr (const void *p1, const void *p2)
{
- const struct ptr_hash_entry *p = p1;
+ const struct ptr_hash_entry *const p = (const struct ptr_hash_entry *) p1;
return (p->ptr == p2);
}
slot = (struct loc_descriptor **) htab_find_slot (loc_hash, &loc, 1);
if (*slot)
return *slot;
- *slot = xcalloc (sizeof (**slot), 1);
+ *slot = XCNEW (struct loc_descriptor);
(*slot)->file = name;
(*slot)->line = line;
(*slot)->function = function;
static int
ggc_prune_ptr (void **slot, void *b ATTRIBUTE_UNUSED)
{
- struct ptr_hash_entry *p = *slot;
+ struct ptr_hash_entry *p = (struct ptr_hash_entry *) *slot;
if (!ggc_marked_p (p->ptr))
{
p->loc->collected += p->size;
{
PTR *slot = htab_find_slot_with_hash (ptr_hash, ptr, htab_hash_pointer (ptr),
NO_INSERT);
- struct ptr_hash_entry *p = *slot;
+ struct ptr_hash_entry *p = (struct ptr_hash_entry *) *slot;
p->loc->freed += p->size;
htab_clear_slot (ptr_hash, slot);
free (p);
static int
final_cmp_statistic (const void *loc1, const void *loc2)
{
- struct loc_descriptor *l1 = *(struct loc_descriptor **) loc1;
- struct loc_descriptor *l2 = *(struct loc_descriptor **) loc2;
+ const struct loc_descriptor *const l1 =
+ *(const struct loc_descriptor *const *) loc1;
+ const struct loc_descriptor *const l2 =
+ *(const struct loc_descriptor *const *) loc2;
long diff;
diff = ((long)(l1->allocated + l1->overhead - l1->freed) -
(l2->allocated + l2->overhead - l2->freed));
static int
cmp_statistic (const void *loc1, const void *loc2)
{
- struct loc_descriptor *l1 = *(struct loc_descriptor **) loc1;
- struct loc_descriptor *l2 = *(struct loc_descriptor **) loc2;
+ const struct loc_descriptor *const l1 =
+ *(const struct loc_descriptor *const *) loc1;
+ const struct loc_descriptor *const l2 =
+ *(const struct loc_descriptor *const *) loc2;
long diff;
diff = ((long)(l1->allocated + l1->overhead - l1->freed - l1->collected) -
ggc_force_collect = true;
ggc_collect ();
- loc_array = xcalloc (sizeof (*loc_array), loc_hash->n_elements);
+ loc_array = XCNEWVEC (struct loc_descriptor *, loc_hash->n_elements);
fprintf (stderr, "-------------------------------------------------------\n");
fprintf (stderr, "\n%-48s %10s %10s %10s %10s %10s\n",
"source location", "Garbage", "Freed", "Leak", "Overhead", "Times");
fprintf (stderr, "%-48s %10s %10s %10s %10s %10s\n",
"source location", "Garbage", "Freed", "Leak", "Overhead", "Times");
fprintf (stderr, "-------------------------------------------------------\n");
+ ggc_force_collect = false;
#endif
}