diff --git a/src/runtime/gencgc.c b/src/runtime/gencgc.c index fbaaa9e..994a3ef 100644 --- a/src/runtime/gencgc.c +++ b/src/runtime/gencgc.c @@ -2669,72 +2669,77 @@ scavenge_newspace_generation(generation_index_t generation) current_new_areas_index));*/ while (current_new_areas_index > 0) { - /* Move the current to the previous new areas */ - previous_new_areas = current_new_areas; - previous_new_areas_index = current_new_areas_index; - - /* Scavenge all the areas in previous new areas. Any new areas - * allocated are saved in current_new_areas. */ - - /* Allocate an array for current_new_areas; alternating between - * new_areas_1 and 2 */ - if (previous_new_areas == &new_areas_1) - current_new_areas = &new_areas_2; - else - current_new_areas = &new_areas_1; - - /* Set up for gc_alloc(). */ - new_areas = current_new_areas; - new_areas_index = 0; - - /* Check whether previous_new_areas had overflowed. */ - if (previous_new_areas_index >= NUM_NEW_AREAS) { - - /* New areas of objects allocated have been lost so need to do a - * full scan to be sure! If this becomes a problem try - * increasing NUM_NEW_AREAS. */ - if (gencgc_verbose) { - SHOW("new_areas overflow, doing full scavenge"); - } - - /* Don't need to record new areas that get scavenged - * anyway during scavenge_newspace_generation_one_scan. */ - record_new_objects = 1; - - scavenge_newspace_generation_one_scan(generation); - - /* Record all new areas now. */ - record_new_objects = 2; - - scav_weak_hash_tables(); - - /* Flush the current regions updating the tables. */ - gc_alloc_update_all_page_tables(); - - } else { - - /* Work through previous_new_areas. */ - for (i = 0; i < previous_new_areas_index; i++) { - page_index_t page = (*previous_new_areas)[i].page; - size_t offset = (*previous_new_areas)[i].offset; - size_t size = (*previous_new_areas)[i].size / N_WORD_BYTES; - gc_assert((*previous_new_areas)[i].size % N_WORD_BYTES == 0); - scavenge(page_address(page)+offset, size); + while (current_new_areas_index > 0) { + /* Move the current to the previous new areas */ + previous_new_areas = current_new_areas; + previous_new_areas_index = current_new_areas_index; + + /* Scavenge all the areas in previous new areas. Any new areas + * allocated are saved in current_new_areas. */ + + /* Allocate an array for current_new_areas; alternating between + * new_areas_1 and 2 */ + if (previous_new_areas == &new_areas_1) + current_new_areas = &new_areas_2; + else + current_new_areas = &new_areas_1; + + /* Set up for gc_alloc(). */ + new_areas = current_new_areas; + new_areas_index = 0; + + /* Check whether previous_new_areas had overflowed. */ + if (previous_new_areas_index >= NUM_NEW_AREAS) { + + /* New areas of objects allocated have been lost so need to do a + * full scan to be sure! If this becomes a problem try + * increasing NUM_NEW_AREAS. */ + if (gencgc_verbose) { + SHOW("new_areas overflow, doing full scavenge"); + } + + /* Don't need to record new areas that get scavenged + * anyway during scavenge_newspace_generation_one_scan. */ + record_new_objects = 1; + + scavenge_newspace_generation_one_scan(generation); + + /* Record all new areas now. */ + record_new_objects = 2; + + /* Flush the current regions updating the tables. */ + gc_alloc_update_all_page_tables(); + + } else { + + /* Work through previous_new_areas. */ + for (i = 0; i < previous_new_areas_index; i++) { + page_index_t page = (*previous_new_areas)[i].page; + size_t offset = (*previous_new_areas)[i].offset; + size_t size = (*previous_new_areas)[i].size / N_WORD_BYTES; + gc_assert((*previous_new_areas)[i].size % N_WORD_BYTES == 0); + scavenge(page_address(page)+offset, size); + } + + /* Flush the current regions updating the tables. */ + gc_alloc_update_all_page_tables(); } - scav_weak_hash_tables(); - - /* Flush the current regions updating the tables. */ - gc_alloc_update_all_page_tables(); - } - - current_new_areas_index = new_areas_index; + current_new_areas_index = new_areas_index; /*FSHOW((stderr, "The re-scan has finished; current_new_areas_index=%d.\n", current_new_areas_index));*/ - } + } + scav_weak_hash_tables(); + + /* Flush the current regions updating the tables. */ + gc_alloc_update_all_page_tables(); + + current_new_areas_index = new_areas_index; + } + /* Turn off recording of areas allocated by gc_alloc(). */ record_new_objects = 0;