X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fruntime%2Fgencgc.c;h=b84987bfecf74658d828cae52822fd491d650848;hb=310aee0b439b715a5ec242862ab0a4d254e123b5;hp=fd982f9c46d862347b912f0d0d055d4d89a5b3b5;hpb=18dbfbb4e0b4e8531e7dd882f3c55d51a8f38985;p=sbcl.git diff --git a/src/runtime/gencgc.c b/src/runtime/gencgc.c index fd982f9..b84987b 100644 --- a/src/runtime/gencgc.c +++ b/src/runtime/gencgc.c @@ -2675,11 +2675,9 @@ update_page_write_prot(page_index_t page) return (wp_it); } -/* Scavenge a generation. - * - * This will not resolve all pointers when generation is the new - * space, as new objects may be added which are not checked here - use - * scavenge_newspace generation. +/* Scavenge all generations from FROM to TO, inclusive, except for + * new_space which needs special handling, as new objects may be + * added which are not checked here - use scavenge_newspace generation. * * Write-protected pages should not have any pointers to the * from_space so do need scavenging; thus write-protected pages are @@ -2707,7 +2705,7 @@ update_page_write_prot(page_index_t page) * pointers as the objects contain a link to the next and are written * if a weak pointer is scavenged. Still it's a useful check. */ static void -scavenge_generation(generation_index_t generation) +scavenge_generations(generation_index_t from, generation_index_t to) { page_index_t i; int num_wp = 0; @@ -2720,9 +2718,12 @@ scavenge_generation(generation_index_t generation) #endif for (i = 0; i < last_free_page; i++) { + generation_index_t generation = page_table[i].gen; if ((page_table[i].allocated & BOXED_PAGE_FLAG) && (page_table[i].bytes_used != 0) - && (page_table[i].gen == generation)) { + && (generation != new_space) + && (generation >= from) + && (generation <= to)) { page_index_t last_page,j; int write_protected=1; @@ -2753,15 +2754,15 @@ scavenge_generation(generation_index_t generation) num_wp += update_page_write_prot(j); } } + if ((gencgc_verbose > 1) && (num_wp != 0)) { + FSHOW((stderr, + "/write protected %d pages within generation %d\n", + num_wp, generation)); + } } i = last_page; } } - if ((gencgc_verbose > 1) && (num_wp != 0)) { - FSHOW((stderr, - "/write protected %d pages within generation %d\n", - num_wp, generation)); - } #if SC_GEN_CK /* Check that none of the write_protected pages in this generation @@ -3502,26 +3503,39 @@ verify_dynamic_space(void) static void write_protect_generation_pages(generation_index_t generation) { - page_index_t i; + page_index_t start; gc_assert(generation < SCRATCH_GENERATION); - for (i = 0; i < last_free_page; i++) - if ((page_table[i].allocated == BOXED_PAGE_FLAG) - && (page_table[i].bytes_used != 0) - && !page_table[i].dont_move - && (page_table[i].gen == generation)) { + for (start = 0; start < last_free_page; start++) { + if ((page_table[start].allocated == BOXED_PAGE_FLAG) + && (page_table[start].bytes_used != 0) + && !page_table[start].dont_move + && (page_table[start].gen == generation)) { void *page_start; + page_index_t last; - page_start = (void *)page_address(i); + /* Note the page as protected in the page tables. */ + page_table[start].write_protected = 1; + + for (last = start + 1; last < last_free_page; last++) { + if ((page_table[last].allocated != BOXED_PAGE_FLAG) + || (page_table[last].bytes_used == 0) + || page_table[last].dont_move + || (page_table[last].gen != generation)) + break; + page_table[last].write_protected = 1; + } + + page_start = (void *)page_address(start); os_protect(page_start, - PAGE_BYTES, + PAGE_BYTES * (last - start), OS_VM_PROT_READ | OS_VM_PROT_EXECUTE); - /* Note the page as protected in the page tables. */ - page_table[i].write_protected = 1; + start = last; } + } if (gencgc_verbose > 1) { FSHOW((stderr, @@ -3704,11 +3718,7 @@ garbage_collect_generation(generation_index_t generation, int raise) /* All generations but the generation being GCed need to be * scavenged. The new_space generation needs special handling as * objects may be moved in - it is handled separately below. */ - for (i = 0; i <= PSEUDO_STATIC_GENERATION; i++) { - if ((i != generation) && (i != new_space)) { - scavenge_generation(i); - } - } + scavenge_generations(generation+1, PSEUDO_STATIC_GENERATION); /* Finally scavenge the new_space generation. Keep going until no * more objects are moved into the new generation */