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:
parent
af9e891215
commit
33e97745e9
|
@ -5116,14 +5116,25 @@ static void free_child_gc(void)
|
||||||
gen0_free_big_pages(gc);
|
gen0_free_big_pages(gc);
|
||||||
gen0_free_entire_nursery(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(i = 0; i < PAGE_TYPES; i++) {
|
||||||
for (work = gc->gen1_pages[i]; work; work = next) {
|
for (work = gc->gen1_pages[i]; work; work = next) {
|
||||||
next = 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);
|
GCVERBOSEPAGE(gc, "Cleaning up GC DYING", work);
|
||||||
gen1_free_mpage(pagemap, work);
|
gen1_free_mpage(pagemap, work);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user