(obj) >> 5) & (NINFLATIONLOCKS-1);
int YieldThenBlock = 0;
assert(ix >= 0 && ix < NINFLATIONLOCKS, "invariant");
- assert((NINFLATIONLOCKS & (NINFLATIONLOCKS-1)) == 0, "invariant");
- Thread::muxAcquire(gInflationLocks + ix, "gInflationLock");
+ gInflationLocks[ix]->lock();
while (obj->mark() == markWord::INFLATING()) {
- // Beware: NakedYield() is advisory and has almost no effect on some platforms
+ // Beware: naked_yield() is advisory and has almost no effect on some platforms
// so we periodically call self->_ParkEvent->park(1).
// We use a mixed spin/yield/block mechanism.
if ((YieldThenBlock++) >= 16) {
@@ -792,7 +792,7 @@ static markWord read_stable_mark(oop obj) {
os::naked_yield();
}
}
- Thread::muxRelease(gInflationLocks + ix);
+ gInflationLocks[ix]->unlock();
}
} else {
SpinPause(); // SMP-polite spinning
diff --git a/src/hotspot/share/runtime/synchronizer.hpp b/src/hotspot/share/runtime/synchronizer.hpp
index 685561cf54b8d..16657c60e6fbc 100644
--- a/src/hotspot/share/runtime/synchronizer.hpp
+++ b/src/hotspot/share/runtime/synchronizer.hpp
@@ -29,6 +29,7 @@
#include "oops/markWord.hpp"
#include "runtime/basicLock.hpp"
#include "runtime/handles.hpp"
+#include "runtime/os.hpp"
#include "runtime/perfData.hpp"
class LogStream;
@@ -114,6 +115,9 @@ class ObjectSynchronizer : AllStatic {
static void release_monitors_owned_by_thread(TRAPS);
static void monitors_iterate(MonitorClosure* m);
+ // Initialize the gInflationLocks
+ static void initialize();
+
// GC: we current use aggressive monitor deflation policy
// Basically we try to deflate all monitors that are not busy.
static size_t deflate_idle_monitors();
diff --git a/src/hotspot/share/runtime/thread.cpp b/src/hotspot/share/runtime/thread.cpp
index bdc17b380b2d8..2366db0c11514 100644
--- a/src/hotspot/share/runtime/thread.cpp
+++ b/src/hotspot/share/runtime/thread.cpp
@@ -291,7 +291,6 @@ Thread::Thread() {
// The stack would act as a cache to avoid calls to ParkEvent::Allocate()
// and ::Release()
_ParkEvent = ParkEvent::Allocate(this);
- _MuxEvent = ParkEvent::Allocate(this);
#ifdef CHECK_UNHANDLED_OOPS
if (CheckUnhandledOops) {
@@ -439,7 +438,6 @@ Thread::~Thread() {
// It's possible we can encounter a null _ParkEvent, etc., in stillborn threads.
// We NULL out the fields for good hygiene.
ParkEvent::Release(_ParkEvent); _ParkEvent = NULL;
- ParkEvent::Release(_MuxEvent); _MuxEvent = NULL;
delete handle_area();
delete metadata_handles();
@@ -3560,6 +3558,7 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) {
// Initialize Java-Level synchronization subsystem
ObjectMonitor::Initialize();
+ ObjectSynchronizer::initialize();
// Initialize global modules
jint status = init_globals();
@@ -4582,22 +4581,11 @@ void Threads::print_threads_compiling(outputStream* st, char* buf, int buflen, b
}
-// Internal SpinLock and Mutex
-// Based on ParkEvent
-
-// Ad-hoc mutual exclusion primitives: SpinLock and Mux
+// Ad-hoc mutual exclusion primitives: SpinLock
//
// We employ SpinLocks _only for low-contention, fixed-length
// short-duration critical sections where we're concerned
// about native mutex_t or HotSpot Mutex:: latency.
-// The mux construct provides a spin-then-block mutual exclusion
-// mechanism.
-//
-// Testing has shown that contention on the ListLock guarding gFreeList
-// is common. If we implement ListLock as a simple SpinLock it's common
-// for the JVM to devolve to yielding with little progress. This is true
-// despite the fact that the critical sections protected by ListLock are
-// extremely short.
//
// TODO-FIXME: ListLock should be of type SpinLock.
// We should make this a 1st-class type, integrated into the lock
@@ -4650,150 +4638,6 @@ void Thread::SpinRelease(volatile int * adr) {
*adr = 0;
}
-// muxAcquire and muxRelease:
-//
-// * muxAcquire and muxRelease support a single-word lock-word construct.
-// The LSB of the word is set IFF the lock is held.
-// The remainder of the word points to the head of a singly-linked list
-// of threads blocked on the lock.
-//
-// * The current implementation of muxAcquire-muxRelease uses its own
-// dedicated Thread._MuxEvent instance. If we're interested in
-// minimizing the peak number of extant ParkEvent instances then
-// we could eliminate _MuxEvent and "borrow" _ParkEvent as long
-// as certain invariants were satisfied. Specifically, care would need
-// to be taken with regards to consuming unpark() "permits".
-// A safe rule of thumb is that a thread would never call muxAcquire()
-// if it's enqueued (cxq, EntryList, WaitList, etc) and will subsequently
-// park(). Otherwise the _ParkEvent park() operation in muxAcquire() could
-// consume an unpark() permit intended for monitorenter, for instance.
-// One way around this would be to widen the restricted-range semaphore
-// implemented in park(). Another alternative would be to provide
-// multiple instances of the PlatformEvent() for each thread. One
-// instance would be dedicated to muxAcquire-muxRelease, for instance.
-//
-// * Usage:
-// -- Only as leaf locks
-// -- for short-term locking only as muxAcquire does not perform
-// thread state transitions.
-//
-// Alternatives:
-// * We could implement muxAcquire and muxRelease with MCS or CLH locks
-// but with parking or spin-then-park instead of pure spinning.
-// * Use Taura-Oyama-Yonenzawa locks.
-// * It's possible to construct a 1-0 lock if we encode the lockword as
-// (List,LockByte). Acquire will CAS the full lockword while Release
-// will STB 0 into the LockByte. The 1-0 scheme admits stranding, so
-// acquiring threads use timers (ParkTimed) to detect and recover from
-// the stranding window. Thread/Node structures must be aligned on 256-byte
-// boundaries by using placement-new.
-// * Augment MCS with advisory back-link fields maintained with CAS().
-// Pictorially: LockWord -> T1 <-> T2 <-> T3 <-> ... <-> Tn <-> Owner.
-// The validity of the backlinks must be ratified before we trust the value.
-// If the backlinks are invalid the exiting thread must back-track through the
-// the forward links, which are always trustworthy.
-// * Add a successor indication. The LockWord is currently encoded as
-// (List, LOCKBIT:1). We could also add a SUCCBIT or an explicit _succ variable
-// to provide the usual futile-wakeup optimization.
-// See RTStt for details.
-//
-
-
-const intptr_t LOCKBIT = 1;
-
-void Thread::muxAcquire(volatile intptr_t * Lock, const char * LockName) {
- intptr_t w = Atomic::cmpxchg(Lock, (intptr_t)0, LOCKBIT);
- if (w == 0) return;
- if ((w & LOCKBIT) == 0 && Atomic::cmpxchg(Lock, w, w|LOCKBIT) == w) {
- return;
- }
-
- ParkEvent * const Self = Thread::current()->_MuxEvent;
- assert((intptr_t(Self) & LOCKBIT) == 0, "invariant");
- for (;;) {
- int its = (os::is_MP() ? 100 : 0) + 1;
-
- // Optional spin phase: spin-then-park strategy
- while (--its >= 0) {
- w = *Lock;
- if ((w & LOCKBIT) == 0 && Atomic::cmpxchg(Lock, w, w|LOCKBIT) == w) {
- return;
- }
- }
-
- Self->reset();
- Self->OnList = intptr_t(Lock);
- // The following fence() isn't _strictly necessary as the subsequent
- // CAS() both serializes execution and ratifies the fetched *Lock value.
- OrderAccess::fence();
- for (;;) {
- w = *Lock;
- if ((w & LOCKBIT) == 0) {
- if (Atomic::cmpxchg(Lock, w, w|LOCKBIT) == w) {
- Self->OnList = 0; // hygiene - allows stronger asserts
- return;
- }
- continue; // Interference -- *Lock changed -- Just retry
- }
- assert(w & LOCKBIT, "invariant");
- Self->ListNext = (ParkEvent *) (w & ~LOCKBIT);
- if (Atomic::cmpxchg(Lock, w, intptr_t(Self)|LOCKBIT) == w) break;
- }
-
- while (Self->OnList != 0) {
- Self->park();
- }
- }
-}
-
-// Release() must extract a successor from the list and then wake that thread.
-// It can "pop" the front of the list or use a detach-modify-reattach (DMR) scheme
-// similar to that used by ParkEvent::Allocate() and ::Release(). DMR-based
-// Release() would :
-// (A) CAS() or swap() null to *Lock, releasing the lock and detaching the list.
-// (B) Extract a successor from the private list "in-hand"
-// (C) attempt to CAS() the residual back into *Lock over null.
-// If there were any newly arrived threads and the CAS() would fail.
-// In that case Release() would detach the RATs, re-merge the list in-hand
-// with the RATs and repeat as needed. Alternately, Release() might
-// detach and extract a successor, but then pass the residual list to the wakee.
-// The wakee would be responsible for reattaching and remerging before it
-// competed for the lock.
-//
-// Both "pop" and DMR are immune from ABA corruption -- there can be
-// multiple concurrent pushers, but only one popper or detacher.
-// This implementation pops from the head of the list. This is unfair,
-// but tends to provide excellent throughput as hot threads remain hot.
-// (We wake recently run threads first).
-//
-// All paths through muxRelease() will execute a CAS.
-// Release consistency -- We depend on the CAS in muxRelease() to provide full
-// bidirectional fence/MEMBAR semantics, ensuring that all prior memory operations
-// executed within the critical section are complete and globally visible before the
-// store (CAS) to the lock-word that releases the lock becomes globally visible.
-void Thread::muxRelease(volatile intptr_t * Lock) {
- for (;;) {
- const intptr_t w = Atomic::cmpxchg(Lock, LOCKBIT, (intptr_t)0);
- assert(w & LOCKBIT, "invariant");
- if (w == LOCKBIT) return;
- ParkEvent * const List = (ParkEvent *) (w & ~LOCKBIT);
- assert(List != NULL, "invariant");
- assert(List->OnList == intptr_t(Lock), "invariant");
- ParkEvent * const nxt = List->ListNext;
- guarantee((intptr_t(nxt) & LOCKBIT) == 0, "invariant");
-
- // The following CAS() releases the lock and pops the head element.
- // The CAS() also ratifies the previously fetched lock-word value.
- if (Atomic::cmpxchg(Lock, w, intptr_t(nxt)) != w) {
- continue;
- }
- List->OnList = 0;
- OrderAccess::fence();
- List->unpark();
- return;
- }
-}
-
void Threads::verify() {
ALL_JAVA_THREADS(p) {
diff --git a/src/hotspot/share/runtime/thread.hpp b/src/hotspot/share/runtime/thread.hpp
index 81e6ee26fcd81..10b0a883e5712 100644
--- a/src/hotspot/share/runtime/thread.hpp
+++ b/src/hotspot/share/runtime/thread.hpp
@@ -827,8 +827,8 @@ class Thread: public ThreadShadow {
public:
volatile intptr_t _Stalled;
volatile int _TypeTag;
- ParkEvent * _ParkEvent; // for Object monitors and JVMTI raw monitors
- ParkEvent * _MuxEvent; // for low-level muxAcquire-muxRelease
+ ParkEvent * _ParkEvent; // for Object monitors, JVMTI raw monitors,
+ // and ObjectSynchronizer::read_stable_mark
int NativeSyncRecursion; // diagnostic
volatile int _OnTrap; // Resume-at IP delta
@@ -837,13 +837,10 @@ class Thread: public ThreadShadow {
jint _hashStateY;
jint _hashStateZ;
- // Low-level leaf-lock primitives used to implement synchronization
- // and native monitor-mutex infrastructure.
+ // Low-level leaf-lock primitives used to implement synchronization.
// Not for general synchronization use.
static void SpinAcquire(volatile int * Lock, const char * Name);
static void SpinRelease(volatile int * Lock);
- static void muxAcquire(volatile intptr_t * Lock, const char * Name);
- static void muxRelease(volatile intptr_t * Lock);
};
// Inline implementation of Thread::current()
diff --git a/src/java.base/share/classes/java/lang/IndexOutOfBoundsException.java b/src/java.base/share/classes/java/lang/IndexOutOfBoundsException.java
index c61d9ffadb31a..a0e338e7bd158 100644
--- a/src/java.base/share/classes/java/lang/IndexOutOfBoundsException.java
+++ b/src/java.base/share/classes/java/lang/IndexOutOfBoundsException.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1995, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2020, 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
@@ -68,4 +68,18 @@ public IndexOutOfBoundsException(String s) {
public IndexOutOfBoundsException(int index) {
super("Index out of range: " + index);
}
+
+ /**
+ * Constructs a new {@code IndexOutOfBoundsException} class with an
+ * argument indicating the illegal index.
+ *
+ * The index is included in this exception's detail message. The
+ * exact presentation format of the detail message is unspecified.
+ *
+ * @param index the illegal index.
+ * @since 16
+ */
+ public IndexOutOfBoundsException(long index) {
+ super("Index out of range: " + index);
+ }
}
diff --git a/src/java.base/share/classes/java/lang/invoke/VarHandle.java b/src/java.base/share/classes/java/lang/invoke/VarHandle.java
index 698eb8374a132..1639a75e9d936 100644
--- a/src/java.base/share/classes/java/lang/invoke/VarHandle.java
+++ b/src/java.base/share/classes/java/lang/invoke/VarHandle.java
@@ -2146,7 +2146,7 @@ final void updateVarForm(VarForm newVForm) {
UNSAFE.fullFence();
}
- static final BiFunction, ArrayIndexOutOfBoundsException>
+ static final BiFunction, ArrayIndexOutOfBoundsException>
AIOOBE_SUPPLIER = Preconditions.outOfBoundsExceptionFormatter(
new Function() {
@Override
diff --git a/src/java.base/share/classes/java/lang/invoke/X-VarHandleMemoryAccess.java.template b/src/java.base/share/classes/java/lang/invoke/X-VarHandleMemoryAccess.java.template
index c5a8ee7f724b6..0bdfd212e0783 100644
--- a/src/java.base/share/classes/java/lang/invoke/X-VarHandleMemoryAccess.java.template
+++ b/src/java.base/share/classes/java/lang/invoke/X-VarHandleMemoryAccess.java.template
@@ -39,7 +39,7 @@ import static java.lang.invoke.MethodHandleStatics.UNSAFE;
final class MemoryAccessVarHandle$Type$Helper extends MemoryAccessVarHandleBase {
static final boolean BE = UNSAFE.isBigEndian();
-
+
static final ScopedMemoryAccess SCOPED_MEMORY_ACCESS = ScopedMemoryAccess.getScopedMemoryAccess();
static final int VM_ALIGN = $BoxType$.BYTES - 1;
@@ -66,7 +66,7 @@ final class MemoryAccessVarHandle$Type$Helper extends MemoryAccessVarHandleBase
public MemoryAccessVarHandle$Type$Helper withInvokeBehavior() {
return !hasInvokeExactBehavior() ?
this :
- new MemoryAccessVarHandle$Type$Helper(skipAlignmentMaskCheck, be, length, alignmentMask, true);
+ new MemoryAccessVarHandle$Type$Helper(skipAlignmentMaskCheck, be, length, alignmentMask, false);
}
#if[floatingPoint]
diff --git a/src/java.base/share/classes/java/lang/ref/Finalizer.java b/src/java.base/share/classes/java/lang/ref/Finalizer.java
index 54b1283bb44a2..b0b27f334f88e 100644
--- a/src/java.base/share/classes/java/lang/ref/Finalizer.java
+++ b/src/java.base/share/classes/java/lang/ref/Finalizer.java
@@ -83,7 +83,8 @@ private void runFinalizer(JavaLangAccess jla) {
try {
Object finalizee = this.getInactive();
- if (finalizee != null && !(finalizee instanceof java.lang.Enum)) {
+ assert finalizee != null;
+ if (!(finalizee instanceof java.lang.Enum)) {
jla.invokeFinalize(finalizee);
// Clear stack slot containing this variable, to decrease
diff --git a/src/java.base/share/classes/java/lang/ref/Reference.java b/src/java.base/share/classes/java/lang/ref/Reference.java
index d7eb5ea883e43..dc1ff6e643f3a 100644
--- a/src/java.base/share/classes/java/lang/ref/Reference.java
+++ b/src/java.base/share/classes/java/lang/ref/Reference.java
@@ -353,6 +353,8 @@ public T get() {
* null, and would subsequently not finalize the referent/finalizee.
*/
T getInactive() {
+ assert this instanceof FinalReference;
+ assert next == this; // I.e. FinalReference is inactive
return this.referent;
}
diff --git a/src/java.base/share/classes/java/lang/reflect/Constructor.java b/src/java.base/share/classes/java/lang/reflect/Constructor.java
index 427321e17f8cc..ed8c9c59f4e0d 100644
--- a/src/java.base/share/classes/java/lang/reflect/Constructor.java
+++ b/src/java.base/share/classes/java/lang/reflect/Constructor.java
@@ -662,7 +662,7 @@ public AnnotatedType getAnnotatedReceiverType() {
getConstantPool(thisDeclClass),
this,
thisDeclClass,
- enclosingClass,
+ resolveToOwnerType(enclosingClass),
TypeAnnotation.TypeAnnotationTarget.METHOD_RECEIVER);
}
}
diff --git a/src/java.base/share/classes/java/lang/reflect/Executable.java b/src/java.base/share/classes/java/lang/reflect/Executable.java
index 2b223c5ce6b37..2d51111d8a5e0 100644
--- a/src/java.base/share/classes/java/lang/reflect/Executable.java
+++ b/src/java.base/share/classes/java/lang/reflect/Executable.java
@@ -38,6 +38,7 @@
import sun.reflect.annotation.AnnotationSupport;
import sun.reflect.annotation.TypeAnnotationParser;
import sun.reflect.annotation.TypeAnnotation;
+import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl;
import sun.reflect.generics.repository.ConstructorRepository;
/**
@@ -698,7 +699,7 @@ public AnnotatedType getAnnotatedReceiverType() {
getConstantPool(getDeclaringClass()),
this,
getDeclaringClass(),
- getDeclaringClass(),
+ resolveToOwnerType(getDeclaringClass()),
TypeAnnotation.TypeAnnotationTarget.METHOD_RECEIVER);
}
@@ -753,4 +754,23 @@ public AnnotatedType[] getAnnotatedExceptionTypes() {
TypeAnnotation.TypeAnnotationTarget.THROWS);
}
+ static Type resolveToOwnerType(Class> c) {
+ TypeVariable>[] v = c.getTypeParameters();
+ Type o = resolveOwner(c);
+ Type t;
+ if (o != null || v.length > 0) {
+ t = ParameterizedTypeImpl.make(c, v, o);
+ } else {
+ t = c;
+ }
+ return t;
+ }
+
+ private static Type resolveOwner(Class> t) {
+ if (Modifier.isStatic(t.getModifiers()) || !(t.isLocalClass() || t.isMemberClass() || t.isAnonymousClass())) {
+ return null;
+ }
+ Class> d = t.getDeclaringClass();
+ return ParameterizedTypeImpl.make(d, d.getTypeParameters(), resolveOwner(d));
+ }
}
diff --git a/src/java.base/share/classes/java/net/doc-files/net-properties.html b/src/java.base/share/classes/java/net/doc-files/net-properties.html
index ccea98b9ff456..8bd0fe7316d10 100644
--- a/src/java.base/share/classes/java/net/doc-files/net-properties.html
+++ b/src/java.base/share/classes/java/net/doc-files/net-properties.html
@@ -30,7 +30,8 @@
Networking Properties
-There are a few standard system properties used to
+
+There are a few standard system properties used to
alter the mechanisms and behavior of the various classes of the
java.net package. Some are checked only once at startup of the VM,
and therefore are best set using the -D option of the java command,
@@ -38,7 +39,8 @@
Networking Properties
the System.setProperty() API.
The purpose of this document is to list
and detail all of these properties.
-If there is no special note, a property value is checked every time it is used.
+
+If there is no special note, a property value is checked every time it is used.
IPv4 / IPv6
@@ -240,5 +242,57 @@ Address Cache
Since these 2 properties are part of the security policy, they are
not set by either the -D option or the {@code System.setProperty()} API,
instead they are set as security properties.
+
+Unix domain sockets
+
+Calling {@link java.nio.channels.ServerSocketChannel#bind(SocketAddress,int) ServerSocketChannel.bind}
+with a {@code null} address parameter will bind to an automatically assigned socket address.
+For Unix domain sockets, this means a unique path in some predefined system temporary directory.
+There are a number of system (and networking) properties that affect this behavior.
+
+Unix domain socket addresses are limited in length to approximately 100
+bytes (depending on the platform), it is important to ensure that the temporary directory's name
+together with the filename used for the socket (currently a name similar to
+{@code socket_1679697142}) does not exceed this limit. The following properties
+can be used to control the selection of this directory:
+
+
+ {@systemProperty jdk.net.unixdomain.tmpdir} This can be set as
+ a networking property in {@code conf/net.properties} If set, this specifies the
+ directory to use for automatically bound server socket addresses. On some platforms,
+ (eg some Unix systems) this will have a predefined default value. On others,
+ (eg Windows) there is no default value. Either way, it is always possible
+ to override the networking property with a system property of the same name
+ set on the command line. If neither of the networking nor system property
+ are set, then some systems (eg Windows) may check a commonly used environment
+ variable as temporary directory.
+
{@systemProperty java.io.tmpdir} If the previous step fails to locate
+ a directory to use, then the directory identified by the system property
+ {@code java.io.tmpdir} is used.
+
+More information about the platform specific behavior can be seen in the
+{@code conf/net.properties} configuration file.
+
+Implicit binding of a {@link java.nio.channels.SocketChannel SocketChannel}
+
+If a client socket is connected to a remote destination without calling {@code bind} first,
+then the socket is implicitly bound. In this case, Unix domain sockets
+are unnamed (ie. their path is empty). This behavior is not affected by any
+system or networking properties.
+
+
+
Enhanced exception messages
+By default, for security reasons, exception messages do not include potentially sensitive
+security information such as hostnames or Unix domain socket address paths.
+The following property can be used to relax this restriction, for debugging and other
+purposes.
+
+ {@systemProperty jdk.includeInExceptions} This is typically set to
+ a comma separated list of keywords that refer to exception types whose messages
+ may be enhanced with more detailed information. If the value includes the string
+ {@code hostInfo} then socket addresses will be included in exception message
+ texts (eg hostnames, Unix domain socket address paths).
+
+