changeset 55554:1ed25a6f90db lworld

Merge to last conflict
author dsimms
date Thu, 23 May 2019 14:13:01 +0200
parents 711cb57fdbc8 845f5a35241b
children 6ebaf606e2a9
files src/hotspot/cpu/x86/gc/shared/modRefBarrierSetAssembler_x86.cpp src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp src/hotspot/cpu/x86/stubGenerator_x86_64.cpp src/hotspot/share/interpreter/interpreterRuntime.cpp src/hotspot/share/oops/cpCache.cpp src/hotspot/share/oops/cpCache.hpp src/hotspot/share/runtime/sharedRuntime.cpp test/hotspot/gtest/oops/test_markOop.cpp
diffstat 17 files changed, 540 insertions(+), 882 deletions(-) [+]
line wrap: on
line diff
--- a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp	Thu May 23 14:12:43 2019 +0200
+++ b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp	Thu May 23 14:13:01 2019 +0200
@@ -1788,7 +1788,7 @@
     }
 #endif //ASSERT
 
-    DecoratorSet decorators = IN_HEAP | IS_ARRAY | ARRAYCOPY_CHECKCAST;
+    DecoratorSet decorators = IN_HEAP | IS_ARRAY | ARRAYCOPY_CHECKCAST | ARRAYCOPY_DISJOINT;
     bool is_oop = true;
     if (dest_uninitialized) {
       decorators |= IS_DEST_UNINITIALIZED;
--- a/src/hotspot/cpu/x86/gc/shared/modRefBarrierSetAssembler_x86.cpp	Thu May 23 14:12:43 2019 +0200
+++ b/src/hotspot/cpu/x86/gc/shared/modRefBarrierSetAssembler_x86.cpp	Thu May 23 14:13:01 2019 +0200
@@ -36,12 +36,14 @@
 
   if (type == T_OBJECT || type == T_ARRAY) {
 #ifdef _LP64
-    if (!checkcast && !obj_int) {
-      // Save count for barrier
-      __ movptr(r11, count);
-    } else if (disjoint && obj_int) {
-      // Save dst in r11 in the disjoint case
-      __ movq(r11, dst);
+    if (!checkcast) {
+      if (!obj_int) {
+        // Save count for barrier
+        __ movptr(r11, count);
+      } else if (disjoint) {
+        // Save dst in r11 in the disjoint case
+        __ movq(r11, dst);
+      }
     }
 #else
     if (disjoint) {
@@ -61,13 +63,15 @@
 
   if (type == T_OBJECT || type == T_ARRAY) {
 #ifdef _LP64
-    if (!checkcast && !obj_int) {
-      // Save count for barrier
-      count = r11;
-    } else if (disjoint && obj_int) {
-      // Use the saved dst in the disjoint case
-      dst = r11;
-    } else if (checkcast) {
+    if (!checkcast) {
+      if (!obj_int) {
+        // Save count for barrier
+        count = r11;
+      } else if (disjoint) {
+        // Use the saved dst in the disjoint case
+        dst = r11;
+      }
+    } else {
       tmp = rscratch1;
     }
 #else
--- a/src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp	Thu May 23 14:12:43 2019 +0200
+++ b/src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp	Thu May 23 14:13:01 2019 +0200
@@ -53,12 +53,14 @@
 
   if (type == T_OBJECT || type == T_ARRAY) {
 #ifdef _LP64
-    if (!checkcast && !obj_int) {
-      // Save count for barrier
-      __ movptr(r11, count);
-    } else if (disjoint && obj_int) {
-      // Save dst in r11 in the disjoint case
-      __ movq(r11, dst);
+    if (!checkcast) {
+      if (!obj_int) {
+        // Save count for barrier
+        __ movptr(r11, count);
+      } else if (disjoint) {
+        // Save dst in r11 in the disjoint case
+        __ movq(r11, dst);
+      }
     }
 #else
     if (disjoint) {
@@ -123,13 +125,15 @@
 
   if (type == T_OBJECT || type == T_ARRAY) {
 #ifdef _LP64
-    if (!checkcast && !obj_int) {
-      // Save count for barrier
-      count = r11;
-    } else if (disjoint && obj_int) {
-      // Use the saved dst in the disjoint case
-      dst = r11;
-    } else if (checkcast) {
+    if (!checkcast) {
+      if (!obj_int) {
+        // Save count for barrier
+        count = r11;
+      } else if (disjoint && obj_int) {
+        // Use the saved dst in the disjoint case
+        dst = r11;
+      }
+    } else {
       tmp = rscratch1;
     }
 #else
--- a/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp	Thu May 23 14:12:43 2019 +0200
+++ b/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp	Thu May 23 14:13:01 2019 +0200
@@ -2198,7 +2198,7 @@
                                    // r9 is used to save r15_thread
     // 'from', 'to' and 'qword_count' are now valid
 
-    DecoratorSet decorators = IN_HEAP | IS_ARRAY | ARRAYCOPY_DISJOINT;
+    DecoratorSet decorators = IN_HEAP | IS_ARRAY;
     if (dest_uninitialized) {
       decorators |= IS_DEST_UNINITIALIZED;
     }
@@ -2392,7 +2392,7 @@
     Address from_element_addr(end_from, count, TIMES_OOP, 0);
     Address   to_element_addr(end_to,   count, TIMES_OOP, 0);
 
-    DecoratorSet decorators = IN_HEAP | IS_ARRAY | ARRAYCOPY_CHECKCAST;
+    DecoratorSet decorators = IN_HEAP | IS_ARRAY | ARRAYCOPY_CHECKCAST | ARRAYCOPY_DISJOINT;
     if (dest_uninitialized) {
       decorators |= IS_DEST_UNINITIALIZED;
     }
--- a/src/hotspot/share/classfile/classLoaderDataGraph.cpp	Thu May 23 14:12:43 2019 +0200
+++ b/src/hotspot/share/classfile/classLoaderDataGraph.cpp	Thu May 23 14:13:01 2019 +0200
@@ -48,6 +48,7 @@
 volatile size_t ClassLoaderDataGraph::_num_instance_classes = 0;
 
 void ClassLoaderDataGraph::clear_claimed_marks() {
+  assert_locked_or_safepoint_weak(ClassLoaderDataGraph_lock);
   for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) {
     cld->clear_claim();
   }
--- a/src/hotspot/share/gc/g1/g1ConcurrentMarkThread.cpp	Thu May 23 14:12:43 2019 +0200
+++ b/src/hotspot/share/gc/g1/g1ConcurrentMarkThread.cpp	Thu May 23 14:13:01 2019 +0200
@@ -268,6 +268,7 @@
 
       {
         G1ConcPhase p(G1ConcurrentPhase::CLEAR_CLAIMED_MARKS, this);
+        MutexLocker ml(ClassLoaderDataGraph_lock);
         ClassLoaderDataGraph::clear_claimed_marks();
       }
 
--- a/src/hotspot/share/interpreter/interpreterRuntime.cpp	Thu May 23 14:12:43 2019 +0200
+++ b/src/hotspot/share/interpreter/interpreterRuntime.cpp	Thu May 23 14:13:01 2019 +0200
@@ -1142,23 +1142,19 @@
            info.call_kind() == CallInfo::vtable_call, "");
   }
 #endif
+  // Get sender or sender's unsafe_anonymous_host, and only set cpCache entry to resolved if
+  // it is not an interface.  The receiver for invokespecial calls within interface
+  // methods must be checked for every call.
+  InstanceKlass* sender = pool->pool_holder();
+  sender = sender->is_unsafe_anonymous() ? sender->unsafe_anonymous_host() : sender;
 
   switch (info.call_kind()) {
-  case CallInfo::direct_call: {
-    // Get sender or sender's unsafe_anonymous_host, and only set cpCache entry to resolved if
-    // it is not an interface.  The receiver for invokespecial calls within interface
-    // methods must be checked for every call.
-    InstanceKlass* pool_holder = pool->pool_holder();
-    InstanceKlass* sender = pool_holder->is_unsafe_anonymous() ?
-                              pool_holder->unsafe_anonymous_host() : pool_holder;
-
+  case CallInfo::direct_call:
     cp_cache_entry->set_direct_call(
       bytecode,
       info.resolved_method(),
-      sender->is_interface(),
-      pool_holder);
+      sender->is_interface());
     break;
-  }
   case CallInfo::vtable_call:
     cp_cache_entry->set_vtable_call(
       bytecode,
--- a/src/hotspot/share/oops/cpCache.cpp	Thu May 23 14:12:43 2019 +0200
+++ b/src/hotspot/share/oops/cpCache.cpp	Thu May 23 14:13:01 2019 +0200
@@ -173,8 +173,7 @@
 void ConstantPoolCacheEntry::set_direct_or_vtable_call(Bytecodes::Code invoke_code,
                                                        const methodHandle& method,
                                                        int vtable_index,
-                                                       bool sender_is_interface,
-                                                       InstanceKlass* pool_holder) {
+                                                       bool sender_is_interface) {
   bool is_vtable_call = (vtable_index >= 0);  // FIXME: split this method on this boolean
   assert(method->interpreter_entry() != NULL, "should have been set at this point");
   assert(!method->is_obsolete(),  "attempt to write obsolete method to cpCache");
@@ -269,17 +268,9 @@
     }
     // Don't mark invokestatic to method as resolved if the holder class has not yet completed
     // initialization. An invokestatic must only proceed if the class is initialized, but if
-    // we resolve it before then that class initialization check is skipped. However if the call
-    // is from the same class we can resolve as we must be executing with <clinit> on our call stack.
-    if (invoke_code == Bytecodes::_invokestatic) {
-      if (!method->method_holder()->is_initialized() &&
-          method->method_holder() != pool_holder) {
-        do_resolve = false;
-      } else {
-        assert(method->method_holder()->is_initialized() ||
-               method->method_holder()->is_reentrant_initialization(Thread::current()),
-               "invalid class initialization state for invoke_static");
-      }
+    // we resolve it before then that class initialization check is skipped.
+    if (invoke_code == Bytecodes::_invokestatic && !method->method_holder()->is_initialized()) {
+      do_resolve = false;
     }
     if (do_resolve) {
       set_bytecode_1(invoke_code);
@@ -325,17 +316,17 @@
 }
 
 void ConstantPoolCacheEntry::set_direct_call(Bytecodes::Code invoke_code, const methodHandle& method,
-                                             bool sender_is_interface, InstanceKlass* pool_holder) {
+                                             bool sender_is_interface) {
   int index = Method::nonvirtual_vtable_index;
   // index < 0; FIXME: inline and customize set_direct_or_vtable_call
-  set_direct_or_vtable_call(invoke_code, method, index, sender_is_interface, pool_holder);
+  set_direct_or_vtable_call(invoke_code, method, index, sender_is_interface);
 }
 
 void ConstantPoolCacheEntry::set_vtable_call(Bytecodes::Code invoke_code, const methodHandle& method, int index) {
   // either the method is a miranda or its holder should accept the given index
   assert(method->method_holder()->is_interface() || method->method_holder()->verify_vtable_index(index), "");
   // index >= 0; FIXME: inline and customize set_direct_or_vtable_call
-  set_direct_or_vtable_call(invoke_code, method, index, false, NULL /* not used */);
+  set_direct_or_vtable_call(invoke_code, method, index, false);
 }
 
 void ConstantPoolCacheEntry::set_itable_call(Bytecodes::Code invoke_code,
--- a/src/hotspot/share/oops/cpCache.hpp	Thu May 23 14:12:43 2019 +0200
+++ b/src/hotspot/share/oops/cpCache.hpp	Thu May 23 14:13:01 2019 +0200
@@ -236,16 +236,14 @@
     Bytecodes::Code invoke_code,                 // the bytecode used for invoking the method
     const methodHandle& method,                  // the method/prototype if any (NULL, otherwise)
     int             vtable_index,                // the vtable index if any, else negative
-    bool            sender_is_interface,         // 'logical' sender (may be host of VMAC)
-    InstanceKlass*  pool_holder                  // class from which the call is made
+    bool            sender_is_interface
   );
 
  public:
   void set_direct_call(                          // sets entry to exact concrete method entry
     Bytecodes::Code invoke_code,                 // the bytecode used for invoking the method
     const methodHandle& method,                  // the method to call
-    bool            sender_is_interface,         // 'logical' sender (may be host of VMAC)
-    InstanceKlass*  pool_holder                  // class from which the call is made
+    bool            sender_is_interface
   );
 
   void set_vtable_call(                          // sets entry to vtable index
--- a/src/hotspot/share/runtime/sharedRuntime.cpp	Thu May 23 14:12:43 2019 +0200
+++ b/src/hotspot/share/runtime/sharedRuntime.cpp	Thu May 23 14:13:01 2019 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2019, 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
@@ -1425,18 +1425,12 @@
   }
 #endif
 
-  // Do not patch call site for static call to another class
-  // when the class is not fully initialized.
-  if (invoke_code == Bytecodes::_invokestatic) {
-    if (!callee_method->method_holder()->is_initialized() &&
-        callee_method->method_holder() != caller_nm->method()->method_holder()) {
-      assert(callee_method->method_holder()->is_linked(), "must be");
-      return callee_method;
-    } else {
-      assert(callee_method->method_holder()->is_initialized() ||
-             callee_method->method_holder()->is_reentrant_initialization(thread),
-             "invalid class initialization state for invoke_static");
-    }
+  // Do not patch call site for static call when the class is not
+  // fully initialized.
+  if (invoke_code == Bytecodes::_invokestatic &&
+      !callee_method->method_holder()->is_initialized()) {
+    assert(callee_method->method_holder()->is_linked(), "must be");
+    return callee_method;
   }
 
   // JSR 292 key invariant:
--- a/src/java.base/share/classes/java/nio/channels/spi/AbstractInterruptibleChannel.java	Thu May 23 14:12:43 2019 +0200
+++ b/src/java.base/share/classes/java/nio/channels/spi/AbstractInterruptibleChannel.java	Thu May 23 14:13:01 2019 +0200
@@ -30,7 +30,6 @@
 import java.nio.channels.Channel;
 import java.nio.channels.ClosedByInterruptException;
 import java.nio.channels.InterruptibleChannel;
-import java.util.concurrent.locks.ReentrantLock;
 
 import jdk.internal.access.SharedSecrets;
 import sun.nio.ch.Interruptible;
@@ -86,7 +85,7 @@
 public abstract class AbstractInterruptibleChannel
     implements Channel, InterruptibleChannel
 {
-    private final ReentrantLock closeLock = new ReentrantLock();
+    private final Object closeLock = new Object();
     private volatile boolean closed;
 
     /**
@@ -106,14 +105,11 @@
      *          If an I/O error occurs
      */
     public final void close() throws IOException {
-        closeLock.lock();
-        try {
+        synchronized (closeLock) {
             if (closed)
                 return;
             closed = true;
             implCloseChannel();
-        } finally {
-            closeLock.unlock();
         }
     }
 
@@ -157,8 +153,7 @@
         if (interruptor == null) {
             interruptor = new Interruptible() {
                     public void interrupt(Thread target) {
-                        closeLock.lock();
-                        try {
+                        synchronized (closeLock) {
                             if (closed)
                                 return;
                             closed = true;
@@ -166,8 +161,6 @@
                             try {
                                 AbstractInterruptibleChannel.this.implCloseChannel();
                             } catch (IOException x) { }
-                        } finally {
-                            closeLock.unlock();
                         }
                     }};
         }
--- a/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java	Thu May 23 14:12:43 2019 +0200
+++ b/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java	Thu May 23 14:13:01 2019 +0200
@@ -53,7 +53,6 @@
 import java.util.HashSet;
 import java.util.Objects;
 import java.util.Set;
-import java.util.concurrent.locks.Condition;
 import java.util.concurrent.locks.ReentrantLock;
 
 import sun.net.ResourceManager;
@@ -90,8 +89,7 @@
 
     // Lock held by any thread that modifies the state fields declared below
     // DO NOT invoke a blocking I/O operation while holding this lock!
-    private final ReentrantLock stateLock = new ReentrantLock();
-    private final Condition stateCondition = stateLock.newCondition();
+    private final Object stateLock = new Object();
 
     // -- The following fields are protected by stateLock
 
@@ -99,8 +97,7 @@
     private static final int ST_UNCONNECTED = 0;
     private static final int ST_CONNECTED = 1;
     private static final int ST_CLOSING = 2;
-    private static final int ST_KILLPENDING = 3;
-    private static final int ST_KILLED = 4;
+    private static final int ST_CLOSED = 3;
     private int state;
 
     // IDs of native threads doing reads and writes, for signalling
@@ -181,11 +178,8 @@
                 : StandardProtocolFamily.INET;
         this.fd = fd;
         this.fdVal = IOUtil.fdVal(fd);
-        stateLock.lock();
-        try {
+        synchronized (stateLock) {
             this.localAddress = Net.localAddress(fd);
-        } finally {
-            stateLock.unlock();
         }
     }
 
@@ -197,36 +191,27 @@
 
     @Override
     public DatagramSocket socket() {
-        stateLock.lock();
-        try {
+        synchronized (stateLock) {
             if (socket == null)
                 socket = DatagramSocketAdaptor.create(this);
             return socket;
-        } finally {
-            stateLock.unlock();
         }
     }
 
     @Override
     public SocketAddress getLocalAddress() throws IOException {
-        stateLock.lock();
-        try {
+        synchronized (stateLock) {
             ensureOpen();
             // Perform security check before returning address
             return Net.getRevealedLocalAddress(localAddress);
-        } finally {
-            stateLock.unlock();
         }
     }
 
     @Override
     public SocketAddress getRemoteAddress() throws IOException {
-        stateLock.lock();
-        try {
+        synchronized (stateLock) {
             ensureOpen();
             return remoteAddress;
-        } finally {
-            stateLock.unlock();
         }
     }
 
@@ -238,8 +223,7 @@
         if (!supportedOptions().contains(name))
             throw new UnsupportedOperationException("'" + name + "' not supported");
 
-        stateLock.lock();
-        try {
+        synchronized (stateLock) {
             ensureOpen();
 
             if (name == StandardSocketOptions.IP_TOS ||
@@ -279,8 +263,6 @@
             // remaining options don't need any special handling
             Net.setSocketOption(fd, Net.UNSPEC, name, value);
             return this;
-        } finally {
-            stateLock.unlock();
         }
     }
 
@@ -293,8 +275,7 @@
         if (!supportedOptions().contains(name))
             throw new UnsupportedOperationException("'" + name + "' not supported");
 
-        stateLock.lock();
-        try {
+        synchronized (stateLock) {
             ensureOpen();
 
             if (name == StandardSocketOptions.IP_TOS ||
@@ -333,8 +314,6 @@
 
             // no special handling
             return (T) Net.getSocketOption(fd, Net.UNSPEC, name);
-        } finally {
-            stateLock.unlock();
         }
     }
 
@@ -382,8 +361,7 @@
             begin();
         }
         SocketAddress remote;
-        stateLock.lock();
-        try {
+        synchronized (stateLock) {
             ensureOpen();
             remote = remoteAddress;
             if ((remote == null) && mustBeConnected)
@@ -392,8 +370,6 @@
                 bindInternal(null);
             if (blocking)
                 readerThread = NativeThread.current();
-        } finally {
-            stateLock.unlock();
         }
         return remote;
     }
@@ -407,15 +383,11 @@
         throws AsynchronousCloseException
     {
         if (blocking) {
-            stateLock.lock();
-            try {
+            synchronized (stateLock) {
                 readerThread = 0;
-                // notify any thread waiting in implCloseSelectableChannel
                 if (state == ST_CLOSING) {
-                    stateCondition.signalAll();
+                    tryFinishClose();
                 }
-            } finally {
-                stateLock.unlock();
             }
             // remove hook for Thread.interrupt
             end(completed);
@@ -708,8 +680,7 @@
             begin();
         }
         SocketAddress remote;
-        stateLock.lock();
-        try {
+        synchronized (stateLock) {
             ensureOpen();
             remote = remoteAddress;
             if ((remote == null) && mustBeConnected)
@@ -718,8 +689,6 @@
                 bindInternal(null);
             if (blocking)
                 writerThread = NativeThread.current();
-        } finally {
-            stateLock.unlock();
         }
         return remote;
     }
@@ -733,15 +702,11 @@
         throws AsynchronousCloseException
     {
         if (blocking) {
-            stateLock.lock();
-            try {
+            synchronized (stateLock) {
                 writerThread = 0;
-                // notify any thread waiting in implCloseSelectableChannel
                 if (state == ST_CLOSING) {
-                    stateCondition.signalAll();
+                    tryFinishClose();
                 }
-            } finally {
-                stateLock.unlock();
             }
             // remove hook for Thread.interrupt
             end(completed);
@@ -810,12 +775,9 @@
         try {
             writeLock.lock();
             try {
-                stateLock.lock();
-                try {
+                synchronized (stateLock) {
                     ensureOpen();
                     IOUtil.configureBlocking(fd, block);
-                } finally {
-                    stateLock.unlock();
                 }
             } finally {
                 writeLock.unlock();
@@ -826,20 +788,14 @@
     }
 
     InetSocketAddress localAddress() {
-        stateLock.lock();
-        try {
+        synchronized (stateLock) {
             return localAddress;
-        } finally {
-            stateLock.unlock();
         }
     }
 
     InetSocketAddress remoteAddress() {
-        stateLock.lock();
-        try {
+        synchronized (stateLock) {
             return remoteAddress;
-        } finally {
-            stateLock.unlock();
         }
     }
 
@@ -849,14 +805,11 @@
         try {
             writeLock.lock();
             try {
-                stateLock.lock();
-                try {
+                synchronized (stateLock) {
                     ensureOpen();
                     if (localAddress != null)
                         throw new AlreadyBoundException();
                     bindInternal(local);
-                } finally {
-                    stateLock.unlock();
                 }
             } finally {
                 writeLock.unlock();
@@ -868,7 +821,7 @@
     }
 
     private void bindInternal(SocketAddress local) throws IOException {
-        assert stateLock.isHeldByCurrentThread() && (localAddress == null);
+        assert Thread.holdsLock(stateLock )&& (localAddress == null);
 
         InetSocketAddress isa;
         if (local == null) {
@@ -891,11 +844,8 @@
 
     @Override
     public boolean isConnected() {
-        stateLock.lock();
-        try {
+        synchronized (stateLock) {
             return (state == ST_CONNECTED);
-        } finally {
-            stateLock.unlock();
         }
     }
 
@@ -917,8 +867,7 @@
         try {
             writeLock.lock();
             try {
-                stateLock.lock();
-                try {
+                synchronized (stateLock) {
                     ensureOpen();
                     if (state == ST_CONNECTED)
                         throw new AlreadyConnectedException();
@@ -952,9 +901,6 @@
                             IOUtil.configureBlocking(fd, true);
                         }
                     }
-
-                } finally {
-                    stateLock.unlock();
                 }
             } finally {
                 writeLock.unlock();
@@ -971,8 +917,7 @@
         try {
             writeLock.lock();
             try {
-                stateLock.lock();
-                try {
+                synchronized (stateLock) {
                     if (!isOpen() || (state != ST_CONNECTED))
                         return this;
 
@@ -986,8 +931,6 @@
 
                     // refresh local address
                     localAddress = Net.localAddress(fd);
-                } finally {
-                    stateLock.unlock();
                 }
             } finally {
                 writeLock.unlock();
@@ -1035,8 +978,7 @@
         if (sm != null)
             sm.checkMulticast(group);
 
-        stateLock.lock();
-        try {
+        synchronized (stateLock) {
             ensureOpen();
 
             // check the registry to see if we are already a member of the group
@@ -1091,8 +1033,6 @@
 
             registry.add(key);
             return key;
-        } finally {
-            stateLock.unlock();
         }
     }
 
@@ -1118,8 +1058,7 @@
     void drop(MembershipKeyImpl key) {
         assert key.channel() == this;
 
-        stateLock.lock();
-        try {
+        synchronized (stateLock) {
             if (!key.isValid())
                 return;
 
@@ -1140,8 +1079,6 @@
 
             key.invalidate();
             registry.remove(key);
-        } finally {
-            stateLock.unlock();
         }
     }
 
@@ -1155,8 +1092,7 @@
         assert key.channel() == this;
         assert key.sourceAddress() == null;
 
-        stateLock.lock();
-        try {
+        synchronized (stateLock) {
             if (!key.isValid())
                 throw new IllegalStateException("key is no longer valid");
             if (source.isAnyLocalAddress())
@@ -1182,8 +1118,6 @@
                 // ancient kernel
                 throw new UnsupportedOperationException();
             }
-        } finally {
-            stateLock.unlock();
         }
     }
 
@@ -1194,8 +1128,7 @@
         assert key.channel() == this;
         assert key.sourceAddress() == null;
 
-        stateLock.lock();
-        try {
+        synchronized (stateLock) {
             if (!key.isValid())
                 throw new IllegalStateException("key is no longer valid");
 
@@ -1215,116 +1148,117 @@
                 // should not happen
                 throw new AssertionError(ioe);
             }
-        } finally {
-            stateLock.unlock();
         }
     }
 
     /**
-     * Invoked by implCloseChannel to close the channel.
-     *
-     * This method waits for outstanding I/O operations to complete. When in
-     * blocking mode, the socket is pre-closed and the threads in blocking I/O
-     * operations are signalled to ensure that the outstanding I/O operations
-     * complete quickly.
-     *
-     * The socket is closed by this method when it is not registered with a
-     * Selector. Note that a channel configured blocking may be registered with
-     * a Selector. This arises when a key is canceled and the channel configured
-     * to blocking mode before the key is flushed from the Selector.
+     * Closes the socket if there are no I/O operations in progress and the
+     * channel is not registered with a Selector.
      */
-    @Override
-    protected void implCloseSelectableChannel() throws IOException {
-        assert !isOpen();
+    private boolean tryClose() throws IOException {
+        assert Thread.holdsLock(stateLock) && state == ST_CLOSING;
+        if ((readerThread == 0) && (writerThread == 0) && !isRegistered()) {
+            state = ST_CLOSED;
+            try {
+                nd.close(fd);
+            } finally {
+                // notify resource manager
+                ResourceManager.afterUdpClose();
+            }
+            return true;
+        } else {
+            return false;
+        }
+    }
 
-        boolean blocking;
-        boolean interrupted = false;
+    /**
+     * Invokes tryClose to attempt to close the socket.
+     *
+     * This method is used for deferred closing by I/O and Selector operations.
+     */
+    private void tryFinishClose() {
+        try {
+            tryClose();
+        } catch (IOException ignore) { }
+    }
 
-        // set state to ST_CLOSING and invalid membership keys
-        stateLock.lock();
-        try {
+    /**
+     * Closes this channel when configured in blocking mode.
+     *
+     * If there is an I/O operation in progress then the socket is pre-closed
+     * and the I/O threads signalled, in which case the final close is deferred
+     * until all I/O operations complete.
+     */
+    private void implCloseBlockingMode() throws IOException {
+        synchronized (stateLock) {
             assert state < ST_CLOSING;
-            blocking = isBlocking();
             state = ST_CLOSING;
 
             // if member of any multicast groups then invalidate the keys
             if (registry != null)
                 registry.invalidateAll();
-        } finally {
-            stateLock.unlock();
-        }
 
-        // wait for any outstanding I/O operations to complete
-        if (blocking) {
-            stateLock.lock();
-            try {
-                assert state == ST_CLOSING;
+            if (!tryClose()) {
                 long reader = readerThread;
                 long writer = writerThread;
                 if (reader != 0 || writer != 0) {
                     nd.preClose(fd);
-
                     if (reader != 0)
                         NativeThread.signal(reader);
                     if (writer != 0)
                         NativeThread.signal(writer);
-
-                    // wait for blocking I/O operations to end
-                    while (readerThread != 0 || writerThread != 0) {
-                        try {
-                            stateCondition.await();
-                        } catch (InterruptedException e) {
-                            interrupted = true;
-                        }
-                    }
                 }
-            } finally {
-                stateLock.unlock();
-            }
-        } else {
-            // non-blocking mode: wait for read/write to complete
-            readLock.lock();
-            try {
-                writeLock.lock();
-                writeLock.unlock();
-            } finally {
-                readLock.unlock();
             }
         }
+    }
 
-        // set state to ST_KILLPENDING
-        stateLock.lock();
-        try {
-            assert state == ST_CLOSING;
-            state = ST_KILLPENDING;
-        } finally {
-            stateLock.unlock();
+    /**
+     * Closes this channel when configured in non-blocking mode.
+     *
+     * If the channel is registered with a Selector then the close is deferred
+     * until the channel is flushed from all Selectors.
+     */
+    private void implCloseNonBlockingMode() throws IOException {
+        synchronized (stateLock) {
+            assert state < ST_CLOSING;
+            state = ST_CLOSING;
+
+            // if member of any multicast groups then invalidate the keys
+            if (registry != null)
+                registry.invalidateAll();
         }
 
-        // close socket if not registered with Selector
-        if (!isRegistered())
-            kill();
+        // wait for any read/write operations to complete before trying to close
+        readLock.lock();
+        readLock.unlock();
+        writeLock.lock();
+        writeLock.unlock();
+        synchronized (stateLock) {
+            if (state == ST_CLOSING) {
+                tryClose();
+            }
+        }
+    }
 
-        // restore interrupt status
-        if (interrupted)
-            Thread.currentThread().interrupt();
+    /**
+     * Invoked by implCloseChannel to close the channel.
+     */
+    @Override
+    protected void implCloseSelectableChannel() throws IOException {
+        assert !isOpen();
+        if (isBlocking()) {
+            implCloseBlockingMode();
+        } else {
+            implCloseNonBlockingMode();
+        }
     }
 
     @Override
-    public void kill() throws IOException {
-        stateLock.lock();
-        try {
-            if (state == ST_KILLPENDING) {
-                state = ST_KILLED;
-                try {
-                    nd.close(fd);
-                } finally {
-                    // notify resource manager
-                    ResourceManager.afterUdpClose();
-                }
+    public void kill() {
+        synchronized (stateLock) {
+            if (state == ST_CLOSING) {
+                tryFinishClose();
             }
-        } finally {
-            stateLock.unlock();
         }
     }
 
--- a/src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java	Thu May 23 14:12:43 2019 +0200
+++ b/src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java	Thu May 23 14:13:01 2019 +0200
@@ -46,7 +46,6 @@
 import java.util.HashSet;
 import java.util.Objects;
 import java.util.Set;
-import java.util.concurrent.locks.Condition;
 import java.util.concurrent.locks.ReentrantLock;
 
 import sun.net.NetHooks;
@@ -72,16 +71,14 @@
 
     // Lock held by any thread that modifies the state fields declared below
     // DO NOT invoke a blocking I/O operation while holding this lock!
-    private final ReentrantLock stateLock = new ReentrantLock();
-    private final Condition stateCondition = stateLock.newCondition();
+    private final Object stateLock = new Object();
 
     // -- The following fields are protected by stateLock
 
     // Channel state, increases monotonically
     private static final int ST_INUSE = 0;
     private static final int ST_CLOSING = 1;
-    private static final int ST_KILLPENDING = 2;
-    private static final int ST_KILLED = 3;
+    private static final int ST_CLOSED = 2;
     private int state;
 
     // ID of native thread currently blocked in this channel, for signalling
@@ -112,11 +109,8 @@
         this.fd =  fd;
         this.fdVal = IOUtil.fdVal(fd);
         if (bound) {
-            stateLock.lock();
-            try {
+            synchronized (stateLock) {
                 localAddress = Net.localAddress(fd);
-            } finally {
-                stateLock.unlock();
             }
         }
     }
@@ -129,26 +123,20 @@
 
     @Override
     public ServerSocket socket() {
-        stateLock.lock();
-        try {
+        synchronized (stateLock) {
             if (socket == null)
                 socket = ServerSocketAdaptor.create(this);
             return socket;
-        } finally {
-            stateLock.unlock();
         }
     }
 
     @Override
     public SocketAddress getLocalAddress() throws IOException {
-        stateLock.lock();
-        try {
+        synchronized (stateLock) {
             ensureOpen();
             return (localAddress == null)
                     ? null
                     : Net.getRevealedLocalAddress(localAddress);
-        } finally {
-            stateLock.unlock();
         }
     }
 
@@ -159,8 +147,7 @@
         Objects.requireNonNull(name);
         if (!supportedOptions().contains(name))
             throw new UnsupportedOperationException("'" + name + "' not supported");
-        stateLock.lock();
-        try {
+        synchronized (stateLock) {
             ensureOpen();
 
             if (name == StandardSocketOptions.SO_REUSEADDR && Net.useExclusiveBind()) {
@@ -171,8 +158,6 @@
                 Net.setSocketOption(fd, Net.UNSPEC, name, value);
             }
             return this;
-        } finally {
-            stateLock.unlock();
         }
     }
 
@@ -185,8 +170,7 @@
         if (!supportedOptions().contains(name))
             throw new UnsupportedOperationException("'" + name + "' not supported");
 
-        stateLock.lock();
-        try {
+        synchronized (stateLock) {
             ensureOpen();
             if (name == StandardSocketOptions.SO_REUSEADDR && Net.useExclusiveBind()) {
                 // SO_REUSEADDR emulated when using exclusive bind
@@ -194,8 +178,6 @@
             }
             // no options that require special handling
             return (T) Net.getSocketOption(fd, Net.UNSPEC, name);
-        } finally {
-            stateLock.unlock();
         }
     }
 
@@ -221,8 +203,7 @@
 
     @Override
     public ServerSocketChannel bind(SocketAddress local, int backlog) throws IOException {
-        stateLock.lock();
-        try {
+        synchronized (stateLock) {
             ensureOpen();
             if (localAddress != null)
                 throw new AlreadyBoundException();
@@ -236,8 +217,6 @@
             Net.bind(fd, isa.getAddress(), isa.getPort());
             Net.listen(fd, backlog < 1 ? 50 : backlog);
             localAddress = Net.localAddress(fd);
-        } finally {
-            stateLock.unlock();
         }
         return this;
     }
@@ -251,15 +230,12 @@
     private void begin(boolean blocking) throws ClosedChannelException {
         if (blocking)
             begin();  // set blocker to close channel if interrupted
-        stateLock.lock();
-        try {
+        synchronized (stateLock) {
             ensureOpen();
             if (localAddress == null)
                 throw new NotYetBoundException();
             if (blocking)
                 thread = NativeThread.current();
-        } finally {
-            stateLock.unlock();
         }
     }
 
@@ -273,15 +249,11 @@
         throws AsynchronousCloseException
     {
         if (blocking) {
-            stateLock.lock();
-            try {
+            synchronized (stateLock) {
                 thread = 0;
-                // notify any thread waiting in implCloseSelectableChannel
                 if (state == ST_CLOSING) {
-                    stateCondition.signalAll();
+                    tryFinishClose();
                 }
-            } finally {
-                stateLock.unlock();
             }
             end(completed);
         }
@@ -405,101 +377,99 @@
      */
     private void lockedConfigureBlocking(boolean block) throws IOException {
         assert acceptLock.isHeldByCurrentThread();
-        stateLock.lock();
-        try {
+        synchronized (stateLock) {
             ensureOpen();
             IOUtil.configureBlocking(fd, block);
-        } finally {
-            stateLock.unlock();
+        }
+    }
+
+    /**
+     * Closes the socket if there are no accept in progress and the channel is
+     * not registered with a Selector.
+     */
+    private boolean tryClose() throws IOException {
+        assert Thread.holdsLock(stateLock) && state == ST_CLOSING;
+        if ((thread == 0) && !isRegistered()) {
+            state = ST_CLOSED;
+            nd.close(fd);
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Invokes tryClose to attempt to close the socket.
+     *
+     * This method is used for deferred closing by I/O and Selector operations.
+     */
+    private void tryFinishClose() {
+        try {
+            tryClose();
+        } catch (IOException ignore) { }
+    }
+
+    /**
+     * Closes this channel when configured in blocking mode.
+     *
+     * If there is an accept in progress then the socket is pre-closed and the
+     * accept thread is signalled, in which case the final close is deferred
+     * until the accept aborts.
+     */
+    private void implCloseBlockingMode() throws IOException {
+        synchronized (stateLock) {
+            assert state < ST_CLOSING;
+            state = ST_CLOSING;
+            if (!tryClose()) {
+                long th = thread;
+                if (th != 0) {
+                    nd.preClose(fd);
+                    NativeThread.signal(th);
+                }
+            }
+        }
+    }
+
+    /**
+     * Closes this channel when configured in non-blocking mode.
+     *
+     * If the channel is registered with a Selector then the close is deferred
+     * until the channel is flushed from all Selectors.
+     */
+    private void implCloseNonBlockingMode() throws IOException {
+        synchronized (stateLock) {
+            assert state < ST_CLOSING;
+            state = ST_CLOSING;
+        }
+        // wait for any accept to complete before trying to close
+        acceptLock.lock();
+        acceptLock.unlock();
+        synchronized (stateLock) {
+            if (state == ST_CLOSING) {
+                tryClose();
+            }
         }
     }
 
     /**
      * Invoked by implCloseChannel to close the channel.
-     *
-     * This method waits for outstanding I/O operations to complete. When in
-     * blocking mode, the socket is pre-closed and the threads in blocking I/O
-     * operations are signalled to ensure that the outstanding I/O operations
-     * complete quickly.
-     *
-     * The socket is closed by this method when it is not registered with a
-     * Selector. Note that a channel configured blocking may be registered with
-     * a Selector. This arises when a key is canceled and the channel configured
-     * to blocking mode before the key is flushed from the Selector.
      */
     @Override
     protected void implCloseSelectableChannel() throws IOException {
         assert !isOpen();
-
-        boolean interrupted = false;
-        boolean blocking;
-
-        // set state to ST_CLOSING
-        stateLock.lock();
-        try {
-            assert state < ST_CLOSING;
-            state = ST_CLOSING;
-            blocking = isBlocking();
-        } finally {
-            stateLock.unlock();
+        if (isBlocking()) {
+            implCloseBlockingMode();
+        } else {
+            implCloseNonBlockingMode();
         }
-
-        // wait for any outstanding accept to complete
-        if (blocking) {
-            stateLock.lock();
-            try {
-                assert state == ST_CLOSING;
-                long th = thread;
-                if (th != 0) {
-                    nd.preClose(fd);
-                    NativeThread.signal(th);
-
-                    // wait for accept operation to end
-                    while (thread != 0) {
-                        try {
-                            stateCondition.await();
-                        } catch (InterruptedException e) {
-                            interrupted = true;
-                        }
-                    }
-                }
-            } finally {
-                stateLock.unlock();
-            }
-        } else {
-            // non-blocking mode: wait for accept to complete
-            acceptLock.lock();
-            acceptLock.unlock();
-        }
-
-        // set state to ST_KILLPENDING
-        stateLock.lock();
-        try {
-            assert state == ST_CLOSING;
-            state = ST_KILLPENDING;
-        } finally {
-            stateLock.unlock();
-        }
-
-        // close socket if not registered with Selector
-        if (!isRegistered())
-            kill();
-
-        // restore interrupt status
-        if (interrupted)
-            Thread.currentThread().interrupt();
     }
 
     @Override
-    public void kill() throws IOException {
-        stateLock.lock();
-        try {
-            if (state == ST_KILLPENDING) {
-                state = ST_KILLED;
-                nd.close(fd);
+    public void kill() {
+        synchronized (stateLock) {
+            if (state == ST_CLOSING) {
+                tryFinishClose();
             }
-        } finally {
-            stateLock.unlock();
         }
     }
 
@@ -507,11 +477,8 @@
      * Returns true if channel's socket is bound
      */
     boolean isBound() {
-        stateLock.lock();
-        try {
+        synchronized (stateLock) {
             return localAddress != null;
-        } finally {
-            stateLock.unlock();
         }
     }
 
@@ -519,11 +486,8 @@
      * Returns the local address, or null if not bound
      */
     InetSocketAddress localAddress() {
-        stateLock.lock();
-        try {
+        synchronized (stateLock) {
             return localAddress;
-        } finally {
-            stateLock.unlock();
         }
     }
 
@@ -589,16 +553,13 @@
         if (!isOpen()) {
             sb.append("closed");
         } else {
-            stateLock.lock();
-            try {
+            synchronized (stateLock) {
                 InetSocketAddress addr = localAddress;
                 if (addr == null) {
                     sb.append("unbound");
                 } else {
                     sb.append(Net.getRevealedLocalAddressAsString(addr));
                 }
-            } finally {
-                stateLock.unlock();
             }
         }
         sb.append(']');
--- a/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java	Thu May 23 14:12:43 2019 +0200
+++ b/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java	Thu May 23 14:13:01 2019 +0200
@@ -53,7 +53,6 @@
 import java.util.HashSet;
 import java.util.Objects;
 import java.util.Set;
-import java.util.concurrent.locks.Condition;
 import java.util.concurrent.locks.ReentrantLock;
 
 import sun.net.ConnectionResetException;
@@ -84,8 +83,7 @@
 
     // Lock held by any thread that modifies the state fields declared below
     // DO NOT invoke a blocking I/O operation while holding this lock!
-    private final ReentrantLock stateLock = new ReentrantLock();
-    private final Condition stateCondition = stateLock.newCondition();
+    private final Object stateLock = new Object();
 
     // Input/Output closed
     private volatile boolean isInputClosed;
@@ -104,8 +102,7 @@
     private static final int ST_CONNECTIONPENDING = 1;
     private static final int ST_CONNECTED = 2;
     private static final int ST_CLOSING = 3;
-    private static final int ST_KILLPENDING = 4;
-    private static final int ST_KILLED = 5;
+    private static final int ST_CLOSED = 4;
     private volatile int state;  // need stateLock to change
 
     // IDs of native threads doing reads and writes, for signalling
@@ -137,11 +134,8 @@
         this.fd = fd;
         this.fdVal = IOUtil.fdVal(fd);
         if (bound) {
-            stateLock.lock();
-            try {
+            synchronized (stateLock) {
                 this.localAddress = Net.localAddress(fd);
-            } finally {
-                stateLock.unlock();
             }
         }
     }
@@ -154,13 +148,10 @@
         super(sp);
         this.fd = fd;
         this.fdVal = IOUtil.fdVal(fd);
-        stateLock.lock();
-        try {
+        synchronized (stateLock) {
             this.localAddress = Net.localAddress(fd);
             this.remoteAddress = isa;
             this.state = ST_CONNECTED;
-        } finally {
-            stateLock.unlock();
         }
     }
 
@@ -197,35 +188,26 @@
 
     @Override
     public Socket socket() {
-        stateLock.lock();
-        try {
+        synchronized (stateLock) {
             if (socket == null)
                 socket = SocketAdaptor.create(this);
             return socket;
-        } finally {
-            stateLock.unlock();
         }
     }
 
     @Override
     public SocketAddress getLocalAddress() throws IOException {
-        stateLock.lock();
-        try {
+        synchronized (stateLock) {
             ensureOpen();
             return Net.getRevealedLocalAddress(localAddress);
-        } finally {
-            stateLock.unlock();
         }
     }
 
     @Override
     public SocketAddress getRemoteAddress() throws IOException {
-        stateLock.lock();
-        try {
+        synchronized (stateLock) {
             ensureOpen();
             return remoteAddress;
-        } finally {
-            stateLock.unlock();
         }
     }
 
@@ -237,8 +219,7 @@
         if (!supportedOptions().contains(name))
             throw new UnsupportedOperationException("'" + name + "' not supported");
 
-        stateLock.lock();
-        try {
+        synchronized (stateLock) {
             ensureOpen();
 
             if (name == StandardSocketOptions.IP_TOS) {
@@ -257,8 +238,6 @@
             // no options that require special handling
             Net.setSocketOption(fd, name, value);
             return this;
-        } finally {
-            stateLock.unlock();
         }
     }
 
@@ -271,8 +250,7 @@
         if (!supportedOptions().contains(name))
             throw new UnsupportedOperationException("'" + name + "' not supported");
 
-        stateLock.lock();
-        try {
+        synchronized (stateLock) {
             ensureOpen();
 
             if (name == StandardSocketOptions.SO_REUSEADDR && Net.useExclusiveBind()) {
@@ -289,8 +267,6 @@
 
             // no options that require special handling
             return (T) Net.getSocketOption(fd, name);
-        } finally {
-            stateLock.unlock();
         }
     }
 
@@ -332,13 +308,10 @@
             // set hook for Thread.interrupt
             begin();
 
-            stateLock.lock();
-            try {
+            synchronized (stateLock) {
                 ensureOpenAndConnected();
                 // record thread so it can be signalled if needed
                 readerThread = NativeThread.current();
-            } finally {
-                stateLock.unlock();
             }
         } else {
             ensureOpenAndConnected();
@@ -355,15 +328,11 @@
         throws AsynchronousCloseException
     {
         if (blocking) {
-            stateLock.lock();
-            try {
+            synchronized (stateLock) {
                 readerThread = 0;
-                // notify any thread waiting in implCloseSelectableChannel
                 if (state == ST_CLOSING) {
-                    stateCondition.signalAll();
+                    tryFinishClose();
                 }
-            } finally {
-                stateLock.unlock();
             }
             // remove hook for Thread.interrupt
             end(completed);
@@ -467,15 +436,12 @@
             // set hook for Thread.interrupt
             begin();
 
-            stateLock.lock();
-            try {
+            synchronized (stateLock) {
                 ensureOpenAndConnected();
                 if (isOutputClosed)
                     throw new ClosedChannelException();
                 // record thread so it can be signalled if needed
                 writerThread = NativeThread.current();
-            } finally {
-                stateLock.unlock();
             }
         } else {
             ensureOpenAndConnected();
@@ -492,15 +458,11 @@
         throws AsynchronousCloseException
     {
         if (blocking) {
-            stateLock.lock();
-            try {
+            synchronized (stateLock) {
                 writerThread = 0;
-                // notify any thread waiting in implCloseSelectableChannel
                 if (state == ST_CLOSING) {
-                    stateCondition.signalAll();
+                    tryFinishClose();
                 }
-            } finally {
-                stateLock.unlock();
             }
             // remove hook for Thread.interrupt
             end(completed);
@@ -613,12 +575,9 @@
      */
     private void lockedConfigureBlocking(boolean block) throws IOException {
         assert readLock.isHeldByCurrentThread() || writeLock.isHeldByCurrentThread();
-        stateLock.lock();
-        try {
+        synchronized (stateLock) {
             ensureOpen();
             IOUtil.configureBlocking(fd, block);
-        } finally {
-            stateLock.unlock();
         }
     }
 
@@ -626,11 +585,8 @@
      * Returns the local address, or null if not bound
      */
     InetSocketAddress localAddress() {
-        stateLock.lock();
-        try {
+        synchronized (stateLock) {
             return localAddress;
-        } finally {
-            stateLock.unlock();
         }
     }
 
@@ -638,11 +594,8 @@
      * Returns the remote address, or null if not connected
      */
     InetSocketAddress remoteAddress() {
-        stateLock.lock();
-        try {
+        synchronized (stateLock) {
             return remoteAddress;
-        } finally {
-            stateLock.unlock();
         }
     }
 
@@ -652,8 +605,7 @@
         try {
             writeLock.lock();
             try {
-                stateLock.lock();
-                try {
+                synchronized (stateLock) {
                     ensureOpen();
                     if (state == ST_CONNECTIONPENDING)
                         throw new ConnectionPendingException();
@@ -668,8 +620,6 @@
                     NetHooks.beforeTcpBind(fd, isa.getAddress(), isa.getPort());
                     Net.bind(fd, isa.getAddress(), isa.getPort());
                     localAddress = Net.localAddress(fd);
-                } finally {
-                    stateLock.unlock();
                 }
             } finally {
                 writeLock.unlock();
@@ -706,8 +656,7 @@
             // set hook for Thread.interrupt
             begin();
         }
-        stateLock.lock();
-        try {
+        synchronized (stateLock) {
             ensureOpen();
             int state = this.state;
             if (state == ST_CONNECTED)
@@ -725,8 +674,6 @@
                 // record thread so it can be signalled if needed
                 readerThread = NativeThread.current();
             }
-        } finally {
-            stateLock.unlock();
         }
     }
 
@@ -743,14 +690,11 @@
         endRead(blocking, completed);
 
         if (completed) {
-            stateLock.lock();
-            try {
+            synchronized (stateLock) {
                 if (state == ST_CONNECTIONPENDING) {
                     localAddress = Net.localAddress(fd);
                     state = ST_CONNECTED;
                 }
-            } finally {
-                stateLock.unlock();
             }
         }
     }
@@ -823,8 +767,7 @@
             // set hook for Thread.interrupt
             begin();
         }
-        stateLock.lock();
-        try {
+        synchronized (stateLock) {
             ensureOpen();
             if (state != ST_CONNECTIONPENDING)
                 throw new NoConnectionPendingException();
@@ -832,8 +775,6 @@
                 // record thread so it can be signalled if needed
                 readerThread = NativeThread.current();
             }
-        } finally {
-            stateLock.unlock();
         }
     }
 
@@ -850,14 +791,11 @@
         endRead(blocking, completed);
 
         if (completed) {
-            stateLock.lock();
-            try {
+            synchronized (stateLock) {
                 if (state == ST_CONNECTIONPENDING) {
                     localAddress = Net.localAddress(fd);
                     state = ST_CONNECTED;
                 }
-            } finally {
-                stateLock.unlock();
             }
         }
     }
@@ -904,90 +842,89 @@
     }
 
     /**
-     * Invoked by implCloseChannel to close the channel.
-     *
-     * This method waits for outstanding I/O operations to complete. When in
-     * blocking mode, the socket is pre-closed and the threads in blocking I/O
-     * operations are signalled to ensure that the outstanding I/O operations
-     * complete quickly.
-     *
-     * If the socket is connected then it is shutdown by this method. The
-     * shutdown ensures that the peer reads EOF for the case that the socket is
-     * not pre-closed or closed by this method.
-     *
-     * The socket is closed by this method when it is not registered with a
-     * Selector. Note that a channel configured blocking may be registered with
-     * a Selector. This arises when a key is canceled and the channel configured
-     * to blocking mode before the key is flushed from the Selector.
+     * Closes the socket if there are no I/O operations in progress and the
+     * channel is not registered with a Selector.
      */
-    @Override
-    protected void implCloseSelectableChannel() throws IOException {
-        assert !isOpen();
+    private boolean tryClose() throws IOException {
+        assert Thread.holdsLock(stateLock) && state == ST_CLOSING;
+        if ((readerThread == 0) && (writerThread == 0) && !isRegistered()) {
+            state = ST_CLOSED;
+            nd.close(fd);
+            return true;
+        } else {
+            return false;
+        }
+    }
 
-        boolean blocking;
-        boolean connected;
-        boolean interrupted = false;
+    /**
+     * Invokes tryClose to attempt to close the socket.
+     *
+     * This method is used for deferred closing by I/O and Selector operations.
+     */
+    private void tryFinishClose() {
+        try {
+            tryClose();
+        } catch (IOException ignore) { }
+    }
 
-        // set state to ST_CLOSING
-        stateLock.lock();
-        try {
+    /**
+     * Closes this channel when configured in blocking mode.
+     *
+     * If there is an I/O operation in progress then the socket is pre-closed
+     * and the I/O threads signalled, in which case the final close is deferred
+     * until all I/O operations complete.
+     *
+     * Note that a channel configured blocking may be registered with a Selector
+     * This arises when a key is canceled and the channel configured to blocking
+     * mode before the key is flushed from the Selector.
+     */
+    private void implCloseBlockingMode() throws IOException {
+        synchronized (stateLock) {
             assert state < ST_CLOSING;
-            blocking = isBlocking();
-            connected = (state == ST_CONNECTED);
             state = ST_CLOSING;
-        } finally {
-            stateLock.unlock();
-        }
-
-        // wait for any outstanding I/O operations to complete
-        if (blocking) {
-            stateLock.lock();
-            try {
-                assert state == ST_CLOSING;
+            if (!tryClose()) {
                 long reader = readerThread;
                 long writer = writerThread;
                 if (reader != 0 || writer != 0) {
                     nd.preClose(fd);
-                    connected = false; // fd is no longer connected socket
-
                     if (reader != 0)
                         NativeThread.signal(reader);
                     if (writer != 0)
                         NativeThread.signal(writer);
-
-                    // wait for blocking I/O operations to end
-                    while (readerThread != 0 || writerThread != 0) {
-                        try {
-                            stateCondition.await();
-                        } catch (InterruptedException e) {
-                            interrupted = true;
-                        }
-                    }
                 }
-            } finally {
-                stateLock.unlock();
-            }
-        } else {
-            // non-blocking mode: wait for read/write to complete
-            readLock.lock();
-            try {
-                writeLock.lock();
-                writeLock.unlock();
-            } finally {
-                readLock.unlock();
             }
         }
+    }
 
-        // set state to ST_KILLPENDING
-        stateLock.lock();
-        try {
-            assert state == ST_CLOSING;
-            // if connected and the channel is registered with a Selector then
-            // shutdown the output if possible so that the peer reads EOF. If
-            // SO_LINGER is enabled and set to a non-zero value then it needs to
-            // be disabled so that the Selector does not wait when it closes
-            // the socket.
-            if (connected && isRegistered()) {
+    /**
+     * Closes this channel when configured in non-blocking mode.
+     *
+     * If the channel is registered with a Selector then the close is deferred
+     * until the channel is flushed from all Selectors.
+     *
+     * If the socket is connected and the channel is registered with a Selector
+     * then the socket is shutdown for writing so that the peer reads EOF. In
+     * addition, if SO_LINGER is set to a non-zero value then it is disabled so
+     * that the deferred close does not wait.
+     */
+    private void implCloseNonBlockingMode() throws IOException {
+        boolean connected;
+        synchronized (stateLock) {
+            assert state < ST_CLOSING;
+            connected = (state == ST_CONNECTED);
+            state = ST_CLOSING;
+        }
+
+        // wait for any read/write operations to complete
+        readLock.lock();
+        readLock.unlock();
+        writeLock.lock();
+        writeLock.unlock();
+
+        // if the socket cannot be closed because it's registered with a Selector
+        // then shutdown the socket for writing.
+        synchronized (stateLock) {
+            if (state == ST_CLOSING && !tryClose() && connected && isRegistered()) {
                 try {
                     SocketOption<Integer> opt = StandardSocketOptions.SO_LINGER;
                     int interval = (int) Net.getSocketOption(fd, Net.UNSPEC, opt);
@@ -1000,37 +937,34 @@
                     }
                 } catch (IOException ignore) { }
             }
-            state = ST_KILLPENDING;
-        } finally {
-            stateLock.unlock();
         }
+    }
 
-        // close socket if not registered with Selector
-        if (!isRegistered())
-            kill();
-
-        // restore interrupt status
-        if (interrupted)
-            Thread.currentThread().interrupt();
+    /**
+     * Invoked by implCloseChannel to close the channel.
+     */
+    @Override
+    protected void implCloseSelectableChannel() throws IOException {
+        assert !isOpen();
+        if (isBlocking()) {
+            implCloseBlockingMode();
+        } else {
+            implCloseNonBlockingMode();
+        }
     }
 
     @Override
-    public void kill() throws IOException {
-        stateLock.lock();
-        try {
-            if (state == ST_KILLPENDING) {
-                state = ST_KILLED;
-                nd.close(fd);
+    public void kill() {
+        synchronized (stateLock) {
+            if (state == ST_CLOSING) {
+                tryFinishClose();
             }
-        } finally {
-            stateLock.unlock();
         }
     }
 
     @Override
     public SocketChannel shutdownInput() throws IOException {
-        stateLock.lock();
-        try {
+        synchronized (stateLock) {
             ensureOpen();
             if (!isConnected())
                 throw new NotYetConnectedException();
@@ -1042,15 +976,12 @@
                 isInputClosed = true;
             }
             return this;
-        } finally {
-            stateLock.unlock();
         }
     }
 
     @Override
     public SocketChannel shutdownOutput() throws IOException {
-        stateLock.lock();
-        try {
+        synchronized (stateLock) {
             ensureOpen();
             if (!isConnected())
                 throw new NotYetConnectedException();
@@ -1062,8 +993,6 @@
                 isOutputClosed = true;
             }
             return this;
-        } finally {
-            stateLock.unlock();
         }
     }
 
@@ -1300,16 +1229,13 @@
      * Return the number of bytes in the socket input buffer.
      */
     int available() throws IOException {
-        stateLock.lock();
-        try {
+        synchronized (stateLock) {
             ensureOpenAndConnected();
             if (isInputClosed) {
                 return 0;
             } else {
                 return Net.available(fd);
             }
-        } finally {
-            stateLock.unlock();
         }
     }
 
@@ -1389,8 +1315,7 @@
         if (!isOpen())
             sb.append("closed");
         else {
-            stateLock.lock();
-            try {
+            synchronized (stateLock) {
                 switch (state) {
                 case ST_UNCONNECTED:
                     sb.append("unconnected");
@@ -1415,8 +1340,6 @@
                     sb.append(" remote=");
                     sb.append(remoteAddress().toString());
                 }
-            } finally {
-                stateLock.unlock();
             }
         }
         sb.append(']');
--- a/src/java.base/unix/classes/sun/nio/ch/SinkChannelImpl.java	Thu May 23 14:12:43 2019 +0200
+++ b/src/java.base/unix/classes/sun/nio/ch/SinkChannelImpl.java	Thu May 23 14:13:01 2019 +0200
@@ -35,7 +35,6 @@
 import java.nio.channels.SelectionKey;
 import java.nio.channels.spi.SelectorProvider;
 import java.util.Objects;
-import java.util.concurrent.locks.Condition;
 import java.util.concurrent.locks.ReentrantLock;
 
 class SinkChannelImpl
@@ -54,16 +53,14 @@
 
     // Lock held by any thread that modifies the state fields declared below
     // DO NOT invoke a blocking I/O operation while holding this lock!
-    private final ReentrantLock stateLock = new ReentrantLock();
-    private final Condition stateCondition = stateLock.newCondition();
+    private final Object stateLock = new Object();
 
     // -- The following fields are protected by stateLock
 
     // Channel state
     private static final int ST_INUSE = 0;
     private static final int ST_CLOSING = 1;
-    private static final int ST_KILLPENDING = 2;
-    private static final int ST_KILLED = 3;
+    private static final int ST_CLOSED = 2;
     private int state;
 
     // ID of native thread doing write, for signalling
@@ -87,82 +84,92 @@
     }
 
     /**
+     * Closes the write end of the pipe if there are no write operation in
+     * progress and the channel is not registered with a Selector.
+     */
+    private boolean tryClose() throws IOException {
+        assert Thread.holdsLock(stateLock) && state == ST_CLOSING;
+        if (thread == 0 && !isRegistered()) {
+            state = ST_CLOSED;
+            nd.close(fd);
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Invokes tryClose to attempt to close the write end of the pipe.
+     *
+     * This method is used for deferred closing by I/O and Selector operations.
+     */
+    private void tryFinishClose() {
+        try {
+            tryClose();
+        } catch (IOException ignore) { }
+    }
+
+    /**
+     * Closes this channel when configured in blocking mode.
+     *
+     * If there is a write operation in progress then the write-end of the pipe
+     * is pre-closed and the writer is signalled, in which case the final close
+     * is deferred until the writer aborts.
+     */
+    private void implCloseBlockingMode() throws IOException {
+        synchronized (stateLock) {
+            assert state < ST_CLOSING;
+            state = ST_CLOSING;
+            if (!tryClose()) {
+                long th = thread;
+                if (th != 0) {
+                    nd.preClose(fd);
+                    NativeThread.signal(th);
+                }
+            }
+        }
+    }
+
+    /**
+     * Closes this channel when configured in non-blocking mode.
+     *
+     * If the channel is registered with a Selector then the close is deferred
+     * until the channel is flushed from all Selectors.
+     */
+    private void implCloseNonBlockingMode() throws IOException {
+        synchronized (stateLock) {
+            assert state < ST_CLOSING;
+            state = ST_CLOSING;
+        }
+        // wait for any write operation to complete before trying to close
+        writeLock.lock();
+        writeLock.unlock();
+        synchronized (stateLock) {
+            if (state == ST_CLOSING) {
+                tryClose();
+            }
+        }
+    }
+
+    /**
      * Invoked by implCloseChannel to close the channel.
      */
     @Override
     protected void implCloseSelectableChannel() throws IOException {
         assert !isOpen();
-
-        boolean interrupted = false;
-        boolean blocking;
-
-        // set state to ST_CLOSING
-        stateLock.lock();
-        try {
-            assert state < ST_CLOSING;
-            state = ST_CLOSING;
-            blocking = isBlocking();
-        } finally {
-            stateLock.unlock();
+        if (isBlocking()) {
+            implCloseBlockingMode();
+        } else {
+            implCloseNonBlockingMode();
         }
-
-        // wait for any outstanding write to complete
-        if (blocking) {
-            stateLock.lock();
-            try {
-                assert state == ST_CLOSING;
-                long th = thread;
-                if (th != 0) {
-                    nd.preClose(fd);
-                    NativeThread.signal(th);
-
-                    // wait for write operation to end
-                    while (thread != 0) {
-                        try {
-                            stateCondition.await();
-                        } catch (InterruptedException e) {
-                            interrupted = true;
-                        }
-                    }
-                }
-            } finally {
-                stateLock.unlock();
-            }
-        } else {
-            // non-blocking mode: wait for write to complete
-            writeLock.lock();
-            writeLock.unlock();
-        }
-
-        // set state to ST_KILLPENDING
-        stateLock.lock();
-        try {
-            assert state == ST_CLOSING;
-            state = ST_KILLPENDING;
-        } finally {
-            stateLock.unlock();
-        }
-
-        // close socket if not registered with Selector
-        if (!isRegistered())
-            kill();
-
-        // restore interrupt status
-        if (interrupted)
-            Thread.currentThread().interrupt();
     }
 
     @Override
-    public void kill() throws IOException {
-        stateLock.lock();
-        try {
-            assert thread == 0;
-            if (state == ST_KILLPENDING) {
-                state = ST_KILLED;
-                nd.close(fd);
+    public void kill() {
+        synchronized (stateLock) {
+            if (state == ST_CLOSING) {
+                tryFinishClose();
             }
-        } finally {
-            stateLock.unlock();
         }
     }
 
@@ -170,11 +177,10 @@
     protected void implConfigureBlocking(boolean block) throws IOException {
         writeLock.lock();
         try {
-            stateLock.lock();
-            try {
+            synchronized (stateLock) {
+                if (!isOpen())
+                    throw new ClosedChannelException();
                 IOUtil.configureBlocking(fd, block);
-            } finally {
-                stateLock.unlock();
             }
         } finally {
             writeLock.unlock();
@@ -229,14 +235,11 @@
             // set hook for Thread.interrupt
             begin();
         }
-        stateLock.lock();
-        try {
+        synchronized (stateLock) {
             if (!isOpen())
                 throw new ClosedChannelException();
             if (blocking)
                 thread = NativeThread.current();
-        } finally {
-            stateLock.unlock();
         }
     }
 
@@ -250,15 +253,11 @@
         throws AsynchronousCloseException
     {
         if (blocking) {
-            stateLock.lock();
-            try {
+            synchronized (stateLock) {
                 thread = 0;
-                // notify any thread waiting in implCloseSelectableChannel
                 if (state == ST_CLOSING) {
-                    stateCondition.signalAll();
+                    tryFinishClose();
                 }
-            } finally {
-                stateLock.unlock();
             }
             // remove hook for Thread.interrupt
             end(completed);
--- a/src/java.base/unix/classes/sun/nio/ch/SourceChannelImpl.java	Thu May 23 14:12:43 2019 +0200
+++ b/src/java.base/unix/classes/sun/nio/ch/SourceChannelImpl.java	Thu May 23 14:13:01 2019 +0200
@@ -35,7 +35,6 @@
 import java.nio.channels.SelectionKey;
 import java.nio.channels.spi.SelectorProvider;
 import java.util.Objects;
-import java.util.concurrent.locks.Condition;
 import java.util.concurrent.locks.ReentrantLock;
 
 class SourceChannelImpl
@@ -54,16 +53,14 @@
 
     // Lock held by any thread that modifies the state fields declared below
     // DO NOT invoke a blocking I/O operation while holding this lock!
-    private final ReentrantLock stateLock = new ReentrantLock();
-    private final Condition stateCondition = stateLock.newCondition();
+    private final Object stateLock = new Object();
 
     // -- The following fields are protected by stateLock
 
     // Channel state
     private static final int ST_INUSE = 0;
     private static final int ST_CLOSING = 1;
-    private static final int ST_KILLPENDING = 2;
-    private static final int ST_KILLED = 3;
+    private static final int ST_CLOSED = 2;
     private int state;
 
     // ID of native thread doing read, for signalling
@@ -87,82 +84,92 @@
     }
 
     /**
+     * Closes the read end of the pipe if there are no read operation in
+     * progress and the channel is not registered with a Selector.
+     */
+    private boolean tryClose() throws IOException {
+        assert Thread.holdsLock(stateLock) && state == ST_CLOSING;
+        if (thread == 0 && !isRegistered()) {
+            state = ST_CLOSED;
+            nd.close(fd);
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Invokes tryClose to attempt to close the read end of the pipe.
+     *
+     * This method is used for deferred closing by I/O and Selector operations.
+     */
+    private void tryFinishClose() {
+        try {
+            tryClose();
+        } catch (IOException ignore) { }
+    }
+
+    /**
+     * Closes this channel when configured in blocking mode.
+     *
+     * If there is a read operation in progress then the read-end of the pipe
+     * is pre-closed and the reader is signalled, in which case the final close
+     * is deferred until the reader aborts.
+     */
+    private void implCloseBlockingMode() throws IOException {
+        synchronized (stateLock) {
+            assert state < ST_CLOSING;
+            state = ST_CLOSING;
+            if (!tryClose()) {
+                long th = thread;
+                if (th != 0) {
+                    nd.preClose(fd);
+                    NativeThread.signal(th);
+                }
+            }
+        }
+    }
+
+    /**
+     * Closes this channel when configured in non-blocking mode.
+     *
+     * If the channel is registered with a Selector then the close is deferred
+     * until the channel is flushed from all Selectors.
+     */
+    private void implCloseNonBlockingMode() throws IOException {
+        synchronized (stateLock) {
+            assert state < ST_CLOSING;
+            state = ST_CLOSING;
+        }
+        // wait for any read operation to complete before trying to close
+        readLock.lock();
+        readLock.unlock();
+        synchronized (stateLock) {
+            if (state == ST_CLOSING) {
+                tryClose();
+            }
+        }
+    }
+
+    /**
      * Invoked by implCloseChannel to close the channel.
      */
     @Override
     protected void implCloseSelectableChannel() throws IOException {
         assert !isOpen();
-
-        boolean interrupted = false;
-        boolean blocking;
-
-        // set state to ST_CLOSING
-        stateLock.lock();
-        try {
-            assert state < ST_CLOSING;
-            state = ST_CLOSING;
-            blocking = isBlocking();
-        } finally {
-            stateLock.unlock();
+        if (isBlocking()) {
+            implCloseBlockingMode();
+        } else {
+            implCloseNonBlockingMode();
         }
-
-        // wait for any outstanding read to complete
-        if (blocking) {
-            stateLock.lock();
-            try {
-                assert state == ST_CLOSING;
-                long th = thread;
-                if (th != 0) {
-                    nd.preClose(fd);
-                    NativeThread.signal(th);
-
-                    // wait for read operation to end
-                    while (thread != 0) {
-                        try {
-                            stateCondition.await();
-                        } catch (InterruptedException e) {
-                            interrupted = true;
-                        }
-                    }
-                }
-            } finally {
-                stateLock.unlock();
+    }
+    @Override
+    public void kill() {
+        synchronized (stateLock) {
+            assert !isOpen();
+            if (state == ST_CLOSING) {
+                tryFinishClose();
             }
-        } else {
-            // non-blocking mode: wait for read to complete
-            readLock.lock();
-            readLock.unlock();
-        }
-
-        // set state to ST_KILLPENDING
-        stateLock.lock();
-        try {
-            assert state == ST_CLOSING;
-            state = ST_KILLPENDING;
-        } finally {
-            stateLock.unlock();
-        }
-
-        // close socket if not registered with Selector
-        if (!isRegistered())
-            kill();
-
-        // restore interrupt status
-        if (interrupted)
-            Thread.currentThread().interrupt();
-    }
-
-    @Override
-    public void kill() throws IOException {
-        stateLock.lock();
-        try {
-            assert thread == 0;
-            if (state == ST_KILLPENDING) {
-                state = ST_KILLED;
-                nd.close(fd);
-            }
-        } finally {
-            stateLock.unlock();
         }
     }
 
@@ -170,11 +177,10 @@
     protected void implConfigureBlocking(boolean block) throws IOException {
         readLock.lock();
         try {
-            stateLock.lock();
-            try {
+            synchronized (stateLock) {
+                if (!isOpen())
+                    throw new ClosedChannelException();
                 IOUtil.configureBlocking(fd, block);
-            } finally {
-                stateLock.unlock();
             }
         } finally {
             readLock.unlock();
@@ -229,14 +235,11 @@
             // set hook for Thread.interrupt
             begin();
         }
-        stateLock.lock();
-        try {
+        synchronized (stateLock) {
             if (!isOpen())
                 throw new ClosedChannelException();
             if (blocking)
                 thread = NativeThread.current();
-        } finally {
-            stateLock.unlock();
         }
     }
 
@@ -250,15 +253,11 @@
         throws AsynchronousCloseException
     {
         if (blocking) {
-            stateLock.lock();
-            try {
+            synchronized (stateLock) {
                 thread = 0;
-                // notify any thread waiting in implCloseSelectableChannel
                 if (state == ST_CLOSING) {
-                    stateCondition.signalAll();
+                    tryFinishClose();
                 }
-            } finally {
-                stateLock.unlock();
             }
             // remove hook for Thread.interrupt
             end(completed);
--- a/test/hotspot/gtest/oops/test_markOop.cpp	Thu May 23 14:12:43 2019 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,140 +0,0 @@
-/*
- * Copyright (c) 2019, 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.
- */
-
-#include "precompiled.hpp"
-#include "classfile/systemDictionary.hpp"
-#include "memory/resourceArea.hpp"
-#include "memory/universe.hpp"
-#include "oops/oop.inline.hpp"
-#include "runtime/atomic.hpp"
-#include "runtime/interfaceSupport.inline.hpp"
-#include "runtime/orderAccess.hpp"
-#include "runtime/os.hpp"
-#include "runtime/synchronizer.hpp"
-#include "threadHelper.inline.hpp"
-#include "unittest.hpp"
-#include "utilities/globalDefinitions.hpp"
-#include "utilities/ostream.hpp"
-
-// The test doesn't work for PRODUCT because it needs WizardMode
-#ifndef PRODUCT
-static bool test_pattern(stringStream* st, const char* pattern) {
-  return (strstr(st->as_string(), pattern) != NULL);
-}
-
-static void assert_test_pattern(Handle object, const char* pattern) {
-  stringStream st;
-  object->print_on(&st);
-  ASSERT_TRUE(test_pattern(&st, pattern)) << pattern << " not in " << st.as_string();
-}
-
-static void assert_not_test_pattern(Handle object, const char* pattern) {
-  stringStream st;
-  object->print_on(&st);
-  ASSERT_FALSE(test_pattern(&st, pattern)) << pattern << " found in " << st.as_string();
-}
-
-class LockerThread : public JavaTestThread {
-  oop _obj;
-  public:
-  LockerThread(Semaphore* post, oop obj) : JavaTestThread(post), _obj(obj) {}
-  virtual ~LockerThread() {}
-
-  void main_run() {
-    Thread* THREAD = Thread::current();
-    HandleMark hm(THREAD);
-    Handle h_obj(THREAD, _obj);
-    ResourceMark rm(THREAD);
-
-    // Wait gets the lock inflated.
-    // The object will stay locked for the context of 'ol' so the lock will
-    // still be inflated after the notify_all() call. Deflation can't happen
-    // while an ObjectMonitor is "busy" and being locked is the most "busy"
-    // state we have...
-    ObjectLocker ol(h_obj, THREAD);
-    ol.notify_all(THREAD);
-    assert_test_pattern(h_obj, "monitor");
-  }
-};
-
-
-TEST_VM(markOopDesc, printing) {
-  JavaThread* THREAD = JavaThread::current();
-  ThreadInVMfromNative invm(THREAD);
-  ResourceMark rm(THREAD);
-
-  oop obj = SystemDictionary::Byte_klass()->allocate_instance(THREAD);
-
-  FlagSetting fs(WizardMode, true);
-  FlagSetting bf(UseBiasedLocking, true);
-
-  HandleMark hm(THREAD);
-  Handle h_obj(THREAD, obj);
-
-  // Biased locking is initially enabled for this java.lang.Byte object.
-  assert_test_pattern(h_obj, "is_biased");
-
-  // Lock using biased locking.
-  BasicObjectLock lock;
-  lock.set_obj(obj);
-  markOop mark = obj->mark()->incr_bias_epoch();
-  obj->set_mark(mark);
-  ObjectSynchronizer::fast_enter(h_obj, lock.lock(), true, THREAD);
-#ifdef _LP64
-  // Look for the biased_locker in markOop, not prototype_header.
-  assert_not_test_pattern(h_obj, "mark(is_biased biased_locker=0x0000000000000000");
-#endif
-
-  // Same thread tries to lock it again.
-  {
-    ObjectLocker ol(h_obj, THREAD);
-    assert_test_pattern(h_obj, "locked");
-  }
-
-  // This is no longer biased, because ObjectLocker revokes the bias.
-  assert_test_pattern(h_obj, "is_neutral no_hash");
-
-  // Wait gets the lock inflated.
-  {
-    ObjectLocker ol(h_obj, THREAD);
-
-    Semaphore done(0);
-    LockerThread* st;
-    st = new LockerThread(&done, h_obj());
-    st->doit();
-
-    ol.wait(THREAD);
-    assert_test_pattern(h_obj, "monitor");
-  }
-
-  // Make the object older. Not all GCs use this field.
-  Universe::heap()->collect(GCCause::_java_lang_system_gc);
-  if (UseParallelGC) {
-    assert_test_pattern(h_obj, "is_neutral no_hash age 1");
-  }
-
-  // Hash the object then print it.
-  intx hash = h_obj->identity_hash();
-  assert_test_pattern(h_obj, "is_neutral hash=0x");
-}
-#endif // PRODUCT