# HG changeset patch # User mchung # Date 1519416656 28800 # Node ID a6c4b85163c18d9182f32494e4ac983adf865c94 # Parent 4f11514fe783b9cf4da6a48487ac1223f5ea9bd1 8198249: Remove deprecated Runtime::runFinalizersOnExit and System::runFinalizersOnExit Reviewed-by: dholmes, alanb, smarks diff -r 4f11514fe783 -r a6c4b85163c1 make/mapfiles/libjava/mapfile-vers --- a/make/mapfiles/libjava/mapfile-vers Fri Feb 23 14:26:29 2018 -0500 +++ b/make/mapfiles/libjava/mapfile-vers Fri Feb 23 12:10:56 2018 -0800 @@ -143,7 +143,6 @@ Java_java_lang_StackStreamFactory_checkStackWalkModes; Java_java_lang_StackStreamFactory_00024AbstractStackWalker_callStackWalk; Java_java_lang_StackStreamFactory_00024AbstractStackWalker_fetchStackFrames; - Java_java_lang_Shutdown_runAllFinalizers; Java_java_lang_StrictMath_IEEEremainder; Java_java_lang_StrictMath_acos; Java_java_lang_StrictMath_asin; diff -r 4f11514fe783 -r a6c4b85163c1 src/hotspot/share/classfile/vmSymbols.hpp --- a/src/hotspot/share/classfile/vmSymbols.hpp Fri Feb 23 14:26:29 2018 -0500 +++ b/src/hotspot/share/classfile/vmSymbols.hpp Fri Feb 23 12:10:56 2018 -0800 @@ -358,7 +358,6 @@ template(reference_lock_name, "lock") \ template(reference_discovered_name, "discovered") \ template(run_finalization_name, "runFinalization") \ - template(run_finalizers_on_exit_name, "runFinalizersOnExit") \ template(dispatchUncaughtException_name, "dispatchUncaughtException") \ template(loadClass_name, "loadClass") \ template(loadClassInternal_name, "loadClassInternal") \ diff -r 4f11514fe783 -r a6c4b85163c1 src/hotspot/share/memory/universe.cpp --- a/src/hotspot/share/memory/universe.cpp Fri Feb 23 14:26:29 2018 -0500 +++ b/src/hotspot/share/memory/universe.cpp Fri Feb 23 12:10:56 2018 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2018, 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 @@ -542,32 +542,6 @@ #undef assert_pll_locked #undef assert_pll_ownership - -static bool has_run_finalizers_on_exit = false; - -void Universe::run_finalizers_on_exit() { - if (has_run_finalizers_on_exit) return; - has_run_finalizers_on_exit = true; - - // Called on VM exit. This ought to be run in a separate thread. - log_trace(ref)("Callback to run finalizers on exit"); - { - PRESERVE_EXCEPTION_MARK; - Klass* finalizer_klass = SystemDictionary::Finalizer_klass(); - JavaValue result(T_VOID); - JavaCalls::call_static( - &result, - finalizer_klass, - vmSymbols::run_finalizers_on_exit_name(), - vmSymbols::void_method_signature(), - THREAD - ); - // Ignore any pending exceptions - CLEAR_PENDING_EXCEPTION; - } -} - - // initialize_vtable could cause gc if // 1) we specified true to initialize_vtable and // 2) this ran after gc was enabled diff -r 4f11514fe783 -r a6c4b85163c1 src/hotspot/share/memory/universe.hpp --- a/src/hotspot/share/memory/universe.hpp Fri Feb 23 14:26:29 2018 -0500 +++ b/src/hotspot/share/memory/universe.hpp Fri Feb 23 12:10:56 2018 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2018, 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 @@ -464,9 +464,6 @@ static bool should_fill_in_stack_trace(Handle throwable); static void check_alignment(uintx size, uintx alignment, const char* name); - // Finalizer support. - static void run_finalizers_on_exit(); - // Iteration // Apply "f" to the addresses of all the direct heap pointers maintained diff -r 4f11514fe783 -r a6c4b85163c1 src/hotspot/share/runtime/thread.cpp --- a/src/hotspot/share/runtime/thread.cpp Fri Feb 23 14:26:29 2018 -0500 +++ b/src/hotspot/share/runtime/thread.cpp Fri Feb 23 12:10:56 2018 -0800 @@ -4202,10 +4202,9 @@ // SystemDictionary::resolve_or_null will return null if there was // an exception. If we cannot load the Shutdown class, just don't // call Shutdown.shutdown() at all. This will mean the shutdown hooks - // and finalizers (if runFinalizersOnExit is set) won't be run. - // Note that if a shutdown hook was registered or runFinalizersOnExit - // was called, the Shutdown class would have already been loaded - // (Runtime.addShutdownHook and runFinalizersOnExit will load it). + // won't be run. Note that if a shutdown hook was registered, + // the Shutdown class would have already been loaded + // (Runtime.addShutdownHook will load it). JavaValue result(T_VOID); JavaCalls::call_static(&result, shutdown_klass, @@ -4228,7 +4227,7 @@ // + Wait until we are the last non-daemon thread to execute // <-- every thing is still working at this moment --> // + Call java.lang.Shutdown.shutdown(), which will invoke Java level -// shutdown hooks, run finalizers if finalization-on-exit +// shutdown hooks // + Call before_exit(), prepare for VM exit // > run VM level shutdown hooks (they are registered through JVM_OnExit(), // currently the only user of this mechanism is File.deleteOnExit()) diff -r 4f11514fe783 -r a6c4b85163c1 src/java.base/share/classes/java/lang/Runtime.java --- a/src/java.base/share/classes/java/lang/Runtime.java Fri Feb 23 14:26:29 2018 -0500 +++ b/src/java.base/share/classes/java/lang/Runtime.java Fri Feb 23 12:10:56 2018 -0800 @@ -79,18 +79,14 @@ * serves as a status code; by convention, a nonzero status code indicates * abnormal termination. * - *

The virtual machine's shutdown sequence consists of two phases. In - * the first phase all registered {@link #addShutdownHook shutdown hooks}, - * if any, are started in some unspecified order and allowed to run - * concurrently until they finish. In the second phase all uninvoked - * finalizers are run if {@link #runFinalizersOnExit finalization-on-exit} - * has been enabled. Once this is done the virtual machine {@link #halt halts}. + *

All registered {@linkplain #addShutdownHook shutdown hooks}, if any, + * are started in some unspecified order and allowed to run concurrently + * until they finish. Once this is done the virtual machine + * {@linkplain #halt halts}. * - *

If this method is invoked after the virtual machine has begun its - * shutdown sequence then if shutdown hooks are being run this method will - * block indefinitely. If shutdown hooks have already been run and on-exit - * finalization has been enabled then this method halts the virtual machine - * with the given status code if the status is nonzero; otherwise, it + *

If this method is invoked after all shutdown hooks have already + * been run and the status is nonzero then this method halts the + * virtual machine with the given status code. Otherwise, this method * blocks indefinitely. * *

The {@link System#exit(int) System.exit} method is the @@ -109,7 +105,6 @@ * @see java.lang.SecurityManager#checkExit(int) * @see #addShutdownHook * @see #removeShutdownHook - * @see #runFinalizersOnExit * @see #halt(int) */ public void exit(int status) { @@ -142,10 +137,9 @@ * thread. When the virtual machine begins its shutdown sequence it will * start all registered shutdown hooks in some unspecified order and let * them run concurrently. When all the hooks have finished it will then - * run all uninvoked finalizers if finalization-on-exit has been enabled. - * Finally, the virtual machine will halt. Note that daemon threads will - * continue to run during the shutdown sequence, as will non-daemon threads - * if shutdown was initiated by invoking the {@link #exit exit} method. + * halt. Note that daemon threads will continue to run during the shutdown + * sequence, as will non-daemon threads if shutdown was initiated by + * invoking the {@link #exit exit} method. * *

Once the shutdown sequence has begun it can be stopped only by * invoking the {@link #halt halt} method, which forcibly @@ -255,10 +249,9 @@ * *

This method should be used with extreme caution. Unlike the * {@link #exit exit} method, this method does not cause shutdown - * hooks to be started and does not run uninvoked finalizers if - * finalization-on-exit has been enabled. If the shutdown sequence has - * already been initiated then this method does not wait for any running - * shutdown hooks or finalizers to finish their work. + * hooks to be started. If the shutdown sequence has already been + * initiated then this method does not wait for any running + * shutdown hooks to finish their work. * * @param status * Termination status. By convention, a nonzero status code @@ -286,46 +279,6 @@ } /** - * Enable or disable finalization on exit; doing so specifies that the - * finalizers of all objects that have finalizers that have not yet been - * automatically invoked are to be run before the Java runtime exits. - * By default, finalization on exit is disabled. - * - *

If there is a security manager, - * its {@code checkExit} method is first called - * with 0 as its argument to ensure the exit is allowed. - * This could result in a SecurityException. - * - * @param value true to enable finalization on exit, false to disable - * @deprecated This method is inherently unsafe. It may result in - * finalizers being called on live objects while other threads are - * concurrently manipulating those objects, resulting in erratic - * behavior or deadlock. - * This method is subject to removal in a future version of Java SE. - * - * @throws SecurityException - * if a security manager exists and its {@code checkExit} - * method doesn't allow the exit. - * - * @see java.lang.Runtime#exit(int) - * @see java.lang.Runtime#gc() - * @see java.lang.SecurityManager#checkExit(int) - * @since 1.1 - */ - @Deprecated(since="1.2", forRemoval=true) - public static void runFinalizersOnExit(boolean value) { - SecurityManager security = System.getSecurityManager(); - if (security != null) { - try { - security.checkExit(0); - } catch (SecurityException e) { - throw new SecurityException("runFinalizersOnExit"); - } - } - Shutdown.setRunFinalizersOnExit(value); - } - - /** * Executes the specified string command in a separate process. * *

This is a convenience method. An invocation of the form diff -r 4f11514fe783 -r a6c4b85163c1 src/java.base/share/classes/java/lang/Shutdown.java --- a/src/java.base/share/classes/java/lang/Shutdown.java Fri Feb 23 14:26:29 2018 -0500 +++ b/src/java.base/share/classes/java/lang/Shutdown.java Fri Feb 23 12:10:56 2018 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2018, 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 @@ -26,35 +26,33 @@ package java.lang; +import jdk.internal.misc.VM; + /** * Package-private utility class containing data structures and logic * governing the virtual-machine shutdown sequence. * * @author Mark Reinhold * @since 1.3 + * + * @see java.io.Console + * @see ApplicationShutdownHooks + * @see java.io.DeleteOnExitHook */ class Shutdown { - /* Shutdown state */ - private static final int RUNNING = 0; - private static final int HOOKS = 1; - private static final int FINALIZERS = 2; - private static int state = RUNNING; - - /* Should we run all finalizers upon exit? */ - private static boolean runFinalizersOnExit = false; - // The system shutdown hooks are registered with a predefined slot. // The list of shutdown hooks is as follows: // (0) Console restore hook - // (1) Application hooks + // (1) ApplicationShutdownHooks that invokes all registered application + // shutdown hooks and waits until they finish // (2) DeleteOnExit hook private static final int MAX_SYSTEM_HOOKS = 10; private static final Runnable[] hooks = new Runnable[MAX_SYSTEM_HOOKS]; // the index of the currently running shutdown hook to the hooks array - private static int currentRunningHook = 0; + private static int currentRunningHook = -1; /* The preceding static fields are protected by this lock */ private static class Lock { }; @@ -63,17 +61,9 @@ /* Lock object for the native halt method */ private static Object haltLock = new Lock(); - /* Invoked by Runtime.runFinalizersOnExit */ - static void setRunFinalizersOnExit(boolean run) { - synchronized (lock) { - runFinalizersOnExit = run; - } - } - - /** - * Add a new shutdown hook. Checks the shutdown state and the hook itself, - * but does not do any security checks. + * Add a new system shutdown hook. Checks the shutdown state and + * the hook itself, but does not do any security checks. * * The registerShutdownInProgress parameter should be false except * registering the DeleteOnExitHook since the first file may @@ -92,15 +82,18 @@ * already passes the given slot */ static void add(int slot, boolean registerShutdownInProgress, Runnable hook) { + if (slot < 0 || slot >= MAX_SYSTEM_HOOKS) { + throw new IllegalArgumentException("Invalid slot: " + slot); + } synchronized (lock) { if (hooks[slot] != null) throw new InternalError("Shutdown hook at slot " + slot + " already registered"); if (!registerShutdownInProgress) { - if (state > RUNNING) + if (currentRunningHook >= 0) throw new IllegalStateException("Shutdown in progress"); } else { - if (state > HOOKS || (state == HOOKS && slot <= currentRunningHook)) + if (VM.isShutdown() || slot <= currentRunningHook) throw new IllegalStateException("Shutdown in progress"); } @@ -108,9 +101,23 @@ } } - /* Run all registered shutdown hooks + /* Run all system shutdown hooks. + * + * The system shutdown hooks are run in the thread synchronized on + * Shutdown.class. Other threads calling Runtime::exit, Runtime::halt + * or JNI DestroyJavaVM will block indefinitely. + * + * ApplicationShutdownHooks is registered as one single hook that starts + * all application shutdown hooks and waits until they finish. */ private static void runHooks() { + synchronized (lock) { + /* Guard against the possibility of a daemon thread invoking exit + * after DestroyJavaVM initiates the shutdown sequence + */ + if (VM.isShutdown()) return; + } + for (int i=0; i < MAX_SYSTEM_HOOKS; i++) { try { Runnable hook; @@ -121,13 +128,16 @@ hook = hooks[i]; } if (hook != null) hook.run(); - } catch(Throwable t) { + } catch (Throwable t) { if (t instanceof ThreadDeath) { ThreadDeath td = (ThreadDeath)t; throw td; } } } + + // set shutdown state + VM.shutdown(); } /* The halt method is synchronized on the halt lock @@ -142,74 +152,22 @@ static native void halt0(int status); - /* Wormhole for invoking java.lang.ref.Finalizer.runAllFinalizers */ - private static native void runAllFinalizers(); - - - /* The actual shutdown sequence is defined here. - * - * If it weren't for runFinalizersOnExit, this would be simple -- we'd just - * run the hooks and then halt. Instead we need to keep track of whether - * we're running hooks or finalizers. In the latter case a finalizer could - * invoke exit(1) to cause immediate termination, while in the former case - * any further invocations of exit(n), for any n, simply stall. Note that - * if on-exit finalizers are enabled they're run iff the shutdown is - * initiated by an exit(0); they're never run on exit(n) for n != 0 or in - * response to SIGINT, SIGTERM, etc. - */ - private static void sequence() { - synchronized (lock) { - /* Guard against the possibility of a daemon thread invoking exit - * after DestroyJavaVM initiates the shutdown sequence - */ - if (state != HOOKS) return; - } - runHooks(); - boolean rfoe; - synchronized (lock) { - state = FINALIZERS; - rfoe = runFinalizersOnExit; - } - if (rfoe) runAllFinalizers(); - } - - /* Invoked by Runtime.exit, which does all the security checks. * Also invoked by handlers for system-provided termination events, * which should pass a nonzero status code. */ static void exit(int status) { - boolean runMoreFinalizers = false; synchronized (lock) { - if (status != 0) runFinalizersOnExit = false; - switch (state) { - case RUNNING: /* Initiate shutdown */ - state = HOOKS; - break; - case HOOKS: /* Stall and halt */ - break; - case FINALIZERS: - if (status != 0) { - /* Halt immediately on nonzero status */ - halt(status); - } else { - /* Compatibility with old behavior: - * Run more finalizers and then halt - */ - runMoreFinalizers = runFinalizersOnExit; - } - break; + if (status != 0 && VM.isShutdown()) { + /* Halt immediately on nonzero status */ + halt(status); } } - if (runMoreFinalizers) { - runAllFinalizers(); - halt(status); - } synchronized (Shutdown.class) { /* Synchronize on the class object, causing any other thread * that attempts to initiate shutdown to stall indefinitely */ - sequence(); + runHooks(); halt(status); } } @@ -220,18 +178,8 @@ * actually halt the VM. */ static void shutdown() { - synchronized (lock) { - switch (state) { - case RUNNING: /* Initiate shutdown */ - state = HOOKS; - break; - case HOOKS: /* Stall and then return */ - case FINALIZERS: - break; - } - } synchronized (Shutdown.class) { - sequence(); + runHooks(); } } diff -r 4f11514fe783 -r a6c4b85163c1 src/java.base/share/classes/java/lang/System.java --- a/src/java.base/share/classes/java/lang/System.java Fri Feb 23 14:26:29 2018 -0500 +++ b/src/java.base/share/classes/java/lang/System.java Fri Feb 23 12:10:56 2018 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2018, 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 @@ -1766,38 +1766,6 @@ } /** - * Enable or disable finalization on exit; doing so specifies that the - * finalizers of all objects that have finalizers that have not yet been - * automatically invoked are to be run before the Java runtime exits. - * By default, finalization on exit is disabled. - * - *

If there is a security manager, - * its checkExit method is first called - * with 0 as its argument to ensure the exit is allowed. - * This could result in a SecurityException. - * - * @deprecated This method is inherently unsafe. It may result in - * finalizers being called on live objects while other threads are - * concurrently manipulating those objects, resulting in erratic - * behavior or deadlock. - * This method is subject to removal in a future version of Java SE. - * @param value indicating enabling or disabling of finalization - * @throws SecurityException - * if a security manager exists and its checkExit - * method doesn't allow the exit. - * - * @see java.lang.Runtime#exit(int) - * @see java.lang.Runtime#gc() - * @see java.lang.SecurityManager#checkExit(int) - * @since 1.1 - */ - @Deprecated(since="1.2", forRemoval=true) - @SuppressWarnings("removal") - public static void runFinalizersOnExit(boolean value) { - Runtime.runFinalizersOnExit(value); - } - - /** * Loads the native library specified by the filename argument. The filename * argument must be an absolute path name. * diff -r 4f11514fe783 -r a6c4b85163c1 src/java.base/share/classes/java/lang/doc-files/threadPrimitiveDeprecation.html --- a/src/java.base/share/classes/java/lang/doc-files/threadPrimitiveDeprecation.html Fri Feb 23 14:26:29 2018 -0500 +++ b/src/java.base/share/classes/java/lang/doc-files/threadPrimitiveDeprecation.html Fri Feb 23 12:10:56 2018 -0800 @@ -1,6 +1,6 @@

diff -r 4f11514fe783 -r a6c4b85163c1 src/java.base/share/classes/java/lang/ref/Finalizer.java --- a/src/java.base/share/classes/java/lang/ref/Finalizer.java Fri Feb 23 14:26:29 2018 -0500 +++ b/src/java.base/share/classes/java/lang/ref/Finalizer.java Fri Feb 23 12:10:56 2018 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2018, 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 @@ -66,7 +66,7 @@ new Finalizer(finalizee); } - private void deregisterAndRunFinalizer(JavaLangAccess jla) { + private void runFinalizer(JavaLangAccess jla) { synchronized (lock) { if (this.next == this) // already finalized return; @@ -80,17 +80,14 @@ this.prev = null; this.next = this; // mark as finalized } - runFinalizer(jla); - } - private void runFinalizer(JavaLangAccess jla) { try { Object finalizee = this.get(); if (finalizee != null && !(finalizee instanceof java.lang.Enum)) { jla.invokeFinalize(finalizee); - /* Clear stack slot containing this variable, to decrease - the chances of false retention with a conservative GC */ + // Clear stack slot containing this variable, to decrease + // the chances of false retention with a conservative GC finalizee = null; } } catch (Throwable x) { } @@ -98,17 +95,14 @@ } /* Create a privileged secondary finalizer thread in the system thread - group for the given Runnable, and wait for it to complete. - - This method is used by both runFinalization and runFinalizersOnExit. - The former method invokes all pending finalizers, while the latter - invokes all uninvoked finalizers if on-exit finalization has been - enabled. - - These two methods could have been implemented by offloading their work - to the regular finalizer thread and waiting for that thread to finish. - The advantage of creating a fresh thread, however, is that it insulates - invokers of these methods from a stalled or deadlocked finalizer thread. + * group for the given Runnable, and wait for it to complete. + * + * This method is used by runFinalization. + * + * It could have been implemented by offloading the work to the + * regular finalizer thread and waiting for that thread to finish. + * The advantage of creating a fresh thread, however, is that it insulates + * invokers of that method from a stalled or deadlocked finalizer thread. */ private static void forkSecondaryFinalizer(final Runnable proc) { AccessController.doPrivileged( @@ -144,40 +138,11 @@ final JavaLangAccess jla = SharedSecrets.getJavaLangAccess(); running = true; for (Finalizer f; (f = (Finalizer)queue.poll()) != null; ) - f.deregisterAndRunFinalizer(jla); + f.runFinalizer(jla); } }); } - /* Invoked by java.lang.Shutdown */ - static void runAllFinalizers() { - if (VM.initLevel() == 0) { - return; - } - - forkSecondaryFinalizer(new Runnable() { - private volatile boolean running; - public void run() { - // in case of recursive call to run() - if (running) - return; - final JavaLangAccess jla = SharedSecrets.getJavaLangAccess(); - running = true; - for (;;) { - // "pollFirst" from unfinalized - Finalizer f; - synchronized (lock) { - f = unfinalized; - if (f == null) break; - unfinalized = f.next; - if (unfinalized != null) - unfinalized.prev = null; - f.next = f; // mark as finalized - } - f.runFinalizer(jla); - }}}); - } - private static class FinalizerThread extends Thread { private volatile boolean running; FinalizerThread(ThreadGroup g) { @@ -203,7 +168,7 @@ for (;;) { try { Finalizer f = (Finalizer)queue.remove(); - f.deregisterAndRunFinalizer(jla); + f.runFinalizer(jla); } catch (InterruptedException x) { // ignore and continue } diff -r 4f11514fe783 -r a6c4b85163c1 src/java.base/share/classes/jdk/internal/misc/VM.java --- a/src/java.base/share/classes/jdk/internal/misc/VM.java Fri Feb 23 14:26:29 2018 -0500 +++ b/src/java.base/share/classes/jdk/internal/misc/VM.java Fri Feb 23 12:10:56 2018 -0800 @@ -27,9 +27,7 @@ import static java.lang.Thread.State.*; import java.util.Map; -import java.util.HashMap; import java.util.Properties; -import java.util.Collections; public class VM { @@ -38,6 +36,8 @@ private static final int MODULE_SYSTEM_INITED = 2; private static final int SYSTEM_LOADER_INITIALIZING = 3; private static final int SYSTEM_BOOTED = 4; + private static final int SYSTEM_SHUTDOWN = 5; + // 0, 1, 2, ... private static volatile int initLevel; @@ -52,7 +52,7 @@ */ public static void initLevel(int value) { synchronized (lock) { - if (value <= initLevel || value > SYSTEM_BOOTED) + if (value <= initLevel || value > SYSTEM_SHUTDOWN) throw new InternalError("Bad level: " + value); initLevel = value; lock.notifyAll(); @@ -94,6 +94,23 @@ return initLevel >= SYSTEM_BOOTED; } + /** + * Set shutdown state. Shutdown completes when all registered shutdown + * hooks have been run. + * + * @see java.lang.Shutdown + */ + public static void shutdown() { + initLevel(SYSTEM_SHUTDOWN); + } + + /** + * Returns {@code true} if the VM has been shutdown + */ + public static boolean isShutdown() { + return initLevel == SYSTEM_SHUTDOWN; + } + // A user-settable upper limit on the maximum amount of allocatable direct // buffer memory. This value may be changed during VM initialization if // "java" is launched with "-XX:MaxDirectMemorySize=". diff -r 4f11514fe783 -r a6c4b85163c1 src/java.base/share/native/libjava/Shutdown.c --- a/src/java.base/share/native/libjava/Shutdown.c Fri Feb 23 14:26:29 2018 -0500 +++ b/src/java.base/share/native/libjava/Shutdown.c Fri Feb 23 12:10:56 2018 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2018, 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 @@ -35,17 +35,3 @@ { JVM_Halt(code); } - - -JNIEXPORT void JNICALL -Java_java_lang_Shutdown_runAllFinalizers(JNIEnv *env, jclass ignored) -{ - jclass cl; - jmethodID mid; - - if ((cl = (*env)->FindClass(env, "java/lang/ref/Finalizer")) - && (mid = (*env)->GetStaticMethodID(env, cl, - "runAllFinalizers", "()V"))) { - (*env)->CallStaticVoidMethod(env, cl, mid); - } -} diff -r 4f11514fe783 -r a6c4b85163c1 src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/Main.java --- a/src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/Main.java Fri Feb 23 14:26:29 2018 -0500 +++ b/src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/Main.java Fri Feb 23 12:10:56 2018 -0800 @@ -80,8 +80,8 @@ * - handling of covariant overrides * - handling of override of method found in multiple superinterfaces * - convert type/method/field output to Java source like syntax, e.g. - * instead of java/lang/Runtime.runFinalizersOnExit(Z)V - * print void java.lang.Runtime.runFinalizersOnExit(boolean) + * instead of java/lang/Character.isJavaLetter(C)Z + * print void java.lang.Character.isJavaLetter(char)boolean * - more example output in man page * - more rigorous GNU style option parsing; use joptsimple? * diff -r 4f11514fe783 -r a6c4b85163c1 src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/internals.md --- a/src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/internals.md Fri Feb 23 14:26:29 2018 -0500 +++ b/src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/internals.md Fri Feb 23 12:10:56 2018 -0800 @@ -195,15 +195,14 @@ **EXAMPLE OUTPUT** Given the following method declaration and annotation from the -`java.lang.Runtime` class, +`java.lang.Character` class, - @Deprecated(since="1.2", - forRemoval=true) - public static void runFinalizersOnExit(boolean value) + @Deprecated(since="1.1") + public static boolean isJavaLetter(char ch) the following line will be emitted from **jdeprscan -Xprint-csv**: - METHOD,java/lang/Runtime,runFinalizersOnExit(Z)V,1.2,true + METHOD,java/lang/Character,isJavaLetter(C)Z,1.1,false [RFC]: https://www.ietf.org/rfc/rfc4180.txt diff -r 4f11514fe783 -r a6c4b85163c1 src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/readme.md --- a/src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/readme.md Fri Feb 23 14:26:29 2018 -0500 +++ b/src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/readme.md Fri Feb 23 12:10:56 2018 -0800 @@ -1,6 +1,6 @@