From bd46c00ce6274b006d06e533cd8f2f0253ece0f8 Mon Sep 17 00:00:00 2001 From: dtc <dtc> Date: Sun, 30 Nov 1997 05:08:29 +0000 Subject: [PATCH] Improve the efficiency of gc_free_heap by having it assume free pages are zero filled and not write protected which should be the case. Make more of the consistency checks conditional and disable them all. --- lisp/gencgc.c | 115 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 73 insertions(+), 42 deletions(-) diff --git a/lisp/gencgc.c b/lisp/gencgc.c index 0157001ea..a5773e7c0 100644 --- a/lisp/gencgc.c +++ b/lisp/gencgc.c @@ -7,7 +7,7 @@ * * Douglas Crosher, 1996, 1997. * - * $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/gencgc.c,v 1.2 1997/11/29 20:32:41 dtc Exp $ + * $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/gencgc.c,v 1.3 1997/11/30 05:08:29 dtc Exp $ * */ #include <stdio.h> @@ -25,7 +25,7 @@ #define gc_abort() lose("GC invariant lost! File \"%s\", line %d\n", \ __FILE__, __LINE__) -#if 1 +#if 0 #define gc_assert(ex) do { \ if (!(ex)) gc_abort(); \ } while (0) @@ -48,18 +48,24 @@ boolean enable_page_protection = TRUE; /* Hunt for pointers to old-space, when GCing generations >= verify_gen. Set to NUM_GENERATIONS to disable. */ -int verify_gens = NUM_GENERATIONS-1; +int verify_gens = NUM_GENERATIONS; /* Enable a pre-scan verify of generation 0 before it's GCed */ boolean pre_verify_gen_0 = FALSE; +/* + * Enable checking for bad pointers after gc_free_heap called + * from purify + */ +boolean verify_after_free_heap = FALSE; + /* Enable the printing of a note when code objects are found in the dynamic space during a heap verify. */ boolean verify_dynamic_code_check = FALSE; /* Enable the checking of code objects for fixup errors after they are transported. */ -boolean check_code_fixups = TRUE; +boolean check_code_fixups = FALSE; /* To enable unmapping of a page and re-mmaping it to have it zero filled. */ @@ -73,6 +79,12 @@ boolean gencgc_unmap_zero = TRUE; /* Enable checking that newly allocated regions are zero filled. */ boolean gencgc_zero_check = FALSE; +/* + * Enable checking that free pages are zero filled during gc_free_heap + * called after purify. + */ +boolean gencgc_zero_check_during_free_heap = FALSE; + /* The minimum size for a large object. */ unsigned large_object_size = 4*4096; @@ -1778,6 +1790,9 @@ sniff_code_object(struct code *code, unsigned displacement) void *code_start_addr, *code_end_addr; int fixup_found = 0; + if (!check_code_fixups) + return; + /* It's ok if it's byte compiled code. The trace table offset will be a fixnum if it's x86 compiled code - check. */ @@ -5497,53 +5512,67 @@ collect_garbage(unsigned last_gen) have been moved to the RO and Static heaps. The dynamic space will need a full re-initialisation. I don't bother having purify flush the current gc_alloc region, as the page_tables are re-initialised, - and every page zeroed to be sure. + and every page is zeroed to be sure. */ void gc_free_heap(void) { unsigned long allocated = bytes_allocated; - int i; + int page; if (gencgc_verbose) fprintf(stderr,"Free heap\n"); - for (i = 0; i < NUM_PAGES; i++) { - void *page_start, *addr; - - /* Mark the page free. The other slots are assumed invalid when it - is a FREE_PAGE and bytes_used is 0 and it should not be write - protected - except that the generation is used for the current - region but it sets that up. */ - page_table[i].allocated = FREE_PAGE; - page_table[i].bytes_used = 0; - - /* Zero the page. */ - page_start = (void *)page_address(i); - - /* First remove any write protection */ - os_protect(page_start, 4096, OS_VM_PROT_ALL); - page_table[i].write_protected = 0; - - os_invalidate(page_start,4096); - addr = os_validate(page_start,4096); - if(addr == NULL || addr != page_start) - fprintf(stderr,"gc_zero: page moved, 0x%08x ==> 0x%08x!\n", - page_start,addr); - } - + for (page = 0; page < NUM_PAGES; page++) + /* Skip Free pages which should already be zero filled. */ + if (page_table[page].allocated != FREE_PAGE) { + void *page_start, *addr; + + /* Mark the page free. The other slots are assumed invalid when it + is a FREE_PAGE and bytes_used is 0 and it should not be write + protected - except that the generation is used for the current + region but it sets that up. */ + page_table[page].allocated = FREE_PAGE; + page_table[page].bytes_used = 0; + + /* Zero the page. */ + page_start = (void *)page_address(page); + + /* First remove any write protection */ + os_protect(page_start, 4096, OS_VM_PROT_ALL); + page_table[page].write_protected = 0; + + os_invalidate(page_start,4096); + addr = os_validate(page_start,4096); + if(addr == NULL || addr != page_start) + fprintf(stderr,"gc_zero: page moved, 0x%08x ==> 0x%08x!\n", + page_start,addr); + } else if (gencgc_zero_check_during_free_heap) { + int *page_start, i; + + /* Double check that the page is zero filled. */ + gc_assert(page_table[page].allocated == FREE_PAGE); + gc_assert(page_table[page].bytes_used == 0); + + page_start = (int *)page_address(i); + + for(i=0; i<1024; i++) + if (page_start[i] != 0) + fprintf(stderr,"** Free region not zero @ %x\n", page_start+i); + } + bytes_allocated = 0; /* Initialise the generations. */ - for (i = 0; i < NUM_GENERATIONS; i++) { - generations[i].alloc_start_page = 0; - generations[i].alloc_unboxed_start_page = 0; - generations[i].alloc_large_start_page = 0; - generations[i].alloc_large_unboxed_start_page = 0; - generations[i].bytes_allocated = 0; - generations[i].gc_trigger = 2000000; - generations[i].num_gc = 0; - generations[i].cum_sum_bytes_allocated = 0; + for (page = 0; page < NUM_GENERATIONS; page++) { + generations[page].alloc_start_page = 0; + generations[page].alloc_unboxed_start_page = 0; + generations[page].alloc_large_start_page = 0; + generations[page].alloc_large_unboxed_start_page = 0; + generations[page].bytes_allocated = 0; + generations[page].gc_trigger = 2000000; + generations[page].num_gc = 0; + generations[page].cum_sum_bytes_allocated = 0; } if (gencgc_verbose) @@ -5573,9 +5602,11 @@ gc_free_heap(void) current_region_free_pointer = boxed_region.free_pointer; current_region_end_addr = boxed_region.end_addr; - /* Check if purify has left any bad pointers. */ - fprintf(stderr,"Checking after free_heap.\n"); - verify_gc(); + if (verify_after_free_heap) { + /* Check if purify has left any bad pointers. */ + fprintf(stderr,"Checking after free_heap.\n"); + verify_gc(); + } } -- GitLab