/* "Bag-of-pages" zone garbage collector for the GNU compiler.
- Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
+ Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007
Free Software Foundation, Inc.
Contributed by Richard Henderson (rth@redhat.com) and Daniel Berlin
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, 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA. */
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
#include "config.h"
#include "system.h"
#include "params.h"
#include "bitmap.h"
-#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)
-#define VALGRIND_MALLOCLIKE_BLOCK(w,x,y,z)
-#define VALGRIND_FREELIKE_BLOCK(x,y)
-#endif
-
/* Prefer MAP_ANON(YMOUS) to /dev/zero, since we don't need to keep a
file open. Prefer either to valloc. */
#ifdef HAVE_MMAP_ANON
ggc_set_mark for any object in the garbage zone, which cuts off
marking quickly. */
-/* Stategy:
+/* Strategy:
This garbage-collecting allocator segregates objects into zones.
It also segregates objects into "large" and "small" bins. Large
}
/* Set the allocation bit corresponding to OBJECT in its page's
- bitmap. Used to split this object from the preceeding one. */
+ bitmap. Used to split this object from the preceding one. */
static inline void
zone_set_object_alloc_bit (const void *object)
{
}
/* Clear the allocation bit corresponding to OBJECT in PAGE's
- bitmap. Used to coalesce this object with the preceeding
+ bitmap. Used to coalesce this object with the preceding
one. */
static inline void
zone_clear_object_alloc_bit (struct small_page_entry *page,
/* Pretend we don't have access to the allocated pages. We'll enable
access to smaller pieces of the area in ggc_alloc. Discard the
handle to avoid handle leak. */
- VALGRIND_DISCARD (VALGRIND_MAKE_NOACCESS (page, size));
+ VALGRIND_DISCARD (VALGRIND_MAKE_MEM_NOACCESS (page, size));
return page;
}
/* Mark the page as inaccessible. Discard the handle to
avoid handle leak. */
- VALGRIND_DISCARD (VALGRIND_MAKE_NOACCESS (entry->common.page,
- SMALL_PAGE_SIZE));
+ VALGRIND_DISCARD (VALGRIND_MAKE_MEM_NOACCESS (entry->common.page,
+ SMALL_PAGE_SIZE));
entry->next = entry->common.zone->free_pages;
entry->common.zone->free_pages = entry;
if (bin > NUM_FREE_BINS)
{
bin = 0;
- VALGRIND_DISCARD (VALGRIND_MAKE_WRITABLE (chunk, sizeof (struct alloc_chunk)));
+ VALGRIND_DISCARD (VALGRIND_MAKE_MEM_UNDEFINED (chunk,
+ sizeof (struct
+ alloc_chunk)));
chunk->size = size;
chunk->next_free = zone->free_chunks[bin];
- VALGRIND_DISCARD (VALGRIND_MAKE_NOACCESS (ptr + sizeof (struct alloc_chunk),
- size - sizeof (struct alloc_chunk)));
+ VALGRIND_DISCARD (VALGRIND_MAKE_MEM_NOACCESS (ptr
+ + sizeof (struct
+ alloc_chunk),
+ size
+ - sizeof (struct
+ alloc_chunk)));
}
else
{
- VALGRIND_DISCARD (VALGRIND_MAKE_WRITABLE (chunk, sizeof (struct alloc_chunk *)));
+ VALGRIND_DISCARD (VALGRIND_MAKE_MEM_UNDEFINED (chunk,
+ sizeof (struct
+ alloc_chunk *)));
chunk->next_free = zone->free_chunks[bin];
- VALGRIND_DISCARD (VALGRIND_MAKE_NOACCESS (ptr + sizeof (struct alloc_chunk *),
- size - sizeof (struct alloc_chunk *)));
+ VALGRIND_DISCARD (VALGRIND_MAKE_MEM_NOACCESS (ptr
+ + sizeof (struct
+ alloc_chunk *),
+ size
+ - sizeof (struct
+ alloc_chunk *)));
}
zone->free_chunks[bin] = chunk;
#ifdef ENABLE_GC_CHECKING
/* `Poison' the entire allocated object. */
- VALGRIND_DISCARD (VALGRIND_MAKE_WRITABLE (result, size));
+ VALGRIND_DISCARD (VALGRIND_MAKE_MEM_UNDEFINED (result, size));
memset (result, 0xaf, size);
- VALGRIND_DISCARD (VALGRIND_MAKE_NOACCESS (result + orig_size,
- size - orig_size));
+ VALGRIND_DISCARD (VALGRIND_MAKE_MEM_NOACCESS (result + orig_size,
+ size - orig_size));
#endif
/* Tell Valgrind that the memory is there, but its content isn't
defined. The bytes at the end of the object are still marked
unaccessible. */
- VALGRIND_DISCARD (VALGRIND_MAKE_WRITABLE (result, orig_size));
+ VALGRIND_DISCARD (VALGRIND_MAKE_MEM_UNDEFINED (result, orig_size));
/* Keep track of how many bytes are being allocated. This
information is used in deciding when to collect. */
zone->allocated += size;
+
+ timevar_ggc_mem_total += size;
#ifdef GATHER_STATISTICS
ggc_record_overhead (orig_size, size - orig_size, result PASS_MEM_STAT);
switch (gte)
{
case gt_ggc_e_14lang_tree_node:
- return ggc_alloc_zone_stat (size, &tree_zone PASS_MEM_STAT);
+ return ggc_alloc_zone_pass_stat (size, &tree_zone);
case gt_ggc_e_7rtx_def:
- return ggc_alloc_zone_stat (size, &rtl_zone PASS_MEM_STAT);
+ return ggc_alloc_zone_pass_stat (size, &rtl_zone);
case gt_ggc_e_9rtvec_def:
- return ggc_alloc_zone_stat (size, &rtl_zone PASS_MEM_STAT);
+ return ggc_alloc_zone_pass_stat (size, &rtl_zone);
default:
- return ggc_alloc_zone_stat (size, &main_zone PASS_MEM_STAT);
+ return ggc_alloc_zone_pass_stat (size, &main_zone);
}
}
void *
ggc_alloc_stat (size_t size MEM_STAT_DECL)
{
- return ggc_alloc_zone_stat (size, &main_zone PASS_MEM_STAT);
+ return ggc_alloc_zone_pass_stat (size, &main_zone);
}
/* Poison the chunk. */
{
if (last_free)
{
- VALGRIND_DISCARD (VALGRIND_MAKE_WRITABLE (last_free,
- object
- - last_free));
+ VALGRIND_DISCARD (VALGRIND_MAKE_MEM_UNDEFINED (last_free,
+ object
+ - last_free));
poison_region (last_free, object - last_free);
free_chunk (last_free, object - last_free, zone);
last_free = NULL;
{
*spp = snext;
#ifdef ENABLE_GC_CHECKING
- VALGRIND_DISCARD (VALGRIND_MAKE_WRITABLE (sp->common.page, SMALL_PAGE_SIZE));
+ VALGRIND_DISCARD (VALGRIND_MAKE_MEM_UNDEFINED (sp->common.page,
+ SMALL_PAGE_SIZE));
/* Poison the page. */
memset (sp->common.page, 0xb5, SMALL_PAGE_SIZE);
#endif
}
else if (last_free)
{
- VALGRIND_DISCARD (VALGRIND_MAKE_WRITABLE (last_free,
- object - last_free));
+ VALGRIND_DISCARD (VALGRIND_MAKE_MEM_UNDEFINED (last_free,
+ object - last_free));
poison_region (last_free, object - last_free);
free_chunk (last_free, object - last_free, zone);
}
pte_overhead += PAGE_L2_SIZE * sizeof (struct page_entry *);
#else
{
- struct page_table_chain *table;
+ page_table table = G.lookup;
pte_overhead = 0;
while (table)
{