mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 23:04:50 +02:00
8273000: Remove WeakReference-based class initialisation barrier implementation
Reviewed-by: psandoz, mchung
This commit is contained in:
parent
21012f2bbe
commit
faa942c8ba
2 changed files with 15 additions and 38 deletions
|
@ -33,7 +33,6 @@ import sun.invoke.util.VerifyAccess;
|
||||||
import sun.invoke.util.VerifyType;
|
import sun.invoke.util.VerifyType;
|
||||||
import sun.invoke.util.Wrapper;
|
import sun.invoke.util.Wrapper;
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
@ -363,27 +362,12 @@ class DirectMethodHandle extends MethodHandle {
|
||||||
VerifyAccess.isSamePackage(ValueConversions.class, cls)) {
|
VerifyAccess.isSamePackage(ValueConversions.class, cls)) {
|
||||||
// It is a system class. It is probably in the process of
|
// It is a system class. It is probably in the process of
|
||||||
// being initialized, but we will help it along just to be safe.
|
// being initialized, but we will help it along just to be safe.
|
||||||
if (UNSAFE.shouldBeInitialized(cls)) {
|
|
||||||
UNSAFE.ensureClassInitialized(cls);
|
UNSAFE.ensureClassInitialized(cls);
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return UNSAFE.shouldBeInitialized(cls);
|
return UNSAFE.shouldBeInitialized(cls);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class EnsureInitialized extends ClassValue<WeakReference<Thread>> {
|
|
||||||
@Override
|
|
||||||
protected WeakReference<Thread> computeValue(Class<?> type) {
|
|
||||||
UNSAFE.ensureClassInitialized(type);
|
|
||||||
if (UNSAFE.shouldBeInitialized(type))
|
|
||||||
// If the previous call didn't block, this can happen.
|
|
||||||
// We are executing inside <clinit>.
|
|
||||||
return new WeakReference<>(Thread.currentThread());
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
static final EnsureInitialized INSTANCE = new EnsureInitialized();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ensureInitialized() {
|
private void ensureInitialized() {
|
||||||
if (checkInitialized(member)) {
|
if (checkInitialized(member)) {
|
||||||
// The coast is clear. Delete the <clinit> barrier.
|
// The coast is clear. Delete the <clinit> barrier.
|
||||||
|
@ -397,24 +381,12 @@ class DirectMethodHandle extends MethodHandle {
|
||||||
}
|
}
|
||||||
private static boolean checkInitialized(MemberName member) {
|
private static boolean checkInitialized(MemberName member) {
|
||||||
Class<?> defc = member.getDeclaringClass();
|
Class<?> defc = member.getDeclaringClass();
|
||||||
WeakReference<Thread> ref = EnsureInitialized.INSTANCE.get(defc);
|
|
||||||
if (ref == null) {
|
|
||||||
return true; // the final state
|
|
||||||
}
|
|
||||||
// Somebody may still be running defc.<clinit>.
|
|
||||||
if (ref.refersTo(Thread.currentThread())) {
|
|
||||||
// If anybody is running defc.<clinit>, it is this thread.
|
|
||||||
if (UNSAFE.shouldBeInitialized(defc))
|
|
||||||
// Yes, we are running it; keep the barrier for now.
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
// We are in a random thread. Block.
|
|
||||||
UNSAFE.ensureClassInitialized(defc);
|
UNSAFE.ensureClassInitialized(defc);
|
||||||
}
|
// Once we get here either defc was fully initialized by another thread, or
|
||||||
assert(!UNSAFE.shouldBeInitialized(defc));
|
// defc was already being initialized by the current thread. In the latter case
|
||||||
// put it into the final state
|
// the barrier must remain. We can detect this simply by checking if initialization
|
||||||
EnsureInitialized.INSTANCE.remove(defc);
|
// is still needed.
|
||||||
return true;
|
return !UNSAFE.shouldBeInitialized(defc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*non-public*/
|
/*non-public*/
|
||||||
|
|
|
@ -1143,9 +1143,14 @@ public final class Unsafe {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ensures the given class has been initialized. This is often
|
* Ensures the given class has been initialized (see JVMS-5.5 for details).
|
||||||
* needed in conjunction with obtaining the static field base of a
|
* This is often needed in conjunction with obtaining the static field base
|
||||||
* class.
|
* of a class.
|
||||||
|
*
|
||||||
|
* The call returns when either class {@code c} is fully initialized or
|
||||||
|
* class {@code c} is being initialized and the call is performed from
|
||||||
|
* the initializing thread. In the latter case a subsequent call to
|
||||||
|
* {@link #shouldBeInitialized} will return {@code true}.
|
||||||
*/
|
*/
|
||||||
public void ensureClassInitialized(Class<?> c) {
|
public void ensureClassInitialized(Class<?> c) {
|
||||||
if (c == null) {
|
if (c == null) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue