From: lauras AT softhome DOT net Message-ID: <20000507195832.11672.qmail@softhome.net> To: gcc-patches AT gcc DOT gnu DOT org Cc: djgpp-workers AT delorie DOT com Subject: PATCH: enabling ggc-page with simple malloc() Date: Sun, 07 May 2000 19:58:32 GMT Mime-version: 1.0 Content-type: text/plain; charset="us-ascii" Reply-To: djgpp-workers AT delorie DOT com This patch allows to use ggc-page on all systems and dramatically reduces compilation times on systems, where previously only ggc-simple was available, e.g. in bootstrap stage2 compiling toplev.c it takes down GC time from garbage collection :1032.58 (97%) usr 0.00 ( 0%) sys1032.58 (97%) wall to garbage collection : 0.10 ( 2%) usr 0.00 ( 0%) sys 0.10 ( 2%) wall Of course, it does that at the expense of some wasted memory, but it's a good tradeoff. And memory wastage could be reduced with Alexandre's code. Tested on i686-pc-msdosdjgpp. If this patch is OK, IMHO we can go further - I can provide patch for exterminating ggc-simple. [ I feel a little bit uncertain about my ChangeLog entries, please tell me if something's wrong with them. ] 2000-05-07 Laurynas Biveinis * ggc-page.c (struct page_entry): New member free_ptr. (alloc_anon): If mmap() or valloc() are not available, allocate page memory with malloc(). (alloc_page): New variable free_ptr. Initialize and use it. Align pointer to page if it was acquired with malloc(). (release_pages): If pages were allocated with malloc, pass free_ptr instead of page to free(). diff -u cvs/gcc/gcc/ggc-page.c gcc/gcc/ggc-page.c --- cvs/gcc/gcc/ggc-page.c Fri Apr 28 03:59:40 2000 +++ gcc/gcc/ggc-page.c Sun May 7 21:30:34 2000 @@ -151,6 +151,11 @@ /* The address at which the memory is allocated. */ char *page; +#ifndef HAVE_MMAP_ANYWHERE | HAVE_VALLOC + /* The address to pass for free() is simple malloc is being used. */ + char *free_ptr; +#endif + /* Saved in-use bit vector for pages that aren't in the topmost context during collection. */ unsigned long *save_in_use_p; @@ -423,12 +428,15 @@ #else #ifdef HAVE_VALLOC page = (char *) valloc (size); +#else + size += G.pagesize - 1; + page = (char *) malloc (size); +#endif if (!page) { fputs ("Virtual memory exhausted!\n", stderr); exit(1); } -#endif /* HAVE_VALLOC */ #endif /* HAVE_MMAP_ANYWHERE */ /* Remember that we allocated this memory. */ @@ -447,6 +455,9 @@ { struct page_entry *entry, *p, **pp; char *page; +#ifndef HAVE_MMAP_ANYWHERE | HAVE_VALLOC + char *free_ptr; +#endif size_t num_objects; size_t bitmap_size; size_t page_entry_size; @@ -460,6 +471,10 @@ entry = NULL; page = NULL; +#ifndef HAVE_MMAP_ANYWHERE | HAVE_VALLOC + free_ptr = NULL; +#endif + /* Check the list of free pages for one we can use. */ for (pp = &G.free_pages, p = *pp; p ; pp = &p->next, p = *pp) if (p->bytes == entry_size) @@ -470,6 +485,9 @@ /* Recycle the allocated memory from this page ... */ *pp = p->next; page = p->page; +#ifndef HAVE_MMAP_ANYWHERE | HAVE_VALLOC + free_ptr = p->free_ptr; +#endif /* ... and, if possible, the page entry itself. */ if (p->order == order) { @@ -477,18 +495,25 @@ memset (entry, 0, page_entry_size); } else - free (p); + free (p); } else { /* Actually allocate the memory. */ page = alloc_anon (NULL, entry_size); +#ifndef HAVE_MMAP_ANYWHERE | HAVE_VALLOC + free_ptr = page; + page = (char *)((size_t)(page + G.pagesize) & ~(G.pagesize - 1)); +#endif } if (entry == NULL) entry = (struct page_entry *) xcalloc (1, page_entry_size); entry->bytes = entry_size; +#ifndef HAVE_MMAP_ANYWHERE | HAVE_VALLOC + entry->free_ptr = free_ptr; +#endif entry->page = page; entry->context_depth = G.context_depth; entry->order = order; @@ -500,7 +525,7 @@ entry->in_use_p[num_objects / HOST_BITS_PER_LONG] = (unsigned long) 1 << (num_objects % HOST_BITS_PER_LONG); - set_page_table_entry (page, entry); + set_page_table_entry (entry->page, entry); if (GGC_DEBUG_LEVEL >= 2) fprintf (G.debug_file, @@ -567,17 +592,19 @@ munmap (start, len); G.bytes_mapped -= len; #else -#ifdef HAVE_VALLOC page_entry *p, *next; for (p = G.free_pages; p ; p = next) { next = p->next; +#ifdef HAVE_VALLOC free (p->page); +#else + free (p->free_ptr); +#endif G.bytes_mapped -= p->bytes; free (p); } -#endif /* HAVE_VALLOC */ #endif /* HAVE_MMAP_ANYWHERE */ G.free_pages = NULL;