diff --git a/ghc/rts/GCCompact.c b/ghc/rts/GCCompact.c
index b3f4fb7d2110d3d568467e032f08604911448b65..9ddd4140508e589e8a2bf9d692381335626cfdcc 100644
--- a/ghc/rts/GCCompact.c
+++ b/ghc/rts/GCCompact.c
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------------
- * $Id: GCCompact.c,v 1.4 2001/07/25 11:55:57 simonmar Exp $
+ * $Id: GCCompact.c,v 1.5 2001/07/30 12:57:01 simonmar Exp $
  *
  * (c) The GHC Team 2001
  *
@@ -723,8 +723,15 @@ update_fwd_compact( bdescr *blocks )
 
 	    size = p - q;
 	    if (free + size > free_bd->start + BLOCK_SIZE_W) {
+		// unset the next bit in the bitmap to indicate that
+		// this object needs to be pushed into the next
+		// block.  This saves us having to run down the
+		// threaded info pointer list twice during the next pass.
+		unmark(q+1,bd);
 		free_bd = free_bd->link;
 		free = free_bd->start;
+	    } else {
+		ASSERT(is_marked(q+1,bd));
 	    }
 
 	    unthread(q,free);
@@ -784,15 +791,7 @@ update_bkwd_compact( step *stp )
 	    }
 #endif
 
-	    // must unthread before we look at the info ptr...
-	    info = get_threaded_info(p);
-
-	    ASSERT(p && (LOOKS_LIKE_GHC_INFO(info)
-			 || IS_HUGS_CONSTR_INFO(info)));
-
-	    size = obj_sizeW((StgClosure *)p,info);
-
-	    if (free + size > free_bd->start + BLOCK_SIZE_W) {
+	    if (!is_marked(p+1,bd)) {
 		// don't forget to update the free ptr in the block desc.
 		free_bd->free = free;
 		free_bd = free_bd->link;
@@ -801,6 +800,12 @@ update_bkwd_compact( step *stp )
 	    }
 
 	    unthread(p,free);
+	    info = get_itbl((StgClosure *)p);
+	    size = obj_sizeW((StgClosure *)p,info);
+
+	    ASSERT(p && (LOOKS_LIKE_GHC_INFO(info)
+			 || IS_HUGS_CONSTR_INFO(info)));
+
 	    if (free != p) {
 		move(free,p,size);
 	    }