8268638: semaphores of AsyncLogWriter may be broken when JVM is exiting.

Backport-of: fa3b44d43811dca8c609d6c61a58680835abf8e3
diff --git a/src/hotspot/share/logging/logAsyncWriter.cpp b/src/hotspot/share/logging/logAsyncWriter.cpp
index b3b61f8..f46fc1c 100644
--- a/src/hotspot/share/logging/logAsyncWriter.cpp
+++ b/src/hotspot/share/logging/logAsyncWriter.cpp
@@ -28,24 +28,18 @@
 #include "logging/logHandle.hpp"
 #include "runtime/atomic.hpp"
 
-Semaphore AsyncLogWriter::_sem(0);
-Semaphore AsyncLogWriter::_io_sem(1);
-
-class AsyncLogLocker : public StackObj {
- private:
-  static Semaphore _lock;
+class AsyncLogWriter::AsyncLogLocker : public StackObj {
  public:
   AsyncLogLocker() {
-    _lock.wait();
+    assert(_instance != nullptr, "AsyncLogWriter::_lock is unavailable");
+    _instance->_lock.wait();
   }
 
   ~AsyncLogLocker() {
-    _lock.signal();
+    _instance->_lock.signal();
   }
 };
 
-Semaphore AsyncLogLocker::_lock(1);
-
 void AsyncLogWriter::enqueue_locked(const AsyncLogMessage& msg) {
   if (_buffer.size() >= _buffer_max_size)  {
     bool p_created;
@@ -64,7 +58,7 @@
   AsyncLogMessage m(output, decorations, os::strdup(msg));
 
   { // critical area
-    AsyncLogLocker lock;
+    AsyncLogLocker locker;
     enqueue_locked(m);
   }
 }
@@ -72,7 +66,7 @@
 // LogMessageBuffer consists of a multiple-part/multiple-line messsage.
 // The lock here guarantees its integrity.
 void AsyncLogWriter::enqueue(LogFileOutput& output, LogMessageBuffer::Iterator msg_iterator) {
-  AsyncLogLocker lock;
+  AsyncLogLocker locker;
 
   for (; !msg_iterator.is_at_end(); msg_iterator++) {
     AsyncLogMessage m(output, msg_iterator.decorations(), os::strdup(msg_iterator.message()));
@@ -81,7 +75,8 @@
 }
 
 AsyncLogWriter::AsyncLogWriter()
-  : _initialized(false),
+  : _lock(1), _sem(0), _io_sem(1),
+    _initialized(false),
     _stats(17 /*table_size*/) {
   if (os::create_thread(this, os::asynclog_thread)) {
     _initialized = true;
@@ -125,7 +120,7 @@
   bool own_io = false;
 
   { // critical region
-    AsyncLogLocker lock;
+    AsyncLogLocker locker;
 
     _buffer.pop_all(&logs);
     // append meta-messages of dropped counters
diff --git a/src/hotspot/share/logging/logAsyncWriter.hpp b/src/hotspot/share/logging/logAsyncWriter.hpp
index 736a957..23c92c5 100644
--- a/src/hotspot/share/logging/logAsyncWriter.hpp
+++ b/src/hotspot/share/logging/logAsyncWriter.hpp
@@ -133,12 +133,16 @@
 // times. It is no-op if async logging is not established.
 //
 class AsyncLogWriter : public NonJavaThread {
+  class AsyncLogLocker;
+
   static AsyncLogWriter* _instance;
+  // _lock(1) denotes a critional region.
+  Semaphore _lock;
   // _sem is a semaphore whose value denotes how many messages have been enqueued.
   // It decreases in AsyncLogWriter::run()
-  static Semaphore _sem;
+  Semaphore _sem;
   // A lock of IO
-  static Semaphore _io_sem;
+  Semaphore _io_sem;
 
   volatile bool _initialized;
   AsyncLogMap _stats; // statistics for dropped messages