Beispiel #1
0
void
MR_new_trail_segment(void)
{

    MR_MemoryZones  *list;
    MR_MemoryZone   *new_zone;
    MR_TrailEntry   *old_trail_ptr;

    old_trail_ptr = MR_trail_ptr;

    /*
    ** We perform explicit overflow checks so redzones just waste space.
    */
    new_zone = MR_create_or_reuse_zone("trail_segment", MR_trail_size, 0,
        0, MR_default_handler);

    list = MR_GC_malloc_uncollectable_attrib(sizeof(MR_MemoryZones),
        MR_ALLOC_SITE_RUNTIME);

#if defined(MR_DEBUG_TRAIL_SEGMENTS)
    printf("create new trail segment: old zone: %p, old trail_ptr %p\n",
        MR_TRAIL_ZONE, MR_trail_ptr);
#endif

    list->MR_zones_head = MR_TRAIL_ZONE;
    list->MR_zones_tail = MR_PREV_TRAIL_ZONES;
    MR_PREV_TRAIL_ZONES = list;
    MR_TRAIL_ZONE = new_zone;
    MR_trail_ptr = (MR_TrailEntry *) MR_TRAIL_ZONE->MR_zone_min;

#if defined(MR_DEBUG_TRAIL_SEGMENTS)
    printf("create new trail segment: new zone: %p, new trail_ptr %p\n",
        MR_TRAIL_ZONE, MR_trail_ptr);
#endif
}
Beispiel #2
0
MR_Word *
MR_new_detstack_segment(MR_Word *sp, int n)
{
    MR_Word         *old_sp;
    MR_MemoryZones  *list;
    MR_MemoryZone   *new_zone;

    old_sp = sp;

    // We perform explicit overflow checks so redzones just waste space.
    new_zone = MR_create_or_reuse_zone("detstack_segment",
        MR_detstack_size, 0, 0, MR_default_handler);

    list = MR_GC_malloc_uncollectable_attrib(sizeof(MR_MemoryZones),
        MR_ALLOC_SITE_RUNTIME);

#ifdef  MR_DEBUG_STACK_SEGMENTS
    // If you ever need to debug this again, you will probably want to
    // change this debugging code to include the information printed out
    // by MR_new_nondetstack_segment() below.

    MR_debug_log_message(
        "create new det segment: old zone: %p, old sp %p, old succip %p",
        MR_CONTEXT(MR_ctxt_detstack_zone), old_sp, MR_succip);
#endif

    list->MR_zones_head = MR_CONTEXT(MR_ctxt_detstack_zone);
    list->MR_zones_tail = MR_CONTEXT(MR_ctxt_prev_detstack_zones);
    MR_CONTEXT(MR_ctxt_prev_detstack_zones) = list;
    MR_CONTEXT(MR_ctxt_detstack_zone) = new_zone;
    MR_CONTEXT(MR_ctxt_sp) = MR_CONTEXT(MR_ctxt_detstack_zone)->MR_zone_min;

    MR_sp_word = (MR_Word) MR_CONTEXT(MR_ctxt_sp);

    MR_incr_sp_leaf(2);
    MR_stackvar(1) = (MR_Word) old_sp;
    MR_stackvar(2) = (MR_Word) MR_succip;

    // This may not be for a leaf procedure; we abuse the macro to avoid
    // a check for whether we have run out of the new detstack segment.
    //
    // XXX It is *theoretically* possible for a single stack frame to need
    // more memory than is available in the whole of the new segment.
    // However, if this is true, then the program is screwed anyway.
    // We cannot save it, though we *could* give a meaningful error message
    // instead of just leaving the program to crash.

    MR_incr_sp_leaf(n);

#ifdef  MR_DEBUG_STACK_SEGMENTS
    MR_debug_log_message(
        "create new det segment: new zone: %p, new sp %p new succip: %p",
        MR_CONTEXT(MR_ctxt_detstack_zone), MR_sp,
        MR_ENTRY(MR_pop_detstack_segment));
#endif

    return MR_sp;
}
Beispiel #3
0
MR_Word *
MR_new_nondetstack_segment(MR_Word *maxfr, int incr)
{
    MR_Word         *sentinel_maxfr;
    MR_Word         *old_maxfr;
    MR_Word         *old_curfr;
    MR_MemoryZone   *new_cur_zone;
    MR_MemoryZones  *new_prev_zones;

    old_maxfr = maxfr;
    old_curfr = MR_curfr;

#ifdef  MR_DEBUG_STACK_SEGMENTS
    printf("\nadding new nondet stack segment");
    printf("\ncontext: %p", &MR_ENGINE(MR_eng_context));
    printf("\nold maxfr: ");
    MR_printnondetstack(stdout, old_maxfr);
    printf("\nold curfr: ");
    MR_printnondetstack(stdout, old_curfr);
    printf("\n");
#endif

    new_cur_zone = MR_rewind_nondetstack_segments(maxfr);
    if (new_cur_zone == NULL) {
        // There is no old segment to reuse in the nondet stack itself,
        // so allocate a new one (possibly one that was freed earlier).
        //
        // Note that we perform explicit overflow checks, so redzones
        // would just waste space.

        new_cur_zone = MR_create_or_reuse_zone("nondetstack_segment",
            MR_nondetstack_size, 0, 0, MR_default_handler);
    }

#ifdef  MR_DEBUG_STACK_SEGMENTS
    printf("\nbefore creating new nondet segment:\n");
    MR_print_zone(stdout, MR_CONTEXT(MR_ctxt_nondetstack_zone));
    printf("\n");
#endif

    new_prev_zones = MR_GC_malloc_uncollectable_attrib(sizeof(MR_MemoryZones),
        MR_ALLOC_SITE_RUNTIME);
    new_prev_zones->MR_zones_head = MR_CONTEXT(MR_ctxt_nondetstack_zone);
    new_prev_zones->MR_zones_tail = MR_CONTEXT(MR_ctxt_prev_nondetstack_zones);
    MR_CONTEXT(MR_ctxt_prev_nondetstack_zones) = new_prev_zones;
    MR_CONTEXT(MR_ctxt_nondetstack_zone) = new_cur_zone;
    MR_CONTEXT(MR_ctxt_maxfr) = new_cur_zone->MR_zone_min;

    MR_maxfr_word = (MR_Word) MR_CONTEXT(MR_ctxt_maxfr);

#ifdef  MR_DEBUG_STACK_SEGMENTS
    printf("\nafter creating new nondet segment\n");
    printf("new maxfr: ");
    MR_printnondetstack(stdout, MR_maxfr);
    printf("\nnew cur zone:\n");
    MR_print_zone(stdout, MR_CONTEXT(MR_ctxt_nondetstack_zone));
    printf("new prev zones:\n");
    MR_print_zones(stdout, MR_CONTEXT(MR_ctxt_prev_nondetstack_zones));
    printf("\n");
    fflush(stdout);
#endif

    // The stack trace tracing code needs to know the size of each nondet
    // stack frame, since it uses the size to classify frames as temp or
    // ordinary. The size is given by the difference in address between
    // the address of the frame and the address of the previous frame.
    // This difference would yield an incorrect size and hence an incorrect
    // frame classification if a temp frame were allowed to have a frame
    // on a different segment as its immediate predecessor.
    //
    // We prevent this by putting an ordinary (i.e. non-temp) frame at the
    // bottom of every new nondet stack segment as a sentinel. We hand-build
    // this frame, since it is not an "ordinary" ordinary frame. It is not
    // created by a call, so it has no meaningful success continuation,
    // and since it does not make any calls, no other frame's success
    // continuation can point to it either.
    //
    // We store three pieces of information in the sentinel frame.
    //
    // - The maxfr at the time the sentinel frame was created, which we store
    //   in the prevfr slot. This is actually the address of the logically
    //   previous frame, so we are using the slot for its intended purpose,
    //   but the difference between the addresses of the two frames is NOT
    //   the size of the sentinel frame.
    //
    // - The curfr at the time the sentinel frame was created, which we store
    //   in the succfr slot. This is NOT actually the frame of the success
    //   continuation; we can store it there because this frame HAS no
    //   meaningful success continuation, so the slot is not needed for its
    //   intended purpose.
    //
    // - The address of the MR_MemoryZone structure of the zone containing
    //   the sentinel frame, which we store in framevar 1. This is used by
    //   the code of MR_pop_nondetstack_segment.

    sentinel_maxfr = MR_maxfr + (MR_NONDET_FIXED_SIZE + 1);
    MR_prevfr_slot_word(sentinel_maxfr) = (MR_Word) old_maxfr;
    MR_succfr_slot_word(sentinel_maxfr) = (MR_Word) old_curfr;
    MR_succip_slot_word(sentinel_maxfr) =
        (MR_Word) MR_ENTRY(MR_do_not_reached);
    MR_redofr_slot_word(sentinel_maxfr) = (MR_Word) sentinel_maxfr;
    MR_redoip_slot_word(sentinel_maxfr) =
        (MR_Word) MR_ENTRY(MR_pop_nondetstack_segment);
    MR_based_framevar(sentinel_maxfr, 1) = (MR_Word) new_cur_zone;

#ifdef  MR_DEBUG_STACK_SEGMENTS
    printf("creating sentinel frame:\n");
    printf("sentinel_maxfr: ");
    MR_printnondetstack(stdout, sentinel_maxfr);
    printf("\nsentinel frame's prevfr slot: ");
    MR_printnondetstack(stdout, MR_prevfr_slot(sentinel_maxfr));
    printf("\nsentinel frame's succfr slot: ");
    MR_printnondetstack(stdout, MR_succfr_slot(sentinel_maxfr));
    printf("\nsentinel frame's redofr slot: ");
    MR_printnondetstack(stdout, MR_redofr_slot(sentinel_maxfr));
    printf("\n");
#endif

    // Reserve space for the new nondet stack frame on top of the
    // sentinel frame.

    MR_maxfr_word = (MR_Word) (sentinel_maxfr + incr);

#ifdef  MR_DEBUG_STACK_SEGMENTS
    printf("after creating sentinel frame and reserving %d words:\n", incr);
    printf("new maxfr: ");
    MR_printnondetstack(stdout, MR_maxfr);
    printf("\n");
    fflush(stdout);
#endif

    return MR_maxfr;
}