Skip to content

Commit ff1285c

Browse files
committed
added caching to semantics to Annotated#getDeclaredAnnotationInfo and removed default implementations from all Annotated methods
1 parent 55da5e6 commit ff1285c

File tree

14 files changed

+175
-72
lines changed

14 files changed

+175
-72
lines changed

src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotJavaType.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,12 @@
2323
package jdk.vm.ci.hotspot;
2424

2525
import jdk.vm.ci.meta.JavaType;
26+
import jdk.vm.ci.meta.annotation.AbstractAnnotated;
2627

2728
/**
2829
* Common base class for all HotSpot {@link JavaType} implementations.
2930
*/
30-
public abstract class HotSpotJavaType implements JavaType {
31+
public abstract class HotSpotJavaType extends AbstractAnnotated implements JavaType {
3132

3233
private final String name;
3334

src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotMethod.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,18 @@
2222
*/
2323
package jdk.vm.ci.hotspot;
2424

25-
import static java.util.FormattableFlags.ALTERNATE;
26-
import static java.util.FormattableFlags.LEFT_JUSTIFY;
27-
import static java.util.FormattableFlags.UPPERCASE;
25+
import jdk.vm.ci.meta.JavaMethod;
26+
import jdk.vm.ci.meta.ResolvedJavaMethod;
27+
import jdk.vm.ci.meta.annotation.AbstractAnnotated;
2828

2929
import java.util.Formattable;
3030
import java.util.Formatter;
3131

32-
import jdk.vm.ci.meta.JavaMethod;
33-
import jdk.vm.ci.meta.ResolvedJavaMethod;
32+
import static java.util.FormattableFlags.ALTERNATE;
33+
import static java.util.FormattableFlags.LEFT_JUSTIFY;
34+
import static java.util.FormattableFlags.UPPERCASE;
3435

35-
abstract class HotSpotMethod implements JavaMethod, Formattable {
36+
abstract class HotSpotMethod extends AbstractAnnotated implements JavaMethod, Formattable {
3637

3738
public static String applyFormattingFlagsAndWidth(String s, int flags, int width) {
3839
if (flags == 0 && width < 0) {

src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedJavaFieldImpl.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import jdk.vm.ci.meta.JavaType;
2727
import jdk.vm.ci.meta.ResolvedJavaType;
2828
import jdk.vm.ci.meta.UnresolvedJavaType;
29+
import jdk.vm.ci.meta.annotation.AbstractAnnotated;
2930
import jdk.vm.ci.meta.annotation.AnnotationsInfo;
3031

3132
import java.lang.annotation.Annotation;
@@ -39,7 +40,7 @@
3940
/**
4041
* Represents a field in a HotSpot type.
4142
*/
42-
class HotSpotResolvedJavaFieldImpl implements HotSpotResolvedJavaField {
43+
class HotSpotResolvedJavaFieldImpl extends AbstractAnnotated implements HotSpotResolvedJavaField {
4344

4445
private final HotSpotResolvedObjectTypeImpl holder;
4546
private JavaType type;
@@ -191,7 +192,7 @@ private boolean hasAnnotations(boolean typeAnnotations) {
191192
HotSpotVMConfig config = config();
192193
final long metaspaceAnnotations = UNSAFE.getAddress(holder.getKlassPointer() + config.instanceKlassAnnotationsOffset);
193194
if (metaspaceAnnotations != 0) {
194-
int annotationsOffset = typeAnnotations? config.annotationsFieldTypeAnnotationsOffset: config.annotationsFieldAnnotationsOffset;
195+
int annotationsOffset = typeAnnotations ? config.annotationsFieldTypeAnnotationsOffset : config.annotationsFieldAnnotationsOffset;
195196
long fieldsAnnotations = UNSAFE.getAddress(metaspaceAnnotations + annotationsOffset);
196197
if (fieldsAnnotations != 0) {
197198
int indexOffset = ADDRESS_SIZE * index;
@@ -233,7 +234,7 @@ public JavaConstant getConstantValue() {
233234
}
234235

235236
@Override
236-
public AnnotationsInfo getDeclaredAnnotationInfo() {
237+
public AnnotationsInfo getRawDeclaredAnnotationInfo() {
237238
if (!hasAnnotations(false)) {
238239
return null;
239240
}

src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -779,7 +779,7 @@ public BitSet getOopMapAt(int bci) {
779779
}
780780

781781
@Override
782-
public AnnotationsInfo getDeclaredAnnotationInfo() {
782+
public AnnotationsInfo getRawDeclaredAnnotationInfo() {
783783
if (!hasAnnotations(config().constMethodHasMethodAnnotations)) {
784784
return null;
785785
}

src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedJavaRecordComponent.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,19 @@
2323
package jdk.vm.ci.hotspot;
2424

2525
import jdk.vm.ci.meta.JavaType;
26-
import java.lang.reflect.RecordComponent;
27-
2826
import jdk.vm.ci.meta.ResolvedJavaRecordComponent;
27+
import jdk.vm.ci.meta.annotation.AbstractAnnotated;
2928
import jdk.vm.ci.meta.annotation.AnnotationsInfo;
3029

30+
import java.lang.reflect.RecordComponent;
31+
3132
import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM;
3233
import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime;
3334

3435
/**
3536
* Represents a {@linkplain RecordComponent component} in a HotSpot record.
3637
*/
37-
final class HotSpotResolvedJavaRecordComponent implements ResolvedJavaRecordComponent {
38+
final class HotSpotResolvedJavaRecordComponent extends AbstractAnnotated implements ResolvedJavaRecordComponent {
3839

3940
private final HotSpotResolvedObjectTypeImpl declaringRecord;
4041
private final String name;
@@ -76,6 +77,7 @@ public String toString() {
7677
public JavaType getType() {
7778
return type;
7879
}
80+
7981
@Override
8082
public boolean equals(Object obj) {
8183
if (obj instanceof HotSpotResolvedJavaRecordComponent that) {
@@ -90,7 +92,7 @@ public int hashCode() {
9092
}
9193

9294
@Override
93-
public AnnotationsInfo getDeclaredAnnotationInfo() {
95+
public AnnotationsInfo getRawDeclaredAnnotationInfo() {
9496
byte[] bytes = compilerToVM().getRawAnnotationBytes('r', declaringRecord, declaringRecord.getKlassPointer(), index, CompilerToVM.DECLARED_ANNOTATIONS);
9597
return AnnotationsInfo.make(bytes, getDeclaringRecord().getConstantPool(), getDeclaringRecord());
9698
}

src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -22,25 +22,6 @@
2222
*/
2323
package jdk.vm.ci.hotspot;
2424

25-
import static java.util.Objects.requireNonNull;
26-
import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM;
27-
import static jdk.vm.ci.hotspot.HotSpotConstantPool.isSignaturePolymorphicHolder;
28-
import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime;
29-
import static jdk.vm.ci.hotspot.HotSpotModifiers.jvmClassModifiers;
30-
import static jdk.vm.ci.hotspot.HotSpotVMConfig.config;
31-
import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE;
32-
33-
import java.lang.annotation.Annotation;
34-
import java.lang.reflect.Field;
35-
import java.lang.reflect.Modifier;
36-
import java.nio.ByteOrder;
37-
import java.util.Arrays;
38-
import java.util.Collections;
39-
import java.util.ArrayList;
40-
import java.util.HashMap;
41-
import java.util.List;
42-
import java.util.Map;
43-
4425
import jdk.vm.ci.common.JVMCIError;
4526
import jdk.vm.ci.meta.Assumptions.AssumptionResult;
4627
import jdk.vm.ci.meta.Assumptions.ConcreteMethod;
@@ -60,6 +41,25 @@
6041
import jdk.vm.ci.meta.UnresolvedJavaType;
6142
import jdk.vm.ci.meta.annotation.AnnotationsInfo;
6243

44+
import java.lang.annotation.Annotation;
45+
import java.lang.reflect.Field;
46+
import java.lang.reflect.Modifier;
47+
import java.nio.ByteOrder;
48+
import java.util.ArrayList;
49+
import java.util.Arrays;
50+
import java.util.Collections;
51+
import java.util.HashMap;
52+
import java.util.List;
53+
import java.util.Map;
54+
55+
import static java.util.Objects.requireNonNull;
56+
import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM;
57+
import static jdk.vm.ci.hotspot.HotSpotConstantPool.isSignaturePolymorphicHolder;
58+
import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime;
59+
import static jdk.vm.ci.hotspot.HotSpotModifiers.jvmClassModifiers;
60+
import static jdk.vm.ci.hotspot.HotSpotVMConfig.config;
61+
import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE;
62+
6363
/**
6464
* Implementation of {@link JavaType} for resolved non-primitive HotSpot classes. This class is not
6565
* an {@link MetaspaceHandleObject} because it doesn't have to be scanned for GC. Its liveness is
@@ -807,18 +807,18 @@ HotSpotResolvedJavaField lookupField(Field reflectionField) {
807807
* @param internalFlags field's internal flags (from the VM)
808808
* @param initializerIndex field's initial value index in the constant pool
809809
*/
810-
record FieldInfo(int nameIndex,
811-
int signatureIndex,
812-
int offset,
813-
int classfileFlags,
814-
int internalFlags,
815-
int initializerIndex) {
816-
817-
record Key(String name, String signature, boolean isStatic) {
818-
static Key from(FieldInfo fi, HotSpotResolvedObjectTypeImpl holder) {
819-
return new FieldInfo.Key(fi.getName(holder), fi.getSignature(holder), fi.isStatic());
820-
}
821-
}
810+
record FieldInfo(int nameIndex,
811+
int signatureIndex,
812+
int offset,
813+
int classfileFlags,
814+
int internalFlags,
815+
int initializerIndex) {
816+
817+
record Key(String name, String signature, boolean isStatic) {
818+
static Key from(FieldInfo fi, HotSpotResolvedObjectTypeImpl holder) {
819+
return new FieldInfo.Key(fi.getName(holder), fi.getSignature(holder), fi.isStatic());
820+
}
821+
}
822822

823823
/**
824824
* Returns the name of this field as a {@link String}. If the field is an internal field the
@@ -1014,7 +1014,7 @@ private boolean hasDirectAnnotations(boolean typeAnnotations) {
10141014
HotSpotVMConfig config = config();
10151015
final long metaspaceAnnotations = UNSAFE.getAddress(getKlassPointer() + config.instanceKlassAnnotationsOffset);
10161016
if (metaspaceAnnotations != 0) {
1017-
int annotationsOffset = typeAnnotations?config.annotationsClassTypeAnnotationsOffset: config.annotationsClassAnnotationsOffset;
1017+
int annotationsOffset = typeAnnotations ? config.annotationsClassTypeAnnotationsOffset : config.annotationsClassAnnotationsOffset;
10181018
long classAnnotations = UNSAFE.getAddress(metaspaceAnnotations + annotationsOffset);
10191019
return classAnnotations != 0;
10201020
}
@@ -1237,7 +1237,7 @@ public boolean isCloneableWithAllocation() {
12371237
}
12381238

12391239
@Override
1240-
public AnnotationsInfo getDeclaredAnnotationInfo() {
1240+
public AnnotationsInfo getRawDeclaredAnnotationInfo() {
12411241
if (!hasDirectAnnotations(false)) {
12421242
return null;
12431243
}

src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedPrimitiveType.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import jdk.vm.ci.meta.ResolvedJavaRecordComponent;
3333
import jdk.vm.ci.meta.ResolvedJavaType;
3434
import jdk.vm.ci.meta.UnresolvedJavaType;
35+
import jdk.vm.ci.meta.annotation.AnnotationsInfo;
3536

3637
import java.lang.annotation.Annotation;
3738
import java.lang.reflect.Modifier;
@@ -268,6 +269,16 @@ public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
268269
return null;
269270
}
270271

272+
@Override
273+
public AnnotationsInfo getTypeAnnotationInfo() {
274+
return null;
275+
}
276+
277+
@Override
278+
public AnnotationsInfo getRawDeclaredAnnotationInfo() {
279+
return null;
280+
}
281+
271282
@Override
272283
public ResolvedJavaType resolve(ResolvedJavaType accessingClass) {
273284
requireNonNull(accessingClass);

src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ResolvedJavaRecordComponent.java

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,22 +32,22 @@ public interface ResolvedJavaRecordComponent extends Annotated {
3232
/**
3333
* Gets the {@link ResolvedJavaType} object representing the class which declares this record component.
3434
*/
35-
ResolvedJavaType getDeclaringRecord();
35+
ResolvedJavaType getDeclaringRecord();
3636

3737
/**
3838
* Gets a {@code ResolvedJavaMethod} that represents the accessor for this record
3939
* component.
4040
*/
41-
default ResolvedJavaMethod getAccessor() {
42-
for (ResolvedJavaMethod method : getDeclaringRecord().getDeclaredMethods(false)) {
43-
if (method.getName().equals(getName()) &&
44-
method.getSignature().getParameterCount(false) == 0 &&
45-
method.getSignature().getReturnType(null).getName().equals(getType().getName())) {
46-
return method;
47-
}
48-
}
49-
return null;
50-
}
41+
default ResolvedJavaMethod getAccessor() {
42+
for (ResolvedJavaMethod method : getDeclaringRecord().getDeclaredMethods(false)) {
43+
if (method.getName().equals(getName()) &&
44+
method.getSignature().getParameterCount(false) == 0 &&
45+
method.getSignature().getReturnType(null).getName().equals(getType().getName())) {
46+
return method;
47+
}
48+
}
49+
return null;
50+
}
5151

5252
/**
5353
* Returns the name of this record component.
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/*
2+
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
package jdk.vm.ci.meta.annotation;
24+
25+
import java.util.function.Function;
26+
27+
/**
28+
* A partial implementation of the {@link Annotated} interface, providing
29+
* the caching mechanism for parsed declared annotation information.
30+
* <p>
31+
* This class maintains a single-entry cache for the result of parsing
32+
* the declared annotation information, allowing for efficient reuse of
33+
* the parsed data when the same parser function is applied multiple times.
34+
* <p>
35+
* Subclasses must provide an implementation for the {@link #getRawDeclaredAnnotationInfo}
36+
* method, which returns the raw annotation information.
37+
*/
38+
public abstract class AbstractAnnotated implements Annotated {
39+
40+
/**
41+
* Record used for entry in {@link #parsedDeclaredAnnotationsCache}.
42+
*/
43+
private record ParsedDeclaredAnnotationsCacheEntry<R>(Function<AnnotationsInfo, R> parser, R result) {
44+
}
45+
46+
/**
47+
* Single-entry cache for the result of parsing {@link #getDeclaredAnnotationInfo}.
48+
*/
49+
private volatile ParsedDeclaredAnnotationsCacheEntry<?> parsedDeclaredAnnotationsCache;
50+
51+
@SuppressWarnings("unchecked")
52+
@Override
53+
public <T> T getDeclaredAnnotationInfo(Function<AnnotationsInfo, T> parser) {
54+
if (parser == null) {
55+
return (T) getRawDeclaredAnnotationInfo();
56+
}
57+
ParsedDeclaredAnnotationsCacheEntry<?> cache = parsedDeclaredAnnotationsCache;
58+
if (cache == null || !parser.equals(cache.parser)) {
59+
AnnotationsInfo info = getRawDeclaredAnnotationInfo();
60+
cache = new ParsedDeclaredAnnotationsCacheEntry<>(parser, parser.apply(info));
61+
parsedDeclaredAnnotationsCache = cache;
62+
}
63+
return (T) cache.result;
64+
}
65+
66+
/**
67+
* Gets the unparsed class file info for the annotations directly present on this element.
68+
*/
69+
public abstract AnnotationsInfo getRawDeclaredAnnotationInfo();
70+
}

0 commit comments

Comments
 (0)