MR_TypeInfoParams MR_materialize_type_params(const MR_LabelLayout *label_layout, MR_Word *saved_regs) { return MR_materialize_type_params_base(label_layout, saved_regs, MR_saved_sp(saved_regs), MR_saved_curfr(saved_regs)); }
void MR_print_stack_regs(FILE *fp, MR_Word *saved_regs) { #ifndef MR_HIGHLEVEL_CODE fprintf(fp, "sp = "); MR_print_detstackptr(fp, MR_saved_sp(saved_regs)); fprintf(fp, "\ncurfr = "); MR_print_nondetstackptr(fp, MR_saved_curfr(saved_regs)); fprintf(fp, "\nmaxfr = "); MR_print_nondetstackptr(fp, MR_saved_maxfr(saved_regs)); fprintf(fp, "\n"); #endif }
MR_bool MR_find_clique_entry_mdb(MR_EventInfo *event_info, MR_SelectedStackFrame which_frame, MR_Level *selected_level_ptr) { const MR_LabelLayout *layout; MR_Word *saved_regs; int clique_entry_level; int clique_parent_level; const char *problem; layout = event_info->MR_event_sll; saved_regs = event_info->MR_saved_regs; problem = MR_find_clique_entry(layout, MR_saved_sp(saved_regs), MR_saved_curfr(saved_regs), &clique_entry_level, &clique_parent_level); if (problem != NULL) { fflush(MR_mdb_out); fprintf(MR_mdb_err, "mdb: %s.\n", problem); return MR_TRUE; } if (which_frame == MR_CLIQUE_ENTRY_PARENT_FRAME) { if (clique_parent_level < 0) { fflush(MR_mdb_out); fprintf(MR_mdb_err, "mdb: All the frames on the stack" "are recursive with the current procedure.\n"); return MR_TRUE; } *selected_level_ptr = clique_parent_level; } else { *selected_level_ptr = clique_entry_level; } return MR_FALSE; }
MR_Next MR_trace_cmd_finish(char **words, int word_count, MR_TraceCmdInfo *cmd, MR_EventInfo *event_info, MR_Code **jumpaddr) { const MR_ProcLayout *proc_layout; const MR_LabelLayout *ancestor_layout; MR_Unsigned depth; MR_Unsigned stop_depth; MR_Unsigned n; MR_Level ancestor_level; MR_TracePort port; MR_Word *base_sp; MR_Word *base_curfr; MR_Unsigned reused_frames; MR_Level actual_level; const char *problem; // Not used. depth = event_info->MR_call_depth; cmd->MR_trace_strict = MR_TRUE; cmd->MR_trace_print_level_specified = MR_FALSE; cmd->MR_trace_print_level = MR_default_print_level; MR_init_trace_check_integrity(cmd); if (! MR_trace_options_movement_cmd(cmd, &words, &word_count)) { // The usage message has already been printed. ; return KEEP_INTERACTING; } else if (word_count == 2 && ( MR_streq(words[1], "entry") || MR_streq(words[1], "clentry"))) { if (MR_find_clique_entry_mdb(event_info, MR_CLIQUE_ENTRY_FRAME, &ancestor_level)) { // The error message has already been printed. return KEEP_INTERACTING; } } else if (word_count == 2 && MR_streq(words[1], "clparent")) { if (MR_find_clique_entry_mdb(event_info, MR_CLIQUE_ENTRY_PARENT_FRAME, &ancestor_level)) { // The error message has already been printed. return KEEP_INTERACTING; } } else if (word_count == 2 && MR_trace_is_natural_number(words[1], &n)) { ancestor_level = n; } else if (word_count == 1) { ancestor_level = 0; } else { MR_trace_usage_cur_cmd(); return KEEP_INTERACTING; } base_sp = MR_saved_sp(event_info->MR_saved_regs); base_curfr = MR_saved_curfr(event_info->MR_saved_regs); proc_layout = event_info->MR_event_sll->MR_sll_entry; MR_trace_find_reused_frames(proc_layout, base_sp, reused_frames); port = event_info->MR_trace_port; stop_depth = depth - ancestor_level; if (MR_port_is_final(port) && depth == stop_depth) { MR_trace_do_noop(); } else if (MR_port_is_final(port) && depth - reused_frames <= stop_depth && stop_depth < depth) { MR_trace_do_noop_tail_rec(); } else { ancestor_layout = MR_find_nth_ancestor(event_info->MR_event_sll, ancestor_level, &base_sp, &base_curfr, &actual_level, &problem); if (ancestor_layout == NULL) { fflush(MR_mdb_out); if (problem != NULL) { fprintf(MR_mdb_err, "mdb: %s\n", problem); } else { fprintf(MR_mdb_err, "mdb: not that many ancestors.\n"); } return KEEP_INTERACTING; } else if (actual_level != ancestor_level) { fflush(MR_mdb_out); fprintf(MR_mdb_err, "%d %d\n", (int) ancestor_level, (int) actual_level); fprintf(MR_mdb_err, "mdb: that stack frame has been reused, " "will stop at finish of reusing call.\n"); } else { cmd->MR_trace_cmd = MR_CMD_FINISH; cmd->MR_trace_stop_depth = stop_depth; return STOP_INTERACTING; } } return KEEP_INTERACTING; }
MR_Next MR_trace_cmd_next(char **words, int word_count, MR_TraceCmdInfo *cmd, MR_EventInfo *event_info, MR_Code **jumpaddr) { const MR_ProcLayout *proc_layout; const MR_LabelLayout *ancestor_layout; MR_Unsigned depth; MR_Unsigned stop_depth; MR_Unsigned n; MR_TracePort port; MR_Word *base_sp; MR_Word *base_curfr; MR_Unsigned reused_frames; MR_Level actual_level; const char *problem; // Not used. depth = event_info->MR_call_depth; cmd->MR_trace_strict = MR_TRUE; cmd->MR_trace_print_level_specified = MR_FALSE; cmd->MR_trace_print_level = MR_default_print_level; MR_init_trace_check_integrity(cmd); if (! MR_trace_options_movement_cmd(cmd, &words, &word_count)) { // The usage message has already been printed. ; return KEEP_INTERACTING; } else if (word_count == 2 && MR_trace_is_natural_number(words[1], &n)) { stop_depth = depth - n; } else if (word_count == 1) { n = 0; stop_depth = depth; } else { MR_trace_usage_cur_cmd(); return KEEP_INTERACTING; } base_sp = MR_saved_sp(event_info->MR_saved_regs); base_curfr = MR_saved_curfr(event_info->MR_saved_regs); proc_layout = event_info->MR_event_sll->MR_sll_entry; MR_trace_find_reused_frames(proc_layout, base_sp, reused_frames); port = event_info->MR_trace_port; if (depth == stop_depth && (MR_port_is_final(port) || port == MR_PORT_TAILREC_CALL)) { MR_trace_do_noop(); } else if (depth - reused_frames <= stop_depth && stop_depth < depth) { MR_trace_do_noop_tail_rec(); } else { ancestor_layout = MR_find_nth_ancestor(event_info->MR_event_sll, n, &base_sp, &base_curfr, &actual_level, &problem); if (ancestor_layout == NULL) { fflush(MR_mdb_out); if (problem != NULL) { fprintf(MR_mdb_err, "mdb: %s\n", problem); } else { fprintf(MR_mdb_err, "mdb: not that many ancestors.\n"); } return KEEP_INTERACTING; } else if (actual_level != n) { fflush(MR_mdb_out); fprintf(MR_mdb_err, "mdb: that stack frame has been reused, " "will stop in reusing call.\n"); } else { cmd->MR_trace_cmd = MR_CMD_NEXT; cmd->MR_trace_stop_depth = stop_depth; return STOP_INTERACTING; } } return KEEP_INTERACTING; }
MR_Next MR_trace_cmd_stack(char **words, int word_count, MR_TraceCmdInfo *cmd, MR_EventInfo *event_info, MR_Code **jumpaddr) { MR_bool print_all; MR_bool detailed; MR_FrameLimit frame_limit; MR_SpecLineLimit clique_line_limit; MR_SpecLineLimit line_limit; MR_SpecLineLimit spec_line_limit; const MR_LabelLayout *layout; MR_Word *saved_regs; const char *msg; detailed = MR_FALSE; print_all = MR_FALSE; frame_limit = 0; clique_line_limit = 10; line_limit = 100; if (! MR_trace_options_stack_trace(&print_all, &detailed, &line_limit, &clique_line_limit, &frame_limit, &words, &word_count)) { /* the usage message has already been printed */ return KEEP_INTERACTING; } else if (word_count == 1) { line_limit = MR_stack_default_line_limit; } else if (word_count == 2 && MR_trace_is_natural_number(words[1], &spec_line_limit)) { line_limit = spec_line_limit; } else { MR_trace_usage_cur_cmd(); return KEEP_INTERACTING; } layout = event_info->MR_event_sll; saved_regs = event_info->MR_saved_regs; #ifdef MR_DEBUG_STACK_DUMP_CLIQUE MR_trace_init_modules(); fprintf(MR_mdb_out, "OLD STACK DUMP:\n"); msg = MR_dump_stack_from_layout(MR_mdb_out, layout, MR_saved_sp(saved_regs), MR_saved_curfr(saved_regs), detailed, MR_context_position != MR_CONTEXT_NOWHERE, frame_limit, line_limit, &MR_dump_stack_record_print); if (msg != NULL) { fflush(MR_mdb_out); fprintf(MR_mdb_err, "%s.\n", msg); } fprintf(MR_mdb_out, "\nNEW STACK DUMP:\n"); #endif msg = MR_dump_stack_from_layout_clique(MR_mdb_out, layout, MR_saved_sp(saved_regs), MR_saved_curfr(saved_regs), detailed, MR_context_position != MR_CONTEXT_NOWHERE, !print_all, clique_line_limit, frame_limit, line_limit, &MR_dump_stack_record_print); if (msg != NULL) { fflush(MR_mdb_out); fprintf(MR_mdb_err, "%s.\n", msg); } return KEEP_INTERACTING; }