8211821: PrintStringTableStatistics crashes JVM

During JVM exit, print the Symbol and String tables before current thread gets deleted.

Reviewed-by: iklam, dholmes
diff --git a/src/hotspot/share/runtime/java.cpp b/src/hotspot/share/runtime/java.cpp
index f5dab8d..47d12cf 100644
--- a/src/hotspot/share/runtime/java.cpp
+++ b/src/hotspot/share/runtime/java.cpp
@@ -572,9 +572,6 @@
 }
 
 void vm_perform_shutdown_actions() {
-  // Warning: do not call 'exit_globals()' here. All threads are still running.
-  // Calling 'exit_globals()' will disable thread-local-storage and cause all
-  // kinds of assertions to trigger in debug mode.
   if (is_init_completed()) {
     Thread* thread = Thread::current_or_null();
     if (thread != NULL && thread->is_Java_thread()) {
diff --git a/src/hotspot/share/runtime/thread.cpp b/src/hotspot/share/runtime/thread.cpp
index 1b00cbb..9ecd3a0 100644
--- a/src/hotspot/share/runtime/thread.cpp
+++ b/src/hotspot/share/runtime/thread.cpp
@@ -4220,10 +4220,10 @@
 //     <-- do not use anything that could get blocked by Safepoint -->
 //   + Disable tracing at JNI/JVM barriers
 //   + Set _vm_exited flag for threads that are still running native code
-//   + Delete this thread
 //   + Call exit_globals()
 //      > deletes tty
 //      > deletes PerfMemory resources
+//   + Delete this thread
 //   + Return to caller
 
 bool Threads::destroy_vm() {
@@ -4299,6 +4299,9 @@
 
   notify_vm_shutdown();
 
+  // exit_globals() will delete tty
+  exit_globals();
+
   // We are after VM_Exit::set_vm_exited() so we can't call
   // thread->smr_delete() or we will block on the Threads_lock.
   // Deleting the shutdown thread here is safe because another
@@ -4312,9 +4315,6 @@
   }
 #endif
 
-  // exit_globals() will delete tty
-  exit_globals();
-
   LogConfiguration::finalize();
 
   return true;
diff --git a/test/hotspot/jtreg/runtime/PrintStringTableStats/PrintStringTableStatsTest.java b/test/hotspot/jtreg/runtime/PrintStringTableStats/PrintStringTableStatsTest.java
new file mode 100644
index 0000000..73941b3
--- /dev/null
+++ b/test/hotspot/jtreg/runtime/PrintStringTableStats/PrintStringTableStatsTest.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 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
+ * 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 jdk.test.lib.process.ProcessTools;
+import jdk.test.lib.process.OutputAnalyzer;
+
+/*
+ * @test PrintStringTableStatsTest
+ * @bug 8211821
+ * @library /test/lib
+ * @run main PrintStringTableStatsTest
+ */
+
+public class PrintStringTableStatsTest {
+    public static void main(String... args) throws Exception {
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+            "-XX:+PrintStringTableStatistics",
+            "--version");
+        OutputAnalyzer output = new OutputAnalyzer(pb.start());
+        output.shouldContain("Number of buckets");
+        output.shouldHaveExitValue(0);
+    }
+}