void MR_dumpframe(FILE *fp, const MR_Word *fr) { int i; fprintf(fp, "frame at "); MR_printnondetstack(fp, fr), fprintf(fp, "\n"); fprintf(fp, "\t succip "); MR_printlabel(fp, MR_succip_slot(fr)); fprintf(fp, "\t redoip "); MR_printlabel(fp, MR_redoip_slot(fr)); fprintf(fp, "\t succfr "); MR_printnondetstack(fp, MR_succfr_slot(fr)); fprintf(fp, "\t prevfr "); MR_printnondetstack(fp, MR_prevfr_slot(fr)); for (i = 1; &MR_based_framevar(fr,i) > MR_prevfr_slot(fr); i++) { fprintf(fp, "\t framevar(%d) %ld 0x%lx\n", i, (long) (MR_Integer) MR_based_framevar(fr,i), (unsigned long) MR_based_framevar(fr,i)); } }
static void MR_dump_short_value(MR_ShortLval locn, MR_MemoryZone *heap_zone, MR_Word *stack_pointer, MR_Word *current_frame, MR_bool do_regs) { int locn_num; MR_Word value; int difference; MR_bool have_value; value = 0; have_value = MR_FALSE; locn_num = (int) locn >> MR_SHORT_LVAL_TAGBITS; switch (MR_SHORT_LVAL_TYPE(locn)) { case MR_SHORT_LVAL_TYPE_R: if (do_regs) { value = MR_virtual_reg_value(locn_num); have_value = MR_TRUE; fprintf(stderr, "r%d\t", locn_num); } else { fprintf(stderr, "r%d (invalid)\t", locn_num); } break; case MR_SHORT_LVAL_TYPE_STACKVAR: value = MR_based_stackvar(stack_pointer, locn_num); have_value = MR_TRUE; fprintf(stderr, "stackvar%d", locn_num); break; case MR_SHORT_LVAL_TYPE_FRAMEVAR: value = MR_based_framevar(current_frame, locn_num); have_value = MR_TRUE; fprintf(stderr, "framevar%d", locn_num); break; case MR_SHORT_LVAL_TYPE_SPECIAL: switch (locn_num) { case MR_LONG_LVAL_TYPE_SUCCIP: fprintf(stderr, "succip"); break; case MR_LONG_LVAL_TYPE_MAXFR: fprintf(stderr, "succip"); break; case MR_LONG_LVAL_TYPE_CURFR: fprintf(stderr, "curfr"); break; case MR_LONG_LVAL_TYPE_HP: fprintf(stderr, "hp"); break; case MR_LONG_LVAL_TYPE_SP: fprintf(stderr, "sp"); break; default: fprintf(stderr, "SPECIAL DEFAULT"); break; } break; default: fprintf(stderr, "SHORT DEFAULT"); break; } if (have_value) { if (value >= (MR_Word) heap_zone->MR_zone_min && value < (MR_Word) heap_zone->MR_zone_hardmax) { difference = (MR_Word *) value - (MR_Word *) heap_zone->MR_zone_min; fprintf(stderr, "\thp[%d]\t(%lx)", difference, (long) value); } else { fprintf(stderr, "\t \t(%lx)", (long) value); } } }
static void MR_dump_long_value(MR_LongLval locn, MR_MemoryZone *heap_zone, MR_Word *stack_pointer, MR_Word *current_frame, MR_bool do_regs) { int locn_num; MR_Word value; int difference; MR_bool have_value; value = 0; have_value = MR_FALSE; locn_num = MR_LONG_LVAL_NUMBER(locn); switch (MR_LONG_LVAL_TYPE(locn)) { case MR_LONG_LVAL_TYPE_R: if (do_regs) { value = MR_virtual_reg_value(locn_num); have_value = MR_TRUE; fprintf(stderr, "r%d\t", locn_num); } else { fprintf(stderr, "r%d (invalid)\t", locn_num); } break; case MR_LONG_LVAL_TYPE_F: fprintf(stderr, "f%d\t", locn_num); break; case MR_LONG_LVAL_TYPE_STACKVAR: value = MR_based_stackvar(stack_pointer, locn_num); have_value = MR_TRUE; fprintf(stderr, "stackvar%d", locn_num); break; case MR_LONG_LVAL_TYPE_FRAMEVAR: value = MR_based_framevar(current_frame, locn_num); have_value = MR_TRUE; fprintf(stderr, "framevar%d", locn_num); break; case MR_LONG_LVAL_TYPE_SUCCIP: fprintf(stderr, "succip"); break; case MR_LONG_LVAL_TYPE_MAXFR: fprintf(stderr, "maxfr"); break; case MR_LONG_LVAL_TYPE_CURFR: fprintf(stderr, "curfr"); break; case MR_LONG_LVAL_TYPE_HP: fprintf(stderr, "hp"); break; case MR_LONG_LVAL_TYPE_SP: fprintf(stderr, "sp"); break; case MR_LONG_LVAL_TYPE_INDIRECT: fprintf(stderr, "offset %d from ", MR_LONG_LVAL_INDIRECT_OFFSET(locn_num)); // XXX Tyson will have to complete this // based on what he wants this function to do. case MR_LONG_LVAL_TYPE_UNKNOWN: fprintf(stderr, "unknown"); break; default: fprintf(stderr, "LONG DEFAULT"); break; } if (have_value) { if (value >= (MR_Word) heap_zone->MR_zone_min && value < (MR_Word) heap_zone->MR_zone_hardmax) { difference = (MR_Word *) value - (MR_Word *) heap_zone->MR_zone_min; fprintf(stderr, "\thp[%d]\t(%lx)", difference, (long) value); } else { fprintf(stderr, "\t \t(%lx)", (long) value); } } }
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; }