--- /home/cpdev/src/classpath/java/lang/ref/Reference.java	2005-07-02 21:03:35.000000000 +0000
+++ java/lang/ref/Reference.java	2005-06-30 05:34:39.000000000 +0000
@@ -75,8 +75,31 @@
   /**
    * The underlying object.  This field is handled in a special way by
    * the garbage collector.
+   * GCJ LOCAL:
+   * This is a RawData because it must be disguised from the GC.
+   * END GCJ LOCAL
    */
-  Object referent;
+  gnu.gcj.RawData referent;
+
+  /**
+   * This is like REFERENT but is not scanned by the GC.  We keep a
+   * copy around so that we can clean up our internal data structure
+   * even after clear() is called.
+   * GCJ LOCAL:
+   * This field doesn't exist in Classpath.
+   * END GCJ LOCAL
+   */
+  gnu.gcj.RawData copy;
+
+  /**
+   * Set to true if {@link #clear()} is called.
+   * GCJ LOCAL:
+   * This field doesn't exist in Classpath.  It is used internally in
+   * natReference.cc, which enqueues the reference unless it is true
+   * (has been cleared).
+   * END GCJ LOCAL
+   */
+  boolean cleared = false;
 
   /**
    * The queue this reference is registered on. This is null, if this
@@ -108,7 +131,7 @@
    */
   Reference(Object ref)
   {
-    referent = ref;
+    create (ref);
   }
 
   /**
@@ -123,11 +146,16 @@
   {
     if (q == null)
       throw new NullPointerException();
-    referent = ref;
     queue = q;
+    create (ref);
   }
 
   /**
+   * Notifies the VM that a new Reference has been created.
+   */
+  private native void create (Object o);
+
+  /**
    * Returns the object, this reference refers to.
    * @return the object, this reference refers to, or null if the 
    * reference was cleared.
@@ -148,7 +176,12 @@
    */
   public void clear()
   {
-    referent = null;
+    // Must synchronize so changes are visible in finalizer thread.
+    synchronized (lock)
+      {
+        referent = null;
+        cleared = true;
+      }
   }
 
   /**
