[m-dev.] for review: fix for a bug reported by Warwick
Warwick Harvey
wharvey at cs.monash.edu.au
Thu Jan 27 18:07:52 AEDT 2000
Fergus wrote:
> On 27-Jan-2000, Warwick Harvey <wharvey at cs.monash.edu.au> wrote:
> > Assuming that the save/restore of the ticket counter is so that the tracing
> > code doesn't interfere with the "real" code, surely the restore should be
> > immediately after the tracing code, not at the end of the predicate?
>
> The ticket counter is not saved/restored, so I'm not sure what you
> are talking about here.
>
> The debugging code checkpoints the trail state (i.e. allocates a trail ticket
> and saves the current trail pointer) so that the state can be restored if
> the user does a "retry" command in the debugger.
Ah, *that's* what it's for. Makes much more sense now. :-)
> > Also, in my struggle to understand all this tracing stuff, I am wondering
> > why in shallow-traced code, when `MR_trace_from_full' is FALSE, MR_trace()
> > is still called. My understanding is no events should be generated in this
> > case? Or is the call to MR_trace() "harmless" here?
>
> I think your understanding is correct.
> Perhaps you could show the generated code which you think is wrong?
I'm not claiming it's wrong, I'm just claiming I don't understand it. :-)
Anyway, here's an extract from io.c, when the standard library's io.m was
compiled in the grade asm_fast.gc.tr.debug (using the standard Mmakefile,
etc., etc., in particular `--trace minimum'):
/* code for predicate 'read_char'/3 in mode 0 */
Define_entry(mercury__io__read_char_3_0);
MR_incr_sp_push_msg(7, "io:read_char/3");
MR_stackvar(7) = (Word) MR_succip;
{
MR_stackvar(4) = MR_trace_from_full;
if (MR_trace_from_full) {
MR_stackvar(1) = MR_trace_event_number;
MR_stackvar(2) = MR_trace_incr_seq();
MR_stackvar(3) = MR_trace_incr_depth();
MR_mark_ticket_stack(MR_stackvar(6));
MR_store_ticket(MR_stackvar(5));
} else {
MR_stackvar(3) = MR_trace_call_depth;
}
}
Define_label(mercury__io__read_char_3_0_i2);
{
Code *MR_jumpaddr;
save_transient_registers();
MR_jumpaddr = MR_trace(
(const MR_Stack_Layout_Label *)
&mercury_data__layout__mercury__io__read_char_3_0_i2)
;
restore_transient_registers();
if (MR_jumpaddr != NULL) GOTO(MR_jumpaddr);
}
MR_trace_from_full = FALSE;
MR_trace_reset_depth(MR_stackvar(3));
... etc.
So if `MR_trace_from_full' is true, it checkpoints the trail state, and if
not it doesn't. Fine, I now know why it's doing this. But the call to
MR_trace(), etc. is unconditional. Anyway, Zoltan has just addressed this
issue in his reply to my mail.
> > Presumably also one
> > could optimise the code for predicates which aren't exported when using
> > shallow tracing, because they can't possibly be called from deep-traced
> > code? (Or can they, through intermodule optimisation?)
>
> Yes, predicates which are not exported can be called through
> intermodule optimization, or from nested modules,
> but in those cases they are marked as `opt_exported'
> or `exported_to_children', so we could detect those cases
> fairly easily. However predicates can also have their
> address taken and be called indirectly. I think we now
> record which predicates have their address taken, so it might
> now be fairly easy to do that optimization for
> non-exported procedures whose address is not taken
> and which are not implementations of type class method.
If you say so... :-)
Warwick
--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to: mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions: mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------
More information about the developers
mailing list