8149925: We don't need jdk.internal.ref.Cleaner any more - part1
Summary: 1st part of removing legacy jdk.internal.ref.Cleaner
Reviewed-by: chegar, mchung
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java Wed Mar 09 13:37:30 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java Wed Mar 09 21:17:06 2016 +0100
@@ -30,7 +30,7 @@
import static java.lang.invoke.MethodHandleNatives.Constants.*;
import static java.lang.invoke.MethodHandleStatics.*;
import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
-import jdk.internal.ref.Cleaner;
+import jdk.internal.ref.CleanerFactory;
/**
* The JVM interface for the method handles package is all here.
@@ -68,10 +68,12 @@
static CallSiteContext make(CallSite cs) {
final CallSiteContext newContext = new CallSiteContext();
- // Cleaner is attached to CallSite instance and it clears native structures allocated for CallSite context.
- // Though the CallSite can become unreachable, its Context is retained by the Cleaner instance (which is
- // referenced from Cleaner class) until cleanup is performed.
- Cleaner.create(cs, newContext);
+ // CallSite instance is tracked by a Cleanable which clears native
+ // structures allocated for CallSite context. Though the CallSite can
+ // become unreachable, its Context is retained by the Cleanable instance
+ // (which is referenced from Cleaner instance which is referenced from
+ // CleanerFactory class) until cleanup is performed.
+ CleanerFactory.cleaner().register(cs, newContext);
return newContext;
}
--- a/jdk/src/java.base/share/classes/java/lang/ref/Cleaner.java Wed Mar 09 13:37:30 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/ref/Cleaner.java Wed Mar 09 21:17:06 2016 +0100
@@ -25,10 +25,11 @@
package java.lang.ref;
+import jdk.internal.ref.CleanerImpl;
+
import java.util.Objects;
import java.util.concurrent.ThreadFactory;
-
-import jdk.internal.ref.CleanerImpl;
+import java.util.function.Function;
/**
* {@code Cleaner} manages a set of object references and corresponding cleaning actions.
@@ -135,7 +136,12 @@
final CleanerImpl impl;
static {
- CleanerImpl.setCleanerImplAccess((Cleaner c) -> c.impl);
+ CleanerImpl.setCleanerImplAccess(new Function<Cleaner, CleanerImpl>() {
+ @Override
+ public CleanerImpl apply(Cleaner cleaner) {
+ return cleaner.impl;
+ }
+ });
}
/**
--- a/jdk/src/java.base/share/classes/jdk/internal/misc/InnocuousThread.java Wed Mar 09 13:37:30 2016 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/InnocuousThread.java Wed Mar 09 21:17:06 2016 +0100
@@ -128,8 +128,12 @@
}
final ThreadGroup root = group;
INNOCUOUSTHREADGROUP = AccessController.doPrivileged(
- (PrivilegedAction<ThreadGroup>) () ->
- { return new ThreadGroup(root, "InnocuousThreadGroup"); });
+ new PrivilegedAction<ThreadGroup>() {
+ @Override
+ public ThreadGroup run() {
+ return new ThreadGroup(root, "InnocuousThreadGroup");
+ }
+ });
} catch (Exception e) {
throw new Error(e);
}
--- a/jdk/src/java.base/share/classes/jdk/internal/ref/CleanerImpl.java Wed Mar 09 13:37:30 2016 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/ref/CleanerImpl.java Wed Mar 09 21:17:06 2016 +0100
@@ -31,6 +31,7 @@
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import jdk.internal.misc.InnocuousThread;
@@ -39,7 +40,7 @@
* CleanerImpl manages a set of object references and corresponding cleaning actions.
* CleanerImpl provides the functionality of {@link java.lang.ref.Cleaner}.
*/
-public final class CleanerImpl {
+public final class CleanerImpl implements Runnable {
/**
* An object to access the CleanerImpl from a Cleaner; set by Cleaner init.
@@ -103,7 +104,7 @@
}
// schedule a nop cleaning action for the cleaner, so the associated thread
// will continue to run at least until the cleaner is reclaimable.
- new PhantomCleanableRef(cleaner, cleaner, () -> {});
+ new CleanerCleanable(cleaner);
if (threadFactory == null) {
threadFactory = CleanerImpl.InnocuousThreadFactory.factory();
@@ -112,7 +113,7 @@
// now that there's at least one cleaning action, for the cleaner,
// we can start the associated thread, which runs until
// all cleaning actions have been run.
- Thread thread = threadFactory.newThread(this::run);
+ Thread thread = threadFactory.newThread(this);
thread.setDaemon(true);
thread.start();
}
@@ -128,7 +129,8 @@
* If the thread is a ManagedLocalsThread, the threadlocals
* are erased before each cleanup
*/
- private void run() {
+ @Override
+ public void run() {
Thread t = Thread.currentThread();
InnocuousThread mlThread = (t instanceof InnocuousThread)
? (InnocuousThread) t
@@ -147,10 +149,9 @@
if (ref != null) {
ref.clean();
}
- } catch (InterruptedException i) {
- continue; // ignore the interruption
} catch (Throwable e) {
// ignore exceptions from the cleanup action
+ // (including interruption of cleanup thread)
}
}
}
@@ -320,14 +321,32 @@
return factory;
}
+ final AtomicInteger cleanerThreadNumber = new AtomicInteger();
+
public Thread newThread(Runnable r) {
- return AccessController.doPrivileged((PrivilegedAction<Thread>) () -> {
- Thread t = new InnocuousThread(r);
- t.setPriority(Thread.MAX_PRIORITY - 2);
- t.setName("Cleaner-" + t.getId());
- return t;
+ return AccessController.doPrivileged(new PrivilegedAction<Thread>() {
+ @Override
+ public Thread run() {
+ Thread t = new InnocuousThread(r);
+ t.setPriority(Thread.MAX_PRIORITY - 2);
+ t.setName("Cleaner-" + cleanerThreadNumber.getAndIncrement());
+ return t;
+ }
});
}
}
+ /**
+ * A PhantomCleanable implementation for tracking the Cleaner itself.
+ */
+ static final class CleanerCleanable extends PhantomCleanable<Cleaner> {
+ CleanerCleanable(Cleaner cleaner) {
+ super(cleaner, cleaner);
+ }
+
+ @Override
+ protected void performCleanup() {
+ // no action
+ }
+ }
}
--- a/jdk/src/java.base/share/classes/sun/nio/ch/IOVecWrapper.java Wed Mar 09 13:37:30 2016 +0000
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/IOVecWrapper.java Wed Mar 09 21:17:06 2016 +0100
@@ -26,7 +26,7 @@
package sun.nio.ch;
import java.nio.ByteBuffer;
-import jdk.internal.ref.Cleaner;
+import jdk.internal.ref.CleanerFactory;
/**
@@ -101,7 +101,7 @@
}
if (wrapper == null) {
wrapper = new IOVecWrapper(size);
- Cleaner.create(wrapper, new Deallocator(wrapper.vecArray));
+ CleanerFactory.cleaner().register(wrapper, new Deallocator(wrapper.vecArray));
cached.set(wrapper);
}
return wrapper;
--- a/jdk/src/java.base/share/classes/sun/nio/ch/Util.java Wed Mar 09 13:37:30 2016 +0000
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/Util.java Wed Mar 09 21:17:06 2016 +0100
@@ -33,7 +33,6 @@
import java.security.PrivilegedAction;
import java.util.*;
import jdk.internal.misc.Unsafe;
-import jdk.internal.ref.Cleaner;
import sun.security.action.GetPropertyAction;
--- a/jdk/src/java.base/share/classes/sun/nio/fs/NativeBuffer.java Wed Mar 09 13:37:30 2016 +0000
+++ b/jdk/src/java.base/share/classes/sun/nio/fs/NativeBuffer.java Wed Mar 09 21:17:06 2016 +0100
@@ -26,7 +26,9 @@
package sun.nio.fs;
import jdk.internal.misc.Unsafe;
-import jdk.internal.ref.Cleaner;
+import jdk.internal.ref.CleanerFactory;
+
+import java.lang.ref.Cleaner;
/**
* A light-weight buffer in native memory.
@@ -37,7 +39,7 @@
private final long address;
private final int size;
- private final Cleaner cleaner;
+ private final Cleaner.Cleanable cleanable;
// optional "owner" to avoid copying
// (only safe for use by thread-local caches)
@@ -56,7 +58,7 @@
NativeBuffer(int size) {
this.address = unsafe.allocateMemory(size);
this.size = size;
- this.cleaner = Cleaner.create(this, new Deallocator(address));
+ this.cleanable = CleanerFactory.cleaner().register(this, new Deallocator(address));
}
void release() {
@@ -71,8 +73,8 @@
return size;
}
- Cleaner cleaner() {
- return cleaner;
+ void free() {
+ cleanable.clean();
}
// not synchronized; only safe for use by thread-local caches
--- a/jdk/src/java.base/share/classes/sun/nio/fs/NativeBuffers.java Wed Mar 09 13:37:30 2016 +0000
+++ b/jdk/src/java.base/share/classes/sun/nio/fs/NativeBuffers.java Wed Mar 09 21:17:06 2016 +0100
@@ -107,14 +107,14 @@
for (int i=0; i<TEMP_BUF_POOL_SIZE; i++) {
NativeBuffer existing = buffers[i];
if (existing.size() < buffer.size()) {
- existing.cleaner().clean();
+ existing.free();
buffers[i] = buffer;
return;
}
}
// free it
- buffer.cleaner().clean();
+ buffer.free();
}
/**
--- a/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsWatchService.java Wed Mar 09 13:37:30 2016 +0000
+++ b/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsWatchService.java Wed Mar 09 21:17:06 2016 +0100
@@ -463,7 +463,7 @@
}
CloseHandle(key.handle());
closeAttachedEvent(key.overlappedAddress());
- key.buffer().cleaner().clean();
+ key.buffer().free();
}
/**