void MR_mkframe_msg(FILE *fp, const char *predname) { MR_restore_transient_registers(); if (!MR_lld_print_enabled) { return; } fprintf(fp, "\nnew choice point for procedure %s\n", predname); fprintf(fp, "new fr: "); MR_printnondetstack(fp, MR_curfr); fprintf(fp, "\nprev fr: "); MR_printnondetstack(fp, MR_prevfr_slot(MR_curfr)); fprintf(fp, "\nsucc fr: "); MR_printnondetstack(fp, MR_succfr_slot(MR_curfr)); fprintf(fp, "\nsucc ip: "); MR_printlabel(fp, MR_succip_slot(MR_curfr)); fprintf(fp, "redo fr: "); MR_printnondetstack(fp, MR_redofr_slot(MR_curfr)); fprintf(fp, "\nredo ip: "); MR_printlabel(fp, MR_redoip_slot(MR_curfr)); #ifdef MR_USE_MINIMAL_MODEL_OWN_STACKS fprintf(fp, "\ndet fr: "); MR_printdetstack(fp, MR_table_detfr_slot(MR_curfr)); #endif fprintf(fp, "\n"); if (MR_detaildebug) { MR_dumpnondetstack(fp); } fflush(fp); }
void MR_mkdettempframe_msg(FILE *fp) { MR_restore_transient_registers(); if (!MR_lld_print_enabled) { return; } fprintf(fp, "\nnew det temp nondet frame"); fprintf(fp, "\nnew fr: "); MR_printnondetstack(fp, MR_maxfr); fprintf(fp, "\nprev fr: "); MR_printnondetstack(fp, MR_prevfr_slot(MR_maxfr)); fprintf(fp, "\nredo fr: "); MR_printnondetstack(fp, MR_redofr_slot(MR_maxfr)); fprintf(fp, "\nredo ip: "); MR_printlabel(fp, MR_redoip_slot(MR_maxfr)); fprintf(fp, "det fr: "); MR_printdetstack(fp, MR_tmp_detfr_slot(MR_maxfr)); fprintf(fp, "\n"); if (MR_detaildebug) { MR_dumpnondetstack(fp); } }
void MR_redo_msg(FILE *fp) { MR_restore_transient_registers(); MR_do_watches(fp); if (!MR_lld_print_enabled) { return; } fprintf(fp, "\nredo from procedure"); fprintf(fp, "\ncurr fr: "); MR_printnondetstack(fp, MR_curfr); fprintf(fp, "\nredo fr: "); MR_printnondetstack(fp, MR_maxfr); fprintf(fp, "\nredo ip: "); MR_printlabel(fp, MR_redoip_slot(MR_maxfr)); }
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)); } }
void MR_succeeddiscard_msg(FILE *fp) { MR_restore_transient_registers(); MR_do_watches(fp); if (!MR_lld_print_enabled) { return; } fprintf(fp, "\nsucceeding from procedure\n"); fprintf(fp, "curr fr: "); MR_printnondetstack(fp, MR_curfr); fprintf(fp, "succ fr: "); MR_printnondetstack(fp, MR_succfr_slot(MR_curfr)); fprintf(fp, "succ ip: "); MR_printlabel(fp, MR_succip_slot(MR_curfr)); if (MR_detaildebug) { MR_printregs(fp, "registers at success"); } }
void MR_printregs(FILE *fp, const char *msg) { MR_restore_transient_registers(); fprintf(fp, "\n%s\n", msg); if (MR_sregdebug) { fprintf(fp, "%-9s", "succip:"); MR_printlabel(fp, MR_succip); fprintf(fp, "%-9s", "curfr:"); MR_printnondetstack(fp, MR_curfr); fprintf(fp, "%-9s", "maxfr:"); MR_printnondetstack(fp, MR_maxfr); fprintf(fp, "%-9s", "hp:"); MR_printheap(fp, MR_hp); fprintf(fp, "%-9s", "sp:"); MR_printdetstack(fp, MR_sp); } if (MR_ordregdebug) { MR_print_ordinary_regs(fp); } }
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; }