Mandy Chung wrote:
6810254: Lazily instantiate the shared secret access objects
Webrev at:
http://cr.openjdk.java.net/~mchung/6810254/webrev.00/
sun.misc.Java*Access objects are created at initialization time.
However, they are not always needed. They can be instantiated lazily
when needed. The fix is to add a static setSharedSecret() method to
be called by sun.misc.SharedSecrets via reflection when the shared
secret access object is requested.
Thanks
Mandy
It's good to see the setup of the shutdown hooks being removed from the
initialization. However, I think it might be cleaner have each register
itself lazily rather than SharedSecrets knowing about it. That has the
added benefit that only the needed hooks are registered. It also avoids
needing the reflection code. A possible downside is that each hook needs
to know its place in the world. Attached is a (completely unpolished)
patch that does this and perhaps it would be useful to try.
-Alan.
--- old/src/share/classes/java/io/Console.java Fri Mar 6 14:49:26 2009
+++ new/src/share/classes/java/io/Console.java Fri Mar 6 14:49:25 2009
@@ -503,6 +503,18 @@
// Set up JavaIOAccess in SharedSecrets
static {
+
+ // Add a shutdown hook to restore console's echo state should
+ // it be necessary.
+ sun.misc.SharedSecrets.getJavaLangAccess()
+ .registerShutdownHook(new Runnable() {
+ public void run() {
+ try {
+ if (echoOff) echo(true);
+ } catch (IOException x) { }
+ }
+ }, 0); // slot 0
+
sun.misc.SharedSecrets.setJavaIOAccess(new sun.misc.JavaIOAccess() {
public Console console() {
if (istty()) {
@@ -513,20 +525,6 @@
return null;
}
- // Add a shutdown hook to restore console's echo state should
- // it be necessary.
- public Runnable consoleRestoreHook() {
- return new Runnable() {
- public void run() {
- try {
- if (echoOff) {
- echo(true);
- }
- } catch (IOException x) {}
- }
- };
- }
-
public Charset charset() {
// This method is called in sun.security.util.Password,
// cons already exists when this method is called
--- old/src/share/classes/java/io/DeleteOnExitHook.java Fri Mar 6 14:49:28 2009
+++ new/src/share/classes/java/io/DeleteOnExitHook.java Fri Mar 6 14:49:27 2009
@@ -34,17 +34,17 @@
*/
class DeleteOnExitHook {
- private static DeleteOnExitHook instance = null;
+ static {
+ sun.misc.SharedSecrets.getJavaLangAccess()
+ .registerShutdownHook(new Runnable() {
+ public void run() {
+ runHooks();
+ }
+ }, 2);
+ }
private static LinkedHashSet<String> files = new LinkedHashSet<String>();
- static DeleteOnExitHook hook() {
- if (instance == null)
- instance = new DeleteOnExitHook();
-
- return instance;
- }
-
private DeleteOnExitHook() {}
static synchronized void add(String file) {
@@ -54,7 +54,7 @@
files.add(file);
}
- void run() {
+ static void runHooks() {
LinkedHashSet<String> theFiles;
synchronized (DeleteOnExitHook.class) {
--- old/src/share/classes/java/io/File.java Fri Mar 6 14:49:30 2009
+++ new/src/share/classes/java/io/File.java Fri Mar 6 14:49:29 2009
@@ -2147,18 +2147,6 @@
/** use serialVersionUID from JDK 1.0.2 for interoperability */
private static final long serialVersionUID = 301077366599181567L;
- // Set up JavaIODeleteOnExitAccess in SharedSecrets
- // Added here as DeleteOnExitHook is package-private and SharedSecrets cannot easily access it.
- static {
- sun.misc.SharedSecrets.setJavaIODeleteOnExitAccess(
- new sun.misc.JavaIODeleteOnExitAccess() {
- public void run() {
- DeleteOnExitHook.hook().run();
- }
- }
- );
- }
-
// -- Integration with java.nio.file --
private volatile transient Path filePath;
--- old/src/share/classes/java/lang/ApplicationShutdownHooks.java Fri Mar 6 14:49:32 2009
+++ new/src/share/classes/java/lang/ApplicationShutdownHooks.java Fri Mar 6 14:49:31 2009
@@ -34,19 +34,17 @@
* @see java.lang.Runtime#removeShutdownHook
*/
-class ApplicationShutdownHooks implements Runnable {
- private static ApplicationShutdownHooks instance = null;
+class ApplicationShutdownHooks {
+ static {
+ Shutdown.add(new Runnable() {
+ public void run() {
+ runHooks();
+ }}, 1);
+ }
/* The set of registered hooks */
private static IdentityHashMap<Thread, Thread> hooks = new IdentityHashMap<Thread, Thread>();
- static synchronized ApplicationShutdownHooks hook() {
- if (instance == null)
- instance = new ApplicationShutdownHooks();
-
- return instance;
- }
-
private ApplicationShutdownHooks() {}
/* Add a new shutdown hook. Checks the shutdown state and the hook itself,
@@ -82,7 +80,7 @@
* to run in. Hooks are run concurrently and this method waits for
* them to finish.
*/
- public void run() {
+ static void runHooks() {
Collection<Thread> threads;
synchronized(ApplicationShutdownHooks.class) {
threads = hooks.keySet();
--- old/src/share/classes/java/lang/Shutdown.java Fri Mar 6 14:49:34 2009
+++ new/src/share/classes/java/lang/Shutdown.java Fri Mar 6 14:49:33 2009
@@ -25,9 +25,7 @@
package java.lang;
-import java.util.ArrayList;
-
/**
* Package-private utility class containing data structures and logic
* governing the virtual-machine shutdown sequence.
@@ -48,7 +46,7 @@
private static boolean runFinalizersOnExit = false;
/* The set of registered, wrapped hooks, or null if there aren't any */
- private static ArrayList<Runnable> hooks = new ArrayList<Runnable>();
+ private static Runnable[] hooks = new Runnable[10];
/* The preceding static fields are protected by this lock */
private static class Lock { };
@@ -68,33 +66,18 @@
/* Add a new shutdown hook. Checks the shutdown state and the hook itself,
* but does not do any security checks.
*/
- static void add(Runnable hook) {
+ static void add(Runnable hook, int slot) {
synchronized (lock) {
if (state > RUNNING)
throw new IllegalStateException("Shutdown in progress");
- hooks.add(hook);
- }
- }
+ if (hooks[slot] != null)
+ throw new InternalError();
-
- /* Remove a previously-registered hook. Like the add method, this method
- * does not do any security checks.
- */
- static boolean remove(Runnable hook) {
- synchronized (lock) {
- if (state > RUNNING)
- throw new IllegalStateException("Shutdown in progress");
- if (hook == null) throw new NullPointerException();
- if (hooks == null) {
- return false;
- } else {
- return hooks.remove(hook);
- }
+ hooks[slot] = hook;
}
}
-
/* Run all registered shutdown hooks
*/
private static void runHooks() {
@@ -103,7 +86,7 @@
*/
for (Runnable hook : hooks) {
try {
- hook.run();
+ if (hook != null) hook.run();
} catch(Throwable t) {
if (t instanceof ThreadDeath) {
ThreadDeath td = (ThreadDeath)t;
--- old/src/share/classes/java/lang/System.java Fri Mar 6 14:49:36 2009
+++ new/src/share/classes/java/lang/System.java Fri Mar 6 14:49:35 2009
@@ -1121,14 +1121,6 @@
// Setup Java signal handlers for HUP, TERM, and INT (where available).
Terminator.setup();
- // The order in with the hooks are added here is important as it
- // determines the order in which they are run.
- // (1)Console restore hook needs to be called first.
- // (2)Application hooks must be run before calling deleteOnExitHook.
- Shutdown.add(sun.misc.SharedSecrets.getJavaIOAccess().consoleRestoreHook());
- Shutdown.add(ApplicationShutdownHooks.hook());
- Shutdown.add(sun.misc.SharedSecrets.getJavaIODeleteOnExitAccess());
-
// Initialize any miscellenous operating system settings that need to be
// set for the class libraries. Currently this is no-op everywhere except
// for Windows where the process-wide error mode is set before the java.io
@@ -1174,6 +1166,9 @@
public void blockedOn(Thread t, Interruptible b) {
t.blockedOn(b);
}
+ public void registerShutdownHook(Runnable r, int slot) {
+ Shutdown.add(r, slot);
+ }
});
}
--- old/src/share/classes/sun/misc/JavaIOAccess.java Fri Mar 6 14:49:38 2009
+++ new/src/share/classes/sun/misc/JavaIOAccess.java Fri Mar 6 14:49:37 2009
@@ -29,6 +29,5 @@
public interface JavaIOAccess {
public Console console();
- public Runnable consoleRestoreHook();
public Charset charset();
}
--- old/src/share/classes/sun/misc/JavaLangAccess.java Fri Mar 6 14:49:40 2009
+++ new/src/share/classes/sun/misc/JavaLangAccess.java Fri Mar 6 14:49:39 2009
@@ -54,4 +54,7 @@
/** Set thread's blocker field. */
void blockedOn(Thread t, Interruptible b);
+
+ /** register shutdown hook */
+ void registerShutdownHook(Runnable r, int slot);
}
--- old/src/share/classes/sun/misc/SharedSecrets.java Fri Mar 6 14:49:42 2009
+++ new/src/share/classes/sun/misc/SharedSecrets.java Fri Mar 6 14:49:41 2009
@@ -44,7 +44,6 @@
private static JavaUtilJarAccess javaUtilJarAccess;
private static JavaLangAccess javaLangAccess;
private static JavaIOAccess javaIOAccess;
- private static JavaIODeleteOnExitAccess javaIODeleteOnExitAccess;
private static JavaNetAccess javaNetAccess;
private static JavaNioAccess javaNioAccess;
private static JavaIOFileDescriptorAccess javaIOFileDescriptorAccess;
@@ -103,17 +102,6 @@
return javaIOAccess;
}
- public static void setJavaIODeleteOnExitAccess(JavaIODeleteOnExitAccess jida) {
- javaIODeleteOnExitAccess = jida;
- }
-
- public static JavaIODeleteOnExitAccess getJavaIODeleteOnExitAccess() {
- if (javaIODeleteOnExitAccess == null) {
- unsafe.ensureClassInitialized(File.class);
- }
- return javaIODeleteOnExitAccess;
- }
-
public static void setJavaIOFileDescriptorAccess(JavaIOFileDescriptorAccess jiofda) {
javaIOFileDescriptorAccess = jiofda;
}
--- old/src/share/classes/sun/misc/JavaIODeleteOnExitAccess.java Fri Mar 6 14:49:44 2009
+++ /dev/null Fri Mar 6 14:49:44 2009
@@ -1,30 +0,0 @@
-/*
- * Copyright 2005 Sun Microsystems, Inc. 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. Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-
-package sun.misc;
-
-public interface JavaIODeleteOnExitAccess extends Runnable {
- public void run();
-}