Skip to content

Commit 6a294fe

Browse files
committed
Pull/merge in changes for JDK-8255883
1 parent 4171e7f commit 6a294fe

File tree

2 files changed

+46
-20
lines changed

2 files changed

+46
-20
lines changed

src/java.base/share/classes/jdk/internal/reflect/NativeConstructorAccessorImpl.java

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,14 @@
3434
afterward, switches to bytecode-based implementation */
3535

3636
class NativeConstructorAccessorImpl extends ConstructorAccessorImpl {
37+
private static final Unsafe U = Unsafe.getUnsafe();
38+
private static final long GENERATED_OFFSET
39+
= U.objectFieldOffset(NativeConstructorAccessorImpl.class, "generated");
40+
3741
private final Constructor<?> c;
3842
private DelegatingConstructorAccessorImpl parent;
3943
private int numInvocations;
44+
private volatile int generated;
4045

4146
NativeConstructorAccessorImpl(Constructor<?> c) {
4247
this.c = c;
@@ -50,15 +55,24 @@ public Object newInstance(Object[] args)
5055
// We can't inflate a constructor belonging to a vm-anonymous class
5156
// because that kind of class can't be referred to by name, hence can't
5257
// be found from the generated bytecode.
53-
if ((++numInvocations > ReflectionFactory.inflationThreshold()
54-
|| Thread.currentThread().isVirtual())
55-
&& !c.getDeclaringClass().isHidden()
56-
&& !ReflectUtil.isVMAnonymousClass(c.getDeclaringClass())) {
58+
if (!c.getDeclaringClass().isHidden()
59+
&& !ReflectUtil.isVMAnonymousClass(c.getDeclaringClass())
60+
&& (Thread.currentThread().isVirtual()
61+
|| ((++numInvocations > ReflectionFactory.inflationThreshold()
62+
&& (generated == 0)
63+
&& U.compareAndSetInt(this, GENERATED_OFFSET, 0, 1))))) {
5764

5865
// class initializer may not have run
5966
Unsafe.getUnsafe().ensureClassInitialized(c.getDeclaringClass());
6067

61-
ConstructorAccessorImpl acc = NewAccessorImplFactory.newConstructorAccessorImpl(c);
68+
ConstructorAccessorImpl acc;
69+
try {
70+
acc = NewAccessorImplFactory.newConstructorAccessorImpl(c);
71+
} catch (Throwable t) {
72+
// newConstructorAccessorImpl failed, restore generated to 0
73+
generated = 0;
74+
throw t;
75+
}
6276

6377
parent.setDelegate(acc);
6478
return acc.newInstance(args);

src/java.base/share/classes/jdk/internal/reflect/NativeMethodAccessorImpl.java

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,14 @@
3434
switches to bytecode-based implementation */
3535

3636
class NativeMethodAccessorImpl extends MethodAccessorImpl {
37+
private static final Unsafe U = Unsafe.getUnsafe();
38+
private static final long GENERATED_OFFSET
39+
= U.objectFieldOffset(NativeMethodAccessorImpl.class, "generated");
40+
3741
private final Method method;
3842
private DelegatingMethodAccessorImpl parent;
3943
private int numInvocations;
44+
private volatile int generated;
4045

4146
NativeMethodAccessorImpl(Method method) {
4247
this.method = method;
@@ -48,27 +53,34 @@ public Object invoke(Object obj, Object[] args)
4853
// We can't inflate methods belonging to vm-anonymous classes because
4954
// that kind of class can't be referred to by name, hence can't be
5055
// found from the generated bytecode.
51-
if ((++numInvocations > ReflectionFactory.inflationThreshold()
52-
|| Thread.currentThread().isVirtual())
53-
&& !method.getDeclaringClass().isHidden()
54-
&& !ReflectUtil.isVMAnonymousClass(method.getDeclaringClass())) {
56+
if (!method.getDeclaringClass().isHidden()
57+
&& !ReflectUtil.isVMAnonymousClass(method.getDeclaringClass())
58+
&& (Thread.currentThread().isVirtual()
59+
|| (++numInvocations > ReflectionFactory.inflationThreshold()
60+
&& (generated == 0)
61+
&& U.compareAndSetInt(this, GENERATED_OFFSET, 0, 1)))) {
5562

5663
// class initializer may not have run
5764
Unsafe.getUnsafe().ensureClassInitialized(method.getDeclaringClass());
5865

5966
MethodAccessorImpl acc;
60-
if (Reflection.isCallerSensitive(method)) {
67+
try {
6168
// use bytecode generated implementation for @CS methods for now
62-
acc = (MethodAccessorImpl)
63-
new MethodAccessorGenerator().
64-
generateMethod(method.getDeclaringClass(),
65-
method.getName(),
66-
method.getParameterTypes(),
67-
method.getReturnType(),
68-
method.getExceptionTypes(),
69-
method.getModifiers());
70-
} else {
71-
acc = NewAccessorImplFactory.newMethodAccessorImpl(method);
69+
if (Reflection.isCallerSensitive(method)) {
70+
acc = (MethodAccessorImpl) new MethodAccessorGenerator()
71+
.generateMethod(method.getDeclaringClass(),
72+
method.getName(),
73+
method.getParameterTypes(),
74+
method.getReturnType(),
75+
method.getExceptionTypes(),
76+
method.getModifiers());
77+
} else {
78+
acc = NewAccessorImplFactory.newMethodAccessorImpl(method);
79+
}
80+
} catch (Throwable t) {
81+
// generateMethod/newMethodAccessorImpl failed, restore generated to 0
82+
generated = 0;
83+
throw t;
7284
}
7385

7486
parent.setDelegate(acc);

0 commit comments

Comments
 (0)