static MR_MemoryZone * MR_rewind_nondetstack_segments(MR_Word *maxfr) { MR_MemoryZone *zone_to_reuse; MR_MemoryZone *zone; MR_Word *limit; MR_MemoryZones *list; zone_to_reuse = NULL; for (;;) { zone = MR_CONTEXT(MR_ctxt_nondetstack_zone); limit = (MR_Word *) zone->MR_zone_end; if (maxfr >= zone->MR_zone_min && maxfr < limit) { break; } #ifdef MR_DEBUG_STACK_SEGMENTS printf("\nfreeing zone\n"); MR_print_zone(stdout, zone); #endif // If there are several currently unneeded segments, this algorithm // reuses the zone of the topmost segment (the first segment in the // list from the top), since its contents are more likely to have been // recently referred to, and thus more likely to be in the cache. // // However, reusing the zone of the bottom-most unneeded segment // would look conceptually a bit neater in that it would preserve // the follows/precedes relationship between the zones. if (zone_to_reuse == NULL) { zone_to_reuse = zone; } else { MR_release_zone(zone); } list = MR_CONTEXT(MR_ctxt_prev_nondetstack_zones); assert(list != NULL); MR_CONTEXT(MR_ctxt_nondetstack_zone) = list->MR_zones_head; MR_CONTEXT(MR_ctxt_prev_nondetstack_zones) = list->MR_zones_tail; MR_GC_free_attrib(list); } #ifdef MR_DEBUG_STACK_SEGMENTS if (zone_to_reuse == NULL) { printf("\nno old nondet segment zone available for reuse\n"); } else { printf("\nreturning zone of old nondet segment for reuse: %p\n", zone_to_reuse); } #endif return zone_to_reuse; }
static void MR_pop_trail_segment(void) { MR_MemoryZones *list; #if defined(MR_DEBUG_TRAIL_SEGMENTS) printf("restore old trail segment: old zone %p, old trail_ptr %p\n", MR_TRAIL_ZONE, MR_trail_ptr); #endif MR_release_zone(MR_TRAIL_ZONE); list = MR_PREV_TRAIL_ZONES; MR_TRAIL_ZONE = list->MR_zones_head; MR_PREV_TRAIL_ZONES = list->MR_zones_tail; MR_trail_ptr = (MR_TrailEntry *) MR_TRAIL_ZONE->MR_zone_end; MR_GC_free(list); #if defined(MR_DEBUG_TRAIL_SEGMENTS) printf("restore old trail segment: new zone %p, new trail_ptr %p\n", MR_TRAIL_ZONE, MR_trail_ptr); #endif }