8149925: We don't need jdk.internal.ref.Cleaner any more - part1
authorplevart
Wed, 09 Mar 2016 21:17:06 +0100
changeset 36435 0408881ad616
parent 36434 3fd8dee1b158
child 36436 c538d4a57e10
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
jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java
jdk/src/java.base/share/classes/java/lang/ref/Cleaner.java
jdk/src/java.base/share/classes/jdk/internal/misc/InnocuousThread.java
jdk/src/java.base/share/classes/jdk/internal/ref/CleanerImpl.java
jdk/src/java.base/share/classes/sun/nio/ch/IOVecWrapper.java
jdk/src/java.base/share/classes/sun/nio/ch/Util.java
jdk/src/java.base/share/classes/sun/nio/fs/NativeBuffer.java
jdk/src/java.base/share/classes/sun/nio/fs/NativeBuffers.java
jdk/src/java.base/windows/classes/sun/nio/fs/WindowsWatchService.java
--- 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();
         }
 
         /**