Hello,
Following up from an earlier discussion on core-libs [1], I've gone
through the exercise of purging sun.misc.Ref from the JDK repo. Patch
below (having difficulties uploading the webrev to cr.openjdk at the
time of writing.)
For the change associated with removing sun.misc.Ref, I was aiming to
minimize the alteration of surrounding code.
For sun.misc.Cache, the CacheEntry class that subclasses Ref before
now instead has an internal SoftReference and a few short methods that
Ref used to define.
In the Applet area, since the functionality of sun.misc.Ref over and
above SoftReference was being used, I copied and partially generified
the sun.misc.Ref code into AppletImageRef. Semantically,
AppletImageRef is now a sun.misc.Ref<Image>.
The purge of Ref required removing a method from AppletResourceLoader,
a class which looks like it should have long ago been deprecated.
A clean build of the jdk repo works after sun.misc.Ref has been
deleted. Before pushing the change, I'll do a jprt job to make sure
there aren't any other stray uses of Ref.
Thanks,
-Joe
[1]
http://mail.openjdk.java.net/pipermail/core-libs-dev/2014-January/024249.html
diff -r 9bf43f25eacd src/share/classes/sun/applet/AppletImageRef.java
--- a/src/share/classes/sun/applet/AppletImageRef.java Sat Jan 18
10:57:41 2014 -0800
+++ b/src/share/classes/sun/applet/AppletImageRef.java Tue Jan 21
10:15:15 2014 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, Oracle and/or its affiliates. All rights
reserved.
+ * Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights
reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,27 +27,71 @@
import java.awt.Toolkit;
import java.awt.Image;
+import java.lang.ref.SoftReference;
import sun.awt.image.URLImageSource;
import java.net.URL;
-class AppletImageRef extends sun.misc.Ref {
+class AppletImageRef {
+ private SoftReference<Image> soft = null;
+
URL url;
/**
+ * Returns a pointer to the object referenced by this Ref. If the
object
+ * has been thrown away by the garbage collector, it will be
+ * reconstituted. This method does everything necessary to ensure
that the garbage
+ * collector throws things away in Least Recently Used(LRU)
order. Applications should
+ * never override this method. The get() method effectively
caches calls to
+ * reconstitute().
+ */
+ public synchronized Image get() {
+ Image t = check();
+ if (t == null) {
+ t = reconstitute();
+ setThing(t);
+ }
+ return t;
+ }
+
+ /**
* Create the Ref
*/
AppletImageRef(URL url) {
this.url = url;
}
- public void flush() {
- super.flush();
+ /**
+ * Flushes the cached object. Forces the next invocation of
get() to
+ * invoke reconstitute().
+ */
+ public synchronized void flush() {
+ SoftReference s = soft;
+ if (s != null) s.clear();
+ soft = null;
+ }
+
+ /**
+ * Sets the thing to the specified object.
+ * @param thing the specified object
+ */
+ public synchronized void setThing(Object thing) {
+ flush();
+ soft = new SoftReference(thing);
+ }
+
+ /**
+ * Checks to see what object is being pointed at by this Ref and
returns it.
+ */
+ public synchronized Image check() {
+ SoftReference<Image> s = soft;
+ if (s == null) return null;
+ return s.get();
}
/**
* Reconsitute the image. Only called when the ref has been
flushed.
*/
- public Object reconstitute() {
+ public Image reconstitute() {
Image img = Toolkit.getDefaultToolkit().createImage(new
URLImageSource(url));
return img;
}
diff -r 9bf43f25eacd
src/share/classes/sun/applet/AppletResourceLoader.java
--- a/src/share/classes/sun/applet/AppletResourceLoader.java Sat Jan
18 10:57:41 2014 -0800
+++ b/src/share/classes/sun/applet/AppletResourceLoader.java Tue Jan
21 10:15:15 2014 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 1998, Oracle and/or its affiliates. All rights
reserved.
+ * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights
reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,21 +27,17 @@
import java.net.URL;
import java.awt.Image;
-import sun.misc.Ref;
/**
* Part of this class still remains only to support legacy, 100%-impure
* applications such as HotJava 1.0.1.
*/
+@Deprecated
public class AppletResourceLoader {
public static Image getImage(URL url) {
return AppletViewer.getCachedImage(url);
}
- public static Ref getImageRef(URL url) {
- return AppletViewer.getCachedImageRef(url);
- }
-
public static void flushImages() {
AppletViewer.flushImageCache();
}
diff -r 9bf43f25eacd src/share/classes/sun/applet/AppletViewer.java
--- a/src/share/classes/sun/applet/AppletViewer.java Sat Jan 18
10:57:41 2014 -0800
+++ b/src/share/classes/sun/applet/AppletViewer.java Tue Jan 21
10:15:15 2014 -0800
@@ -35,7 +35,6 @@
import java.net.URL;
import java.net.MalformedURLException;
import java.net.SocketPermission;
-import sun.misc.Ref;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.lang.reflect.InvocationTargetException;
@@ -390,22 +389,18 @@
return getCachedImage(url);
}
+ /**
+ * Get an image.
+ */
static Image getCachedImage(URL url) {
// System.getSecurityManager().checkConnection(url.getHost(),
url.getPort());
- return (Image)getCachedImageRef(url).get();
- }
-
- /**
- * Get an image ref.
- */
- static Ref getCachedImageRef(URL url) {
synchronized (imageRefs) {
AppletImageRef ref = (AppletImageRef)imageRefs.get(url);
if (ref == null) {
ref = new AppletImageRef(url);
imageRefs.put(url, ref);
}
- return ref;
+ return ref.get();
}
}
diff -r 9bf43f25eacd src/share/classes/sun/misc/Cache.java
--- a/src/share/classes/sun/misc/Cache.java Sat Jan 18 10:57:41
2014 -0800
+++ b/src/share/classes/sun/misc/Cache.java Tue Jan 21 10:15:15
2014 -0800
@@ -25,6 +25,7 @@
package sun.misc;
+import java.lang.ref.SoftReference;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.NoSuchElementException;
@@ -32,12 +33,26 @@
/**
* Caches the collision list.
*/
-class CacheEntry extends Ref {
+class CacheEntry {
int hash;
Object key;
CacheEntry next;
- public Object reconstitute() {
- return null;
+ SoftReference<Object> value;
+
+ public CacheEntry() {
+ value = null;
+ }
+
+ public CacheEntry(Object o) {
+ value = new SoftReference<>(o);
+ }
+
+ public Object get() {
+ return value.get();
+ }
+
+ public void setThing(Object thing) {
+ value = new SoftReference<>(thing);
}
}
@@ -192,7 +207,7 @@
int index = (hash & 0x7FFFFFFF) % tab.length;
for (CacheEntry e = tab[index]; e != null; e = e.next) {
if ((e.hash == hash) && e.key.equals(key)) {
- return e.check();
+ return e.get();
}
}
return null;
@@ -220,7 +235,7 @@
for (CacheEntry old = oldTable[i]; old != null;) {
CacheEntry e = old;
old = old.next;
- if (e.check() != null) {
+ if (e.get() != null) {
int index = (e.hash & 0x7FFFFFFF) % newCapacity;
e.next = newTable[index];
newTable[index] = e;
@@ -253,10 +268,10 @@
CacheEntry ne = null;
for (CacheEntry e = tab[index]; e != null; e = e.next) {
if ((e.hash == hash) && e.key.equals(key)) {
- Object old = e.check();
+ Object old = e.get();
e.setThing(value);
return old;
- } else if (e.check() == null)
+ } else if (e.get() == null)
ne = e; /* reuse old flushed value */
}
@@ -296,7 +311,7 @@
tab[index] = e.next;
}
count--;
- return e.check();
+ return e.get();
}
}
return null;
@@ -322,7 +337,7 @@
public boolean hasMoreElements() {
while (index >= 0) {
while (entry != null)
- if (entry.check() != null)
+ if (entry.get() != null)
return true;
else
entry = entry.next;
@@ -338,8 +353,8 @@
if (entry != null) {
CacheEntry e = entry;
entry = e.next;
- if (e.check() != null)
- return keys ? e.key : e.check();
+ if (e.get() != null)
+ return keys ? e.key : e.get();
}
}
throw new NoSuchElementException("CacheEnumerator");
# Deletion of sun.misc.Ref elided.