static MR_bool MR_find_zone_for_det_ptr(const MR_Word *ptr, MR_Context **ctxt_ptr, MR_MemoryZone **zone_ptr, int *zone_num_ptr) { #ifdef MR_USE_MINIMAL_MODEL_OWN_STACKS const MR_Dlist *item; MR_Context *ctxt; if (MR_find_zone_for_det_ptr_in_context(ptr, MR_ENGINE(MR_eng_main_context), zone_ptr, zone_num_ptr)) { if (ctxt_ptr != NULL) { *ctxt_ptr = MR_ENGINE(MR_eng_main_context); } return MR_TRUE; } MR_for_dlist(item, MR_ENGINE(MR_eng_gen_contexts)) { ctxt = (MR_Context *) MR_dlist_data(item); if (MR_find_zone_for_det_ptr_in_context(ptr, ctxt, zone_ptr, zone_num_ptr)) { if (ctxt_ptr != NULL) { *ctxt_ptr = ctxt; } return MR_TRUE; } }
void MR_agc_dump_roots(MR_RootList roots) { #ifndef MR_HIGHLEVEL_CODE MR_Word saved_regs[MR_MAX_FAKE_REG]; MR_Float saved_f_regs[MR_MAX_VIRTUAL_F_REG]; #endif fflush(NULL); fprintf(stderr, "Dumping roots\n"); if (MR_debug_agc_print_vars) { while (roots != NULL) { #ifndef MR_HIGHLEVEL_CODE /* ** Restore the registers, because we need to save them to a more ** permanent backing store (we are going to call Mercury soon, ** and we don't want it messing with the saved registers). */ MR_restore_registers(); MR_copy_regs_to_saved_regs(MR_MAX_FAKE_REG - 1, saved_regs, MR_MAX_VIRTUAL_F_REG - 1, saved_f_regs); MR_hp_word = MR_ENGINE(MR_eng_debug_heap_zone->MR_zone_min); MR_virtual_hp_word = MR_ENGINE(MR_eng_debug_heap_zone->MR_zone_min); #endif /* !MR_HIGHLEVEL_CODE */ fflush(NULL); MR_write_variable(roots->type_info, *roots->root); fflush(NULL); fprintf(stderr, "\n"); #ifndef MR_HIGHLEVEL_CODE MR_copy_saved_regs_to_regs(MR_MAX_FAKE_REG - 1, saved_regs, MR_MAX_VIRTUAL_F_REG, saved_f_regs); MR_save_registers(); #endif /* !MR_HIGHLEVEL_CODE */ roots = roots->next; } } }
static void MR_print_ordinary_regs(FILE *fp) { int i; MR_Integer value; for (i = 0; i < 8; i++) { fprintf(fp, "r%d: ", i + 1); value = (MR_Integer) MR_get_reg(i+1); #ifndef MR_CONSERVATIVE_GC if ((MR_Integer) MR_ENGINE(MR_eng_heap_zone)->min <= value && value < (MR_Integer) MR_ENGINE(MR_eng_heap_zone)->top) { fprintf(fp, "(heap) "); } #endif fprintf(fp, "%ld %lx\n", (long) value, (long) value); } }
void MR_print_heapptr(FILE *fp, const MR_Word *s) { #ifdef MR_CONSERVATIVE_GC fprintf(fp, "heap %" MR_INTEGER_LENGTH_MODIFIER "d", (MR_Integer) s); #else fprintf(fp, "heap %3ld", (long) (MR_Integer) (s - MR_ENGINE(MR_eng_heap_zone)->MR_zone_min)); #endif if (MR_print_raw_addrs) { fprintf(fp, " (%p)", (const void *) s); } }
void MR_printheap(FILE *fp, const MR_Word *h) { #ifndef MR_CONSERVATIVE_GC if (MR_print_raw_addrs) { fprintf(fp, "ptr %p, ", (const void *) h); } fprintf(fp, "offset %6ld words\n", (long) (MR_Integer) (h - MR_ENGINE(MR_eng_heap_zone)->min)); #else fprintf(fp, "ptr %p\n", (const void *) h); #endif }
void MR_reg_msg(FILE *fp) { int i; MR_Integer x; if (!MR_lld_print_enabled) { return; } for (i=1; i<=8; i++) { x = (MR_Integer) MR_get_reg(i); #ifndef MR_CONSERVATIVE_GC if ((MR_Integer) MR_ENGINE(MR_eng_heap_zone)->MR_zone_min <= x && x < (MR_Integer) MR_ENGINE(MR_eng_heap_zone)->MR_zone_top) { x -= (MR_Integer) MR_ENGINE(MR_eng_heap_zone)->MR_zone_min; } #endif fprintf(fp, "%8lx ", (long) x); } fprintf(fp, "\n"); }
static void MR_dump_live_variables(const MR_LabelLayout *label_layout, MR_MemoryZone *heap_zone, MR_bool top_frame, MR_Word *stack_pointer, MR_Word *current_frame) { int short_var_count; int long_var_count; int i; MR_TypeInfo type_info; MR_Word value; MR_TypeInfoParams type_params; MR_Word saved_regs[MR_MAX_FAKE_REG]; MR_Float saved_f_regs[MR_MAX_VIRTUAL_F_REG]; MR_Word *current_regs; MR_Float *current_f_regs; long_var_count = MR_long_desc_var_count(label_layout); short_var_count = MR_short_desc_var_count(label_layout); // For the top stack frame, we should pass a pointer to a filled-in // saved_regs instead of NULL. For other stack frames, passing NULL // is fine, since output arguments are not live yet for any call // except the top one. MR_restore_registers(); MR_copy_regs_to_saved_regs(MR_MAX_FAKE_REG - 1, saved_regs, MR_MAX_VIRTUAL_F_REG - 1, saved_f_regs); if (top_frame) { current_regs = saved_regs; current_f_regs = saved_f_regs; } else { current_regs = NULL; current_f_regs = NULL; } type_params = MR_materialize_type_params_base(label_layout, current_regs, stack_pointer, current_frame); for (i = 0; i < long_var_count; i++) { fprintf(stderr, "%-12s\t", ""); if (MR_PROC_LAYOUT_HAS_PROC_ID(label_layout->MR_sll_entry)) { MR_print_proc_id(stderr, label_layout->MR_sll_entry); } MR_dump_long_value(MR_long_desc_var_locn(label_layout, i), heap_zone, stack_pointer, current_frame, top_frame); fprintf(stderr, "\n"); fflush(NULL); if (MR_debug_agc_print_vars) { // Call Mercury but use the debugging heap. MR_hp_word = MR_ENGINE(MR_eng_debug_heap_zone->MR_zone_min); MR_virtual_hp_word = MR_ENGINE(MR_eng_debug_heap_zone->MR_zone_min); if (MR_get_type_and_value_base(label_layout, i, current_regs, stack_pointer, current_frame, current_f_regs, type_params, &type_info, &value)) { printf("\t"); MR_write_variable(type_info, value); printf("\n"); } fflush(NULL); } } for (i = 0; i < short_var_count; i++) { fprintf(stderr, "%-12s\t", ""); if (MR_PROC_LAYOUT_HAS_PROC_ID(label_layout->MR_sll_entry)) { MR_print_proc_id(stderr, label_layout->MR_sll_entry); } MR_dump_short_value(MR_short_desc_var_locn(label_layout, i), heap_zone, stack_pointer, current_frame, top_frame); fprintf(stderr, "\n"); fflush(NULL); if (MR_debug_agc_print_vars) { // Call Mercury but use the debugging heap. MR_hp_word = MR_ENGINE(MR_eng_debug_heap_zone->MR_zone_min); MR_virtual_hp_word = MR_ENGINE(MR_eng_debug_heap_zone->MR_zone_min); if (MR_get_type_and_value_base(label_layout, i, current_regs, stack_pointer, current_frame, current_f_regs, type_params, &type_info, &value)) { printf("\t"); MR_write_variable(type_info, value); printf("\n"); } fflush(NULL); } } MR_copy_saved_regs_to_regs(MR_MAX_FAKE_REG - 1, saved_regs, MR_MAX_VIRTUAL_F_REG - 1, saved_f_regs); MR_save_registers(); MR_free(type_params); }
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; }