changeset 35641:da165fd9c886

8148117: Move sun.misc.Cleaner to jdk.internal.ref Reviewed-by: alanb, rriggs
author chegar
date Tue, 02 Feb 2016 08:59:52 +0000
parents f4936025bbea
children e45a64dce0f6
files jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java jdk/src/java.base/share/classes/java/lang/ref/Reference.java jdk/src/java.base/share/classes/java/nio/Direct-X-Buffer.java.template jdk/src/java.base/share/classes/jdk/internal/ref/Cleaner.java jdk/src/java.base/share/classes/sun/misc/Cleaner.java jdk/src/java.base/share/classes/sun/nio/ch/DirectBuffer.java jdk/src/java.base/share/classes/sun/nio/ch/FileChannelImpl.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/test/TEST.groups jdk/test/jdk/internal/ref/Cleaner/ExitOnThrow.java jdk/test/sun/misc/Cleaner/ExitOnThrow.java jdk/test/sun/misc/Cleaner/exitOnThrow.sh
diffstat 14 files changed, 248 insertions(+), 256 deletions(-) [+]
line wrap: on
line diff
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java	Tue Feb 02 09:39:20 2016 +0800
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java	Tue Feb 02 08:59:52 2016 +0000
@@ -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 sun.misc.Cleaner;
+import jdk.internal.ref.Cleaner;
 
 /**
  * The JVM interface for the method handles package is all here.
--- a/jdk/src/java.base/share/classes/java/lang/ref/Reference.java	Tue Feb 02 09:39:20 2016 +0800
+++ b/jdk/src/java.base/share/classes/java/lang/ref/Reference.java	Tue Feb 02 08:59:52 2016 +0000
@@ -26,10 +26,10 @@
 package java.lang.ref;
 
 import jdk.internal.vm.annotation.DontInline;
-import sun.misc.Cleaner;
 import jdk.internal.HotSpotIntrinsicCandidate;
 import jdk.internal.misc.JavaLangRefAccess;
 import jdk.internal.misc.SharedSecrets;
+import jdk.internal.ref.Cleaner;
 
 /**
  * Abstract base class for reference objects.  This class defines the
--- a/jdk/src/java.base/share/classes/java/nio/Direct-X-Buffer.java.template	Tue Feb 02 09:39:20 2016 +0800
+++ b/jdk/src/java.base/share/classes/java/nio/Direct-X-Buffer.java.template	Tue Feb 02 08:59:52 2016 +0000
@@ -28,9 +28,9 @@
 package java.nio;
 
 import java.io.FileDescriptor;
-import sun.misc.Cleaner;
 import jdk.internal.misc.Unsafe;
 import jdk.internal.misc.VM;
+import jdk.internal.ref.Cleaner;
 import sun.nio.ch.DirectBuffer;
 
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/ref/Cleaner.java	Tue Feb 02 08:59:52 2016 +0000
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2003, 2013, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.ref;
+
+import java.lang.ref.*;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+
+/**
+ * General-purpose phantom-reference-based cleaners.
+ *
+ * <p> Cleaners are a lightweight and more robust alternative to finalization.
+ * They are lightweight because they are not created by the VM and thus do not
+ * require a JNI upcall to be created, and because their cleanup code is
+ * invoked directly by the reference-handler thread rather than by the
+ * finalizer thread.  They are more robust because they use phantom references,
+ * the weakest type of reference object, thereby avoiding the nasty ordering
+ * problems inherent to finalization.
+ *
+ * <p> A cleaner tracks a referent object and encapsulates a thunk of arbitrary
+ * cleanup code.  Some time after the GC detects that a cleaner's referent has
+ * become phantom-reachable, the reference-handler thread will run the cleaner.
+ * Cleaners may also be invoked directly; they are thread safe and ensure that
+ * they run their thunks at most once.
+ *
+ * <p> Cleaners are not a replacement for finalization.  They should be used
+ * only when the cleanup code is extremely simple and straightforward.
+ * Nontrivial cleaners are inadvisable since they risk blocking the
+ * reference-handler thread and delaying further cleanup and finalization.
+ *
+ *
+ * @author Mark Reinhold
+ */
+
+public class Cleaner
+    extends PhantomReference<Object>
+    implements Runnable
+{
+
+    // Dummy reference queue, needed because the PhantomReference constructor
+    // insists that we pass a queue.  Nothing will ever be placed on this queue
+    // since the reference handler invokes cleaners explicitly.
+    //
+    private static final ReferenceQueue<Object> dummyQueue = new ReferenceQueue<>();
+
+    // Doubly-linked list of live cleaners, which prevents the cleaners
+    // themselves from being GC'd before their referents
+    //
+    private static Cleaner first = null;
+
+    private Cleaner
+        next = null,
+        prev = null;
+
+    private static synchronized Cleaner add(Cleaner cl) {
+        if (first != null) {
+            cl.next = first;
+            first.prev = cl;
+        }
+        first = cl;
+        return cl;
+    }
+
+    private static synchronized boolean remove(Cleaner cl) {
+
+        // If already removed, do nothing
+        if (cl.next == cl)
+            return false;
+
+        // Update list
+        if (first == cl) {
+            if (cl.next != null)
+                first = cl.next;
+            else
+                first = cl.prev;
+        }
+        if (cl.next != null)
+            cl.next.prev = cl.prev;
+        if (cl.prev != null)
+            cl.prev.next = cl.next;
+
+        // Indicate removal by pointing the cleaner to itself
+        cl.next = cl;
+        cl.prev = cl;
+        return true;
+
+    }
+
+    private final Runnable thunk;
+
+    private Cleaner(Object referent, Runnable thunk) {
+        super(referent, dummyQueue);
+        this.thunk = thunk;
+    }
+
+    /**
+     * Creates a new cleaner.
+     *
+     * @param  ob the referent object to be cleaned
+     * @param  thunk
+     *         The cleanup code to be run when the cleaner is invoked.  The
+     *         cleanup code is run directly from the reference-handler thread,
+     *         so it should be as simple and straightforward as possible.
+     *
+     * @return  The new cleaner
+     */
+    public static Cleaner create(Object ob, Runnable thunk) {
+        if (thunk == null)
+            return null;
+        return add(new Cleaner(ob, thunk));
+    }
+
+    /**
+     * Runs this cleaner, if it has not been run before.
+     */
+    public void clean() {
+        if (!remove(this))
+            return;
+        try {
+            thunk.run();
+        } catch (final Throwable x) {
+            AccessController.doPrivileged(new PrivilegedAction<>() {
+                    public Void run() {
+                        if (System.err != null)
+                            new Error("Cleaner terminated abnormally", x)
+                                .printStackTrace();
+                        System.exit(1);
+                        return null;
+                    }});
+        }
+    }
+
+    @Override public void run() {
+        SecurityManager security = System.getSecurityManager();
+        if (security != null)
+            security.checkPackageAccess("jdk.internal.ref");
+        this.clean();
+    }
+
+}
--- a/jdk/src/java.base/share/classes/sun/misc/Cleaner.java	Tue Feb 02 09:39:20 2016 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,156 +0,0 @@
-/*
- * Copyright (c) 2003, 2013, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.misc;
-
-import java.lang.ref.*;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-
-
-/**
- * General-purpose phantom-reference-based cleaners.
- *
- * <p> Cleaners are a lightweight and more robust alternative to finalization.
- * They are lightweight because they are not created by the VM and thus do not
- * require a JNI upcall to be created, and because their cleanup code is
- * invoked directly by the reference-handler thread rather than by the
- * finalizer thread.  They are more robust because they use phantom references,
- * the weakest type of reference object, thereby avoiding the nasty ordering
- * problems inherent to finalization.
- *
- * <p> A cleaner tracks a referent object and encapsulates a thunk of arbitrary
- * cleanup code.  Some time after the GC detects that a cleaner's referent has
- * become phantom-reachable, the reference-handler thread will run the cleaner.
- * Cleaners may also be invoked directly; they are thread safe and ensure that
- * they run their thunks at most once.
- *
- * <p> Cleaners are not a replacement for finalization.  They should be used
- * only when the cleanup code is extremely simple and straightforward.
- * Nontrivial cleaners are inadvisable since they risk blocking the
- * reference-handler thread and delaying further cleanup and finalization.
- *
- *
- * @author Mark Reinhold
- */
-
-public class Cleaner
-    extends PhantomReference<Object>
-{
-
-    // Dummy reference queue, needed because the PhantomReference constructor
-    // insists that we pass a queue.  Nothing will ever be placed on this queue
-    // since the reference handler invokes cleaners explicitly.
-    //
-    private static final ReferenceQueue<Object> dummyQueue = new ReferenceQueue<>();
-
-    // Doubly-linked list of live cleaners, which prevents the cleaners
-    // themselves from being GC'd before their referents
-    //
-    private static Cleaner first = null;
-
-    private Cleaner
-        next = null,
-        prev = null;
-
-    private static synchronized Cleaner add(Cleaner cl) {
-        if (first != null) {
-            cl.next = first;
-            first.prev = cl;
-        }
-        first = cl;
-        return cl;
-    }
-
-    private static synchronized boolean remove(Cleaner cl) {
-
-        // If already removed, do nothing
-        if (cl.next == cl)
-            return false;
-
-        // Update list
-        if (first == cl) {
-            if (cl.next != null)
-                first = cl.next;
-            else
-                first = cl.prev;
-        }
-        if (cl.next != null)
-            cl.next.prev = cl.prev;
-        if (cl.prev != null)
-            cl.prev.next = cl.next;
-
-        // Indicate removal by pointing the cleaner to itself
-        cl.next = cl;
-        cl.prev = cl;
-        return true;
-
-    }
-
-    private final Runnable thunk;
-
-    private Cleaner(Object referent, Runnable thunk) {
-        super(referent, dummyQueue);
-        this.thunk = thunk;
-    }
-
-    /**
-     * Creates a new cleaner.
-     *
-     * @param  ob the referent object to be cleaned
-     * @param  thunk
-     *         The cleanup code to be run when the cleaner is invoked.  The
-     *         cleanup code is run directly from the reference-handler thread,
-     *         so it should be as simple and straightforward as possible.
-     *
-     * @return  The new cleaner
-     */
-    public static Cleaner create(Object ob, Runnable thunk) {
-        if (thunk == null)
-            return null;
-        return add(new Cleaner(ob, thunk));
-    }
-
-    /**
-     * Runs this cleaner, if it has not been run before.
-     */
-    public void clean() {
-        if (!remove(this))
-            return;
-        try {
-            thunk.run();
-        } catch (final Throwable x) {
-            AccessController.doPrivileged(new PrivilegedAction<>() {
-                    public Void run() {
-                        if (System.err != null)
-                            new Error("Cleaner terminated abnormally", x)
-                                .printStackTrace();
-                        System.exit(1);
-                        return null;
-                    }});
-        }
-    }
-
-}
--- a/jdk/src/java.base/share/classes/sun/nio/ch/DirectBuffer.java	Tue Feb 02 09:39:20 2016 +0800
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/DirectBuffer.java	Tue Feb 02 08:59:52 2016 +0000
@@ -25,7 +25,7 @@
 
 package sun.nio.ch;
 
-import sun.misc.Cleaner;
+import jdk.internal.ref.Cleaner;
 
 
 public interface DirectBuffer {
--- a/jdk/src/java.base/share/classes/sun/nio/ch/FileChannelImpl.java	Tue Feb 02 09:39:20 2016 +0800
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/FileChannelImpl.java	Tue Feb 02 08:59:52 2016 +0000
@@ -47,7 +47,7 @@
 import jdk.internal.misc.JavaIOFileDescriptorAccess;
 import jdk.internal.misc.JavaNioAccess;
 import jdk.internal.misc.SharedSecrets;
-import sun.misc.Cleaner;
+import jdk.internal.ref.Cleaner;
 import sun.security.action.GetPropertyAction;
 
 public class FileChannelImpl
--- a/jdk/src/java.base/share/classes/sun/nio/ch/IOVecWrapper.java	Tue Feb 02 09:39:20 2016 +0800
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/IOVecWrapper.java	Tue Feb 02 08:59:52 2016 +0000
@@ -26,7 +26,7 @@
 package sun.nio.ch;
 
 import java.nio.ByteBuffer;
-import sun.misc.*;
+import jdk.internal.ref.Cleaner;
 
 
 /**
--- a/jdk/src/java.base/share/classes/sun/nio/ch/Util.java	Tue Feb 02 09:39:20 2016 +0800
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/Util.java	Tue Feb 02 08:59:52 2016 +0000
@@ -33,7 +33,7 @@
 import java.security.PrivilegedAction;
 import java.util.*;
 import jdk.internal.misc.Unsafe;
-import sun.misc.Cleaner;
+import jdk.internal.ref.Cleaner;
 import sun.security.action.GetPropertyAction;
 
 
--- a/jdk/src/java.base/share/classes/sun/nio/fs/NativeBuffer.java	Tue Feb 02 09:39:20 2016 +0800
+++ b/jdk/src/java.base/share/classes/sun/nio/fs/NativeBuffer.java	Tue Feb 02 08:59:52 2016 +0000
@@ -26,7 +26,7 @@
 package sun.nio.fs;
 
 import jdk.internal.misc.Unsafe;
-import sun.misc.Cleaner;
+import jdk.internal.ref.Cleaner;
 
 /**
  * A light-weight buffer in native memory.
--- a/jdk/test/TEST.groups	Tue Feb 02 09:39:20 2016 +0800
+++ b/jdk/test/TEST.groups	Tue Feb 02 08:59:52 2016 +0000
@@ -78,6 +78,7 @@
     sun/reflect \
     jdk/lambda \
     jdk/internal/misc \
+    jdk/internal/ref \
     vm
 
 # All of the java.util package
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/jdk/internal/ref/Cleaner/ExitOnThrow.java	Tue Feb 02 08:59:52 2016 +0000
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2003, 2013, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4954921 8009259
+ * @library /test/lib/share/classes
+ * @build jdk.test.lib.*
+ * @build jdk.test.lib.process.*
+ * @run main ExitOnThrow
+ * @summary Ensure that if a cleaner throws an exception then the VM exits
+ */
+import java.util.Arrays;
+
+import jdk.internal.ref.Cleaner;
+import jdk.test.lib.JDKToolLauncher;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+public class ExitOnThrow {
+
+    static final String cp = System.getProperty("test.classes", ".");
+
+    public static void main(String[] args) throws Exception {
+        if (args.length == 0) {
+            String[] cmd = JDKToolLauncher.createUsingTestJDK("java")
+                                          .addToolArg("-cp")
+                                          .addToolArg(cp)
+                                          .addToolArg("ExitOnThrow")
+                                          .addToolArg("-executeCleaner")
+                                          .getCommand();
+            ProcessBuilder pb = new ProcessBuilder(cmd);
+            OutputAnalyzer out = ProcessTools.executeProcess(pb);
+            System.out.println("======================");
+            System.out.println(Arrays.toString(cmd));
+            String msg = " stdout: [" + out.getStdout() + "]\n" +
+                         " stderr: [" + out.getStderr() + "]\n" +
+                         " exitValue = " + out.getExitValue() + "\n";
+            System.out.println(msg);
+
+            if (out.getExitValue() != 1)
+                throw new RuntimeException("Unexpected exit code: " +
+                                           out.getExitValue());
+
+        } else {
+            Cleaner.create(new Object(),
+                           () -> { throw new RuntimeException("Foo!"); } );
+            while (true) {
+                System.gc();
+                Thread.sleep(100);
+            }
+        }
+    }
+
+}
--- a/jdk/test/sun/misc/Cleaner/ExitOnThrow.java	Tue Feb 02 09:39:20 2016 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2003, 2013, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-//
-
-import sun.misc.*;
-
-
-public class ExitOnThrow {
-
-    public static void main(String[] args) throws Exception {
-        Cleaner.create(new Object(),
-                       new Runnable() {
-                               public void run() {
-                                   throw new RuntimeException("Foo!");
-                               }
-                           });
-        while (true) {
-            System.gc();
-            Thread.sleep(100);
-        }
-    }
-
-}
--- a/jdk/test/sun/misc/Cleaner/exitOnThrow.sh	Tue Feb 02 09:39:20 2016 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-#! /bin/sh
-
-#
-# Copyright (c) 2003, 2012, 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
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-
-#
-# @test
-# @bug 4954921 8009259
-# @summary Ensure that if a cleaner throws an exception then the VM exits
-#
-# @build ExitOnThrow
-# @run shell exitOnThrow.sh
-
-# Command-line usage: sh exitOnThrow.sh /path/to/build
-
-if [ -z "$TESTJAVA" ]; then
-  if [ $# -lt 1 ]; then exit 1; fi
-  TESTJAVA=$1; shift
-  TESTCLASSES=`pwd`
-fi
-
-if $TESTJAVA/bin/java ${TESTVMOPTS} -cp $TESTCLASSES ExitOnThrow; then
-  echo Failed: VM exited normally
-  exit 1
-else
-  echo Passed: VM exited with code $?
-  exit 0
-fi