From c30ee2656adc3ba725baf6f37461a79dda765f9d Mon Sep 17 00:00:00 2001 From: Douglas Katzman Date: Sat, 10 Dec 2016 10:44:09 -0500 Subject: [PATCH] Fix two problems in mark & sweep GC. - Fencepost bug in computing 'max_used_varyobj_page' if the final page has no object header on it (so its generation mask is 0). - Flip the order of operations in the page fault handler. In the order as it was, if GC happened in between setting the dirty bit and making a page writable, then the GC might simply clear the bit, as no write has actually occurred yet, only to resume at the system call which unprotects the page. This made a writable page not marked dirty. --- src/runtime/marknsweepgc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/runtime/marknsweepgc.c b/src/runtime/marknsweepgc.c index f40bface1..a62d8fd4b 100644 --- a/src/runtime/marknsweepgc.c +++ b/src/runtime/marknsweepgc.c @@ -1128,7 +1128,7 @@ static void compute_immobile_space_bound() for (max = (IMMOBILE_SPACE_SIZE/IMMOBILE_CARD_BYTES)-1 ; max >= FIRST_VARYOBJ_PAGE ; --max) - if (VARYOBJ_PAGE_GENS(max)) + if (varyobj_page_gens_augmented(max)) break; max_used_varyobj_page = max; // this is a page index, not the number of pages. } @@ -1376,6 +1376,8 @@ int immobile_space_handle_wp_violation(void* fault_addr) low_page_index_t page_index = find_immobile_page_index(fault_addr); if (page_index < 0) return 0; + os_protect((os_vm_address_t)((lispobj)fault_addr & ~(IMMOBILE_CARD_BYTES-1)), + IMMOBILE_CARD_BYTES, OS_VM_PROT_ALL); if (page_index >= FIRST_VARYOBJ_PAGE) { // The free pointer can move up or down. Attempting to insist that a WP // fault not occur above the free pointer (plus some slack) is not @@ -1391,8 +1393,6 @@ int immobile_space_handle_wp_violation(void* fault_addr) return 0; SET_WP_FLAG(page_index, WRITE_PROTECT_CLEARED); } - os_protect((os_vm_address_t)((lispobj)fault_addr & ~(IMMOBILE_CARD_BYTES-1)), - IMMOBILE_CARD_BYTES, OS_VM_PROT_ALL); return 1; } -- 2.11.4.GIT