diff --git a/ghc/includes/ClosureMacros.h b/ghc/includes/ClosureMacros.h
index f2352d9314cc96f2f66906fb56140cb9c214914a..a1c9f50e651e3bf86e7d71e6dd3f978b2259d789 100644
--- a/ghc/includes/ClosureMacros.h
+++ b/ghc/includes/ClosureMacros.h
@@ -1,5 +1,5 @@
 /* ----------------------------------------------------------------------------
- * $Id: ClosureMacros.h,v 1.8 1999/03/11 11:21:45 simonm Exp $
+ * $Id: ClosureMacros.h,v 1.9 1999/03/15 16:53:10 simonm Exp $
  *
  * (c) The GHC Team, 1998-1999
  *
@@ -318,6 +318,14 @@ SET_STATIC_HDR(PrelBase_CZh_closure,PrelBase_CZh_info,costCentreStack,const);
 #define STATIC_LINK(info,p) \
    (*stgCast(StgClosure**,&((p)->payload[info->layout.payload.ptrs + \
 					info->layout.payload.nptrs])))
+/* These macros are optimised versions of the above for certain
+ * closure types.  They *must* be equivalent to the generic
+ * STATIC_LINK.
+ */
+#define FUN_STATIC_LINK(p)   ((p)->payload[0])
+#define THUNK_STATIC_LINK(p) ((p)->payload[2])
+#define IND_STATIC_LINK(p)   ((p)->payload[1])
+
 #define STATIC_LINK2(info,p) \
    (*stgCast(StgClosure**,&((p)->payload[info->layout.payload.ptrs + \
 					info->layout.payload.nptrs + 1])))
diff --git a/ghc/rts/GC.c b/ghc/rts/GC.c
index 59a3da1db59f5e07228711f4978f66af13180c3a..680c8e5b22c8c0611901bb1197314586889f02ac 100644
--- a/ghc/rts/GC.c
+++ b/ghc/rts/GC.c
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------------
- * $Id: GC.c,v 1.51 1999/03/15 16:30:27 simonm Exp $
+ * $Id: GC.c,v 1.52 1999/03/15 16:53:11 simonm Exp $
  *
  * (c) The GHC Team 1998-1999
  *
@@ -1288,30 +1288,35 @@ loop:
     q = ((StgInd*)q)->indirectee;
     goto loop;
 
-    /* ToDo: optimise STATIC_LINK for known cases.
-       - FUN_STATIC       : payload[0]
-       - THUNK_STATIC     : payload[1]
-       - IND_STATIC       : payload[1]
-    */
   case THUNK_STATIC:
+    if (info->srt_len > 0 && major_gc && 
+	THUNK_STATIC_LINK((StgClosure *)q) == NULL) {
+      THUNK_STATIC_LINK((StgClosure *)q) = static_objects;
+      static_objects = (StgClosure *)q;
+    }
+    return q;
+
   case FUN_STATIC:
-    if (info->srt_len == 0) {	/* small optimisation */
-      return q;
+    if (info->srt_len > 0 && major_gc && 
+	FUN_STATIC_LINK((StgClosure *)q) == NULL) {
+      FUN_STATIC_LINK((StgClosure *)q) = static_objects;
+      static_objects = (StgClosure *)q;
     }
-    /* fall through */
-  case CONSTR_STATIC:
+    return q;
+
   case IND_STATIC:
-    /* don't want to evacuate these, but we do want to follow pointers
-     * from SRTs  - see scavenge_static.
-     */
+    if (major_gc && IND_STATIC_LINK((StgClosure *)q) == NULL) {
+      IND_STATIC_LINK((StgClosure *)q) = static_objects;
+      static_objects = (StgClosure *)q;
+    }
+    return q;
 
-    /* put the object on the static list, if necessary.
-     */
+  case CONSTR_STATIC:
     if (major_gc && STATIC_LINK(info,(StgClosure *)q) == NULL) {
       STATIC_LINK(info,(StgClosure *)q) = static_objects;
       static_objects = (StgClosure *)q;
     }
-    /* fall through */
+    return q;
 
   case CONSTR_INTLIKE:
   case CONSTR_CHARLIKE: