diff options
Diffstat (limited to 'gcc/ggc-page.c')
-rw-r--r-- | gcc/ggc-page.c | 53 |
1 files changed, 52 insertions, 1 deletions
diff --git a/gcc/ggc-page.c b/gcc/ggc-page.c index ea637b1b63c..f22ddf6e826 100644 --- a/gcc/ggc-page.c +++ b/gcc/ggc-page.c @@ -1,5 +1,5 @@ /* "Bag-of-pages" garbage collector for the GNU compiler. - Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007 + Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008 Free Software Foundation, Inc. This file is part of GCC. @@ -1256,6 +1256,57 @@ ggc_alloc_stat (size_t size MEM_STAT_DECL) return result; } +/* Mark function for strings. */ + +void +gt_ggc_m_S (const void *p) +{ + page_entry *entry; + unsigned bit, word; + unsigned long mask; + unsigned long offset; + + if (!p || !ggc_allocated_p (p)) + return; + + /* Look up the page on which the object is alloced. . */ + entry = lookup_page_table_entry (p); + gcc_assert (entry); + + /* Calculate the index of the object on the page; this is its bit + position in the in_use_p bitmap. Note that because a char* might + point to the middle of an object, we need special code here to + make sure P points to the start of an object. */ + offset = ((const char *) p - entry->page) % object_size_table[entry->order]; + if (offset) + { + /* Here we've seen a char* which does not point to the beginning + of an allocated object. We assume it points to the middle of + a STRING_CST. */ + gcc_assert (offset == offsetof (struct tree_string, str)); + p = ((const char *) p) - offset; + gt_ggc_mx_lang_tree_node ((void *) p); + return; + } + + bit = OFFSET_TO_BIT (((const char *) p) - entry->page, entry->order); + word = bit / HOST_BITS_PER_LONG; + mask = (unsigned long) 1 << (bit % HOST_BITS_PER_LONG); + + /* If the bit was previously set, skip it. */ + if (entry->in_use_p[word] & mask) + return; + + /* Otherwise set it, and decrement the free object count. */ + entry->in_use_p[word] |= mask; + entry->num_free_objects -= 1; + + if (GGC_DEBUG_LEVEL >= 4) + fprintf (G.debug_file, "Marking %p\n", p); + + return; +} + /* If P is not marked, marks it and return false. Otherwise return true. P must have been allocated by the GC allocator; it mustn't point to static objects, stack variables, or memory allocated with malloc. */ |