Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,12 @@
package jdk.vm.ci.hotspot;

import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.annotation.AbstractAnnotated;

/**
* Common base class for all HotSpot {@link JavaType} implementations.
*/
public abstract class HotSpotJavaType implements JavaType {
public abstract class HotSpotJavaType extends AbstractAnnotated implements JavaType {

private final String name;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,18 @@
*/
package jdk.vm.ci.hotspot;

import static java.util.FormattableFlags.ALTERNATE;
import static java.util.FormattableFlags.LEFT_JUSTIFY;
import static java.util.FormattableFlags.UPPERCASE;
import jdk.vm.ci.meta.JavaMethod;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.annotation.AbstractAnnotated;

import java.util.Formattable;
import java.util.Formatter;

import jdk.vm.ci.meta.JavaMethod;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import static java.util.FormattableFlags.ALTERNATE;
import static java.util.FormattableFlags.LEFT_JUSTIFY;
import static java.util.FormattableFlags.UPPERCASE;

abstract class HotSpotMethod implements JavaMethod, Formattable {
abstract class HotSpotMethod extends AbstractAnnotated implements JavaMethod, Formattable {

public static String applyFormattingFlagsAndWidth(String s, int flags, int width) {
if (flags == 0 && width < 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.ResolvedJavaType;
import jdk.vm.ci.meta.UnresolvedJavaType;
import jdk.vm.ci.meta.annotation.AbstractAnnotated;
import jdk.vm.ci.meta.annotation.AnnotationsInfo;

import java.lang.annotation.Annotation;
Expand All @@ -39,7 +40,7 @@
/**
* Represents a field in a HotSpot type.
*/
class HotSpotResolvedJavaFieldImpl implements HotSpotResolvedJavaField {
class HotSpotResolvedJavaFieldImpl extends AbstractAnnotated implements HotSpotResolvedJavaField {

private final HotSpotResolvedObjectTypeImpl holder;
private JavaType type;
Expand Down Expand Up @@ -191,7 +192,7 @@ private boolean hasAnnotations(boolean typeAnnotations) {
HotSpotVMConfig config = config();
final long metaspaceAnnotations = UNSAFE.getAddress(holder.getKlassPointer() + config.instanceKlassAnnotationsOffset);
if (metaspaceAnnotations != 0) {
int annotationsOffset = typeAnnotations? config.annotationsFieldTypeAnnotationsOffset: config.annotationsFieldAnnotationsOffset;
int annotationsOffset = typeAnnotations ? config.annotationsFieldTypeAnnotationsOffset : config.annotationsFieldAnnotationsOffset;
long fieldsAnnotations = UNSAFE.getAddress(metaspaceAnnotations + annotationsOffset);
if (fieldsAnnotations != 0) {
int indexOffset = ADDRESS_SIZE * index;
Expand Down Expand Up @@ -233,7 +234,7 @@ public JavaConstant getConstantValue() {
}

@Override
public AnnotationsInfo getDeclaredAnnotationInfo() {
public AnnotationsInfo getRawDeclaredAnnotationInfo() {
if (!hasAnnotations(false)) {
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -779,7 +779,7 @@ public BitSet getOopMapAt(int bci) {
}

@Override
public AnnotationsInfo getDeclaredAnnotationInfo() {
public AnnotationsInfo getRawDeclaredAnnotationInfo() {
if (!hasAnnotations(config().constMethodHasMethodAnnotations)) {
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,19 @@
package jdk.vm.ci.hotspot;

import jdk.vm.ci.meta.JavaType;
import java.lang.reflect.RecordComponent;

import jdk.vm.ci.meta.ResolvedJavaRecordComponent;
import jdk.vm.ci.meta.annotation.AbstractAnnotated;
import jdk.vm.ci.meta.annotation.AnnotationsInfo;

import java.lang.reflect.RecordComponent;

import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM;
import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime;

/**
* Represents a {@linkplain RecordComponent component} in a HotSpot record.
*/
final class HotSpotResolvedJavaRecordComponent implements ResolvedJavaRecordComponent {
final class HotSpotResolvedJavaRecordComponent extends AbstractAnnotated implements ResolvedJavaRecordComponent {

private final HotSpotResolvedObjectTypeImpl declaringRecord;
private final String name;
Expand Down Expand Up @@ -76,6 +77,7 @@ public String toString() {
public JavaType getType() {
return type;
}

@Override
public boolean equals(Object obj) {
if (obj instanceof HotSpotResolvedJavaRecordComponent that) {
Expand All @@ -90,7 +92,7 @@ public int hashCode() {
}

@Override
public AnnotationsInfo getDeclaredAnnotationInfo() {
public AnnotationsInfo getRawDeclaredAnnotationInfo() {
byte[] bytes = compilerToVM().getRawAnnotationBytes('r', declaringRecord, declaringRecord.getKlassPointer(), index, CompilerToVM.DECLARED_ANNOTATIONS);
return AnnotationsInfo.make(bytes, getDeclaringRecord().getConstantPool(), getDeclaringRecord());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,25 +22,6 @@
*/
package jdk.vm.ci.hotspot;

import static java.util.Objects.requireNonNull;
import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM;
import static jdk.vm.ci.hotspot.HotSpotConstantPool.isSignaturePolymorphicHolder;
import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime;
import static jdk.vm.ci.hotspot.HotSpotModifiers.jvmClassModifiers;
import static jdk.vm.ci.hotspot.HotSpotVMConfig.config;
import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.nio.ByteOrder;
import java.util.Arrays;
import java.util.Collections;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import jdk.vm.ci.common.JVMCIError;
import jdk.vm.ci.meta.Assumptions.AssumptionResult;
import jdk.vm.ci.meta.Assumptions.ConcreteMethod;
Expand All @@ -60,6 +41,25 @@
import jdk.vm.ci.meta.UnresolvedJavaType;
import jdk.vm.ci.meta.annotation.AnnotationsInfo;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static java.util.Objects.requireNonNull;
import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM;
import static jdk.vm.ci.hotspot.HotSpotConstantPool.isSignaturePolymorphicHolder;
import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime;
import static jdk.vm.ci.hotspot.HotSpotModifiers.jvmClassModifiers;
import static jdk.vm.ci.hotspot.HotSpotVMConfig.config;
import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE;

/**
* Implementation of {@link JavaType} for resolved non-primitive HotSpot classes. This class is not
* an {@link MetaspaceHandleObject} because it doesn't have to be scanned for GC. Its liveness is
Expand Down Expand Up @@ -807,18 +807,18 @@ HotSpotResolvedJavaField lookupField(Field reflectionField) {
* @param internalFlags field's internal flags (from the VM)
* @param initializerIndex field's initial value index in the constant pool
*/
record FieldInfo(int nameIndex,
int signatureIndex,
int offset,
int classfileFlags,
int internalFlags,
int initializerIndex) {

record Key(String name, String signature, boolean isStatic) {
static Key from(FieldInfo fi, HotSpotResolvedObjectTypeImpl holder) {
return new FieldInfo.Key(fi.getName(holder), fi.getSignature(holder), fi.isStatic());
}
}
record FieldInfo(int nameIndex,
int signatureIndex,
int offset,
int classfileFlags,
int internalFlags,
int initializerIndex) {

record Key(String name, String signature, boolean isStatic) {
static Key from(FieldInfo fi, HotSpotResolvedObjectTypeImpl holder) {
return new FieldInfo.Key(fi.getName(holder), fi.getSignature(holder), fi.isStatic());
}
}

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

@Override
public AnnotationsInfo getDeclaredAnnotationInfo() {
public AnnotationsInfo getRawDeclaredAnnotationInfo() {
if (!hasDirectAnnotations(false)) {
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import jdk.vm.ci.meta.ResolvedJavaRecordComponent;
import jdk.vm.ci.meta.ResolvedJavaType;
import jdk.vm.ci.meta.UnresolvedJavaType;
import jdk.vm.ci.meta.annotation.AnnotationsInfo;

import java.lang.annotation.Annotation;
import java.lang.reflect.Modifier;
Expand Down Expand Up @@ -268,6 +269,16 @@ public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
return null;
}

@Override
public AnnotationsInfo getTypeAnnotationInfo() {
return null;
}

@Override
public AnnotationsInfo getRawDeclaredAnnotationInfo() {
return null;
}

@Override
public ResolvedJavaType resolve(ResolvedJavaType accessingClass) {
requireNonNull(accessingClass);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,22 +32,22 @@ public interface ResolvedJavaRecordComponent extends Annotated {
/**
* Gets the {@link ResolvedJavaType} object representing the class which declares this record component.
*/
ResolvedJavaType getDeclaringRecord();
ResolvedJavaType getDeclaringRecord();

/**
* Gets a {@code ResolvedJavaMethod} that represents the accessor for this record
* component.
*/
default ResolvedJavaMethod getAccessor() {
for (ResolvedJavaMethod method : getDeclaringRecord().getDeclaredMethods(false)) {
if (method.getName().equals(getName()) &&
method.getSignature().getParameterCount(false) == 0 &&
method.getSignature().getReturnType(null).getName().equals(getType().getName())) {
return method;
}
}
return null;
}
default ResolvedJavaMethod getAccessor() {
for (ResolvedJavaMethod method : getDeclaringRecord().getDeclaredMethods(false)) {
if (method.getName().equals(getName()) &&
method.getSignature().getParameterCount(false) == 0 &&
method.getSignature().getReturnType(null).getName().equals(getType().getName())) {
return method;
}
}
return null;
}

/**
* Returns the name of this record component.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* Copyright (c) 2025, 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.
*/
package jdk.vm.ci.meta.annotation;

import java.util.function.Function;

/**
* A partial implementation of the {@link Annotated} interface, providing
* the caching mechanism for parsed declared annotation information.
* <p>
* This class maintains a single-entry cache for the result of parsing
* the declared annotation information, allowing for efficient reuse of
* the parsed data when the same parser function is applied multiple times.
* <p>
* Subclasses must provide an implementation for the {@link #getRawDeclaredAnnotationInfo}
* method, which returns the raw annotation information.
*/
public abstract class AbstractAnnotated implements Annotated {

/**
* Record used for entry in {@link #parsedDeclaredAnnotationsCache}.
*/
private record ParsedDeclaredAnnotationsCacheEntry<R>(Function<AnnotationsInfo, R> parser, R result) {
}

/**
* Single-entry cache for the result of parsing {@link #getDeclaredAnnotationInfo}.
*/
private volatile ParsedDeclaredAnnotationsCacheEntry<?> parsedDeclaredAnnotationsCache;

@SuppressWarnings("unchecked")
@Override
public <T> T getDeclaredAnnotationInfo(Function<AnnotationsInfo, T> parser) {
if (parser == null) {
return (T) getRawDeclaredAnnotationInfo();
}
ParsedDeclaredAnnotationsCacheEntry<?> cache = parsedDeclaredAnnotationsCache;
if (cache == null || !parser.equals(cache.parser)) {
AnnotationsInfo info = getRawDeclaredAnnotationInfo();
cache = new ParsedDeclaredAnnotationsCacheEntry<>(parser, parser.apply(info));
parsedDeclaredAnnotationsCache = cache;
}
return (T) cache.result;
}

/**
* Gets the unparsed class file info for the annotations directly present on this element.
*/
public abstract AnnotationsInfo getRawDeclaredAnnotationInfo();
}
Loading
Loading