treat OS page manager (especially Linux) more gently

Batch up mprotect() calls when cleaning up a place. Hopefully,
this will avoid ENOMEM errors from mprotect() on DrDr's build.
This commit is contained in:
Matthew Flatt 2014-09-05 17:47:51 -06:00
parent af9e891215
commit 33e97745e9

View File

@ -5116,14 +5116,25 @@ static void free_child_gc(void)
gen0_free_big_pages(gc);
gen0_free_entire_nursery(gc);
/* First, unprotect all pages. It's important to "queue" up all this work
as a batch to minimize commuincation with the OS and avoid fragmenting
the OS's table (in the case of Linux) that tracks page permissions. */
for(i = 0; i < PAGE_TYPES; i++) {
if(i != PAGE_ATOMIC) {
for (work = gc->gen1_pages[i]; work; work = next) {
next = work->next;
if (work->mprotected) {
work->mprotected = 0;
mmu_queue_write_unprotect_range(gc->mmu, work->addr, real_page_size(work), page_mmu_type(work), &work->mmu_src_block);
}
}
}
}
mmu_flush_write_unprotect_ranges(gc->mmu);
for(i = 0; i < PAGE_TYPES; i++) {
for (work = gc->gen1_pages[i]; work; work = next) {
next = work->next;
if (work->mprotected)
{
mmu_write_unprotect_page(gc->mmu, work->addr, real_page_size(work));
}
GCVERBOSEPAGE(gc, "Cleaning up GC DYING", work);
gen1_free_mpage(pagemap, work);
}