diff: trailing & commits bug fix

Fergus Henderson fjh at kryten.cs.mu.OZ.AU
Wed Sep 24 20:01:49 AEST 1997


runtime/mercury_trail.c:
	Fix a bug: it was removing trail entries at commits, but this
	is in general unsafe, for mdi modes.
	XXX This fix introduces some possibilities for storage leaks.
	We should garbage collect the trail properly.

doc/reference_manual.texi:
	Document the above change.

Index: mercury_trail.c
===================================================================
RCS file: /home/staff/zs/imp/mercury/runtime/mercury_trail.c,v
retrieving revision 1.2
diff -u -u -r1.2 mercury_trail.c
--- 1.2	1997/08/24 10:35:46
+++ mercury_trail.c	1997/09/24 09:54:15
@@ -27,33 +27,42 @@
 void
 MR_untrail_to(MR_TrailEntry *old_trail_ptr, MR_untrail_reason reason)
 {
+    MR_TrailEntry *tr_ptr = MR_trail_ptr;
+
     switch (reason) {
 	case MR_commit:
 	    /* Just handle the function trail entries */
-	    while (MR_trail_ptr != old_trail_ptr) {
-	    	MR_trail_ptr--;
-	    	if (MR_get_trail_entry_kind(MR_trail_ptr) == MR_func_entry) {
-		    (*MR_get_trail_entry_untrail_func(MR_trail_ptr))(
-				MR_get_trail_entry_datum(MR_trail_ptr),
+	    while (tr_ptr != old_trail_ptr) {
+	    	tr_ptr--;
+	    	if (MR_get_trail_entry_kind(tr_ptr) == MR_func_entry) {
+		    (*MR_get_trail_entry_untrail_func(tr_ptr))(
+				MR_get_trail_entry_datum(tr_ptr),
 				reason);
 		}
 	    }
+	    /*
+	    ** NB. We do _not_ reset the trail pointer here.
+	    ** Doing so would be unsafe, for `mdi' modes,
+	    ** because we may still need to restore the value
+	    ** if/when we backtrack to a choicepoint prior to
+	    ** the one we're cutting away.
+	    */
 	    break;
-
 	case MR_undo:
 	case MR_exception:
 	    /* Handle both function and value trail entries */
-	    while (MR_trail_ptr != old_trail_ptr) {
-		MR_trail_ptr--;
-	    	if (MR_get_trail_entry_kind(MR_trail_ptr) == MR_func_entry) {
-		    (*MR_get_trail_entry_untrail_func(MR_trail_ptr))(
-				MR_get_trail_entry_datum(MR_trail_ptr),
+	    while (tr_ptr != old_trail_ptr) {
+		tr_ptr--;
+	    	if (MR_get_trail_entry_kind(tr_ptr) == MR_func_entry) {
+		    (*MR_get_trail_entry_untrail_func(tr_ptr))(
+				MR_get_trail_entry_datum(tr_ptr),
 				reason);
 		} else {
-		    *MR_get_trail_entry_address(MR_trail_ptr) =
-				MR_get_trail_entry_value(MR_trail_ptr);
+		    *MR_get_trail_entry_address(tr_ptr) =
+				MR_get_trail_entry_value(tr_ptr);
 		}
 	    }
+	    MR_trail_ptr = tr_ptr;
 	    break;
 	
 	default:



Index: reference_manual.texi
===================================================================
RCS file: /home/staff/zs/imp/mercury/doc/reference_manual.texi,v
retrieving revision 1.71
diff -u -u -r1.71 reference_manual.texi
--- 1.71	1997/09/23 16:47:22
+++ reference_manual.texi	1997/09/24 09:57:54
@@ -3080,40 +3080,9 @@
 If the Mercury compiler determines that it will never
 need to backtrack to a particular choice point, then it will
 ``prune'' away that choice point.  If a choice point is pruned,
-the trail entries for those updates will be discarded;
-any updates occurring after that choice point will not be undone.
-
-Note that execution may subsequently backtrack to a @emph{prior} choice point,
-but if so, the values updated will not be live at that point, so
-there is no need to undo the updates.  The reason that the updated values
-are guaranteed to not be live is that the Mercury compiler will only
-prune choice points when it is guaranteed to be safe to do so.
-The compiler may commit to a goal in two circumstances: if it is guaranteed
-that execution will never attempt to backtrack over that goal, or
-if the goal has no outputs.  In the former case, execution
-cannot backtrack to a prior choice point, and in the latter case,
-the values updated within the goal cannot be live after the goal
-has succeeded, since the goal has no outputs.
-
-For example:
-
- at example
-
-:- mode q(mdi, muo) is nondet.
-:- mode p(mdi) is semidet.
-p(X) :- q(X, _Y), fail.
-
- at end example
-
-Here any choice points created in @code{q/2} will be pruned away
-before the call to @code{fail/1}.  At the call to @code{fail},
-execution will backtrack; any updates performed inside @code{q/2}
-will not be undone, but that should be OK, because the variable
- at samp{_Y} will no longer be live.
-
-Oh, but @samp{X} @emph{will} be live.  Oh-oh...
-
-XXX we really should fix that bug.
+the trail entries for those updates will not necessarily be discarded,
+because in general they may still be necessary in case we backtrack
+to a prior choice point.
 
 @node Value trailing
 @subsubsection Value trailing
-- 
Fergus Henderson <fjh at cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3         |     -- the last words of T. S. Garp.



More information about the developers mailing list