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_fail_msg(FILE *fp) { MR_restore_transient_registers(); MR_do_watches(fp); if (!MR_lld_print_enabled) { return; } fprintf(fp, "\nfailing from procedure\n"); fprintf(fp, "curr fr: "); MR_printnondetstack(fp, MR_curfr); fprintf(fp, "\nfail fr: "); MR_printnondetstack(fp, MR_prevfr_slot(MR_curfr)); fprintf(fp, "\nfail ip: "); MR_printlabel(fp, MR_redoip_slot(MR_prevfr_slot(MR_curfr))); fprintf(fp, "\n"); }
void MR_dumpnondetstack(FILE *fp) { MR_Word *fr; fprintf(fp, "\nnondetstack dump\n"); for (fr = MR_maxfr; MR_above_bottom_nondet_frame(fr); fr = MR_prevfr_slot(fr)) { MR_dumpframe(fp, fr); } }
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_agc_dump_nondet_stack_frames(MR_Internal *label, MR_MemoryZone *heap_zone, MR_Word *stack_pointer, MR_Word *current_frame, MR_Word *max_frame) { MR_Code *success_ip; int frame_size; MR_bool registers_valid; while (max_frame > MR_nondet_stack_trace_bottom_fr) { registers_valid = (max_frame == current_frame); frame_size = max_frame - MR_prevfr_slot(max_frame); if (frame_size == MR_NONDET_TEMP_SIZE) { fprintf(stderr, "%p: nondet temp\n", max_frame); fprintf(stderr, " redoip: "); fflush(NULL); MR_printlabel(stderr, MR_redoip_slot(max_frame)); fflush(NULL); fprintf(stderr, " redofr: %p\n", MR_redofr_slot(max_frame)); label = MR_lookup_internal_by_addr(MR_redoip_slot(max_frame)); if (label && label->MR_internal_layout) { MR_dump_live_variables(label->MR_internal_layout, heap_zone, registers_valid, stack_pointer, MR_redofr_slot(max_frame)); } } else if (frame_size == MR_DET_TEMP_SIZE) { fprintf(stderr, "%p: nondet temp\n", max_frame); fprintf(stderr, " redoip: "); fflush(NULL); MR_printlabel(stderr, MR_redoip_slot(max_frame)); fflush(NULL); fprintf(stderr, " redofr: %p\n", MR_redofr_slot(max_frame)); fprintf(stderr, " detfr: %p\n", MR_tmp_detfr_slot(max_frame)); label = MR_lookup_internal_by_addr(MR_redoip_slot(max_frame)); if (label && label->MR_internal_layout) { MR_dump_live_variables(label->MR_internal_layout, heap_zone, registers_valid, MR_tmp_detfr_slot(max_frame), max_frame); // XXX Should max_frame above be // MR_redoip_slot(max_frame) instead? } } else { fprintf(stderr, "%p: nondet ordinary\n", max_frame); fprintf(stderr, " redoip: "); fflush(NULL); MR_printlabel(stderr, MR_redoip_slot(max_frame)); fflush(NULL); fprintf(stderr, " redofr: %p\n", MR_redofr_slot(max_frame)); fprintf(stderr, " succip: "); fflush(NULL); MR_printlabel(stderr, MR_succip_slot(max_frame)); fflush(NULL); fprintf(stderr, " succfr: %p\n", MR_succfr_slot(max_frame)); // XXX ??? label = MR_lookup_internal_by_addr(MR_redoip_slot(max_frame)); if (label != NULL && label->MR_internal_layout) { MR_dump_live_variables(label->MR_internal_layout, heap_zone, registers_valid, stack_pointer, MR_redofr_slot(max_frame)); fprintf(stderr, " this label: %s\n", label->MR_internal_name); } } max_frame = MR_prevfr_slot(max_frame); } // XXX Lookup the address (redoip?) and dump the variables. fflush(NULL); }
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; }