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 @@ -238,13 +238,10 @@ public boolean initialize() {
Heap.getHeap().walkImageHeapObjects(computeHubDataVisitor);
Metaspace.singleton().walkObjects(computeHubDataVisitor);

/*
* Classes that are loaded at runtime don't have any declared fields at the moment. This
* needs to be changed once GR-60069 is merged.
*/
for (int i = TypeIDs.singleton().getFirstRuntimeTypeId(); i < classInfoCount; i++) {
ClassInfo classInfo = getClassInfo(i);
if (ClassInfoAccess.isValid(classInfo)) {
/* GR-69330 */
classInfo.setStaticFieldCount(0);
classInfo.setInstanceFieldCount(0);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@

import com.oracle.svm.configure.ClassNameSupport;
import com.oracle.svm.configure.config.SignatureUtil;

import com.oracle.svm.core.AlwaysInline;
import com.oracle.svm.core.BuildPhaseProvider.AfterHeapLayout;
import com.oracle.svm.core.BuildPhaseProvider.AfterHostedUniverse;
Expand Down Expand Up @@ -483,7 +482,9 @@ public static DynamicHub allocate(String name, DynamicHub superHub, Object inter
int[] interfaceHashTableHeapArray,
int openTypeWorldInterfaceHashParam,
int vTableEntries,
int afterFieldsOffset, boolean valueBased) {
int[] declaredInstanceReferenceFieldOffsets,
int afterFieldsOffset,
boolean valueBased) {
VMError.guarantee(RuntimeClassLoading.isSupported());

ReferenceType referenceType = ReferenceType.computeReferenceType(DynamicHub.toClass(superHub));
Expand Down Expand Up @@ -541,7 +542,7 @@ public static DynamicHub allocate(String name, DynamicHub superHub, Object inter

boolean needsMonitorOffset = !valueBased;
if (needsMonitorOffset) {
// GR-60069 could look for gaps
// GR-69304 could look for gaps
int size = ol.getReferenceSize();
int bits = size - 1;
int alignmentAdjust = ((instanceSize + bits) & ~bits) - instanceSize;
Expand All @@ -552,7 +553,7 @@ public static DynamicHub allocate(String name, DynamicHub superHub, Object inter
if (ol.isIdentityHashFieldInObjectHeader()) {
identityHashOffset = ol.getObjectHeaderIdentityHashOffset();
} else if (ol.isIdentityHashFieldAtTypeSpecificOffset() || ol.isIdentityHashFieldOptional()) {
// GR-60069 could look for gaps
// GR-69304 could look for gaps
int bits = Integer.BYTES - 1;
int alignmentAdjust = ((instanceSize + bits) & ~bits) - instanceSize;
identityHashOffset = instanceSize + alignmentAdjust;
Expand Down Expand Up @@ -591,7 +592,7 @@ public static DynamicHub allocate(String name, DynamicHub superHub, Object inter
DynamicHub hub = Metaspace.singleton().allocateDynamicHub(vTableEntries);
int[] openTypeWorldTypeCheckSlots = Metaspace.singleton().copyToMetaspace(typeCheckSlotsHeapArray);
int[] openTypeWorldInterfaceHashTable = Metaspace.singleton().copyToMetaspace(interfaceHashTableHeapArray);
int referenceMapCompressedOffset = RuntimeInstanceReferenceMapSupport.singleton().getOrCreateReferenceMap(superHub);
int referenceMapCompressedOffset = RuntimeInstanceReferenceMapSupport.singleton().getOrCreateReferenceMap(superHub, declaredInstanceReferenceFieldOffsets);

/* Write fields in defining order. */
DynamicHubOffsets dynamicHubOffsets = DynamicHubOffsets.singleton();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,13 +71,11 @@ public static RuntimeInstanceReferenceMapSupport singleton() {
* @return a compressed offset, relative to the heap base, that points to an
* {@link InstanceReferenceMap}.
*/
public int getOrCreateReferenceMap(DynamicHub superHub, FieldInfo... declaredInstanceFields) {
public int getOrCreateReferenceMap(DynamicHub superHub, int... declaredInstanceReferenceFieldsOffsets) {
/* Create a bitmap and mark where there are declared object fields. */
SubstrateReferenceMap map = new SubstrateReferenceMap();
for (var field : declaredInstanceFields) {
if (field.hasObjectType()) {
map.markReferenceAtOffset(field.offset(), true);
}
for (int offset : declaredInstanceReferenceFieldsOffsets) {
map.markReferenceAtOffset(offset, true);
}

/* If there are no declared object fields, reuse the reference map from the super class. */
Expand Down Expand Up @@ -122,10 +120,6 @@ private static int toCompressedOffset(byte[] metaspaceRefMapArray) {
return InstanceReferenceMapEncoder.computeReferenceMapCompressedOffset(metaspaceMap);
}

/* Remove once GR-60069 is merged. */
public record FieldInfo(int offset, boolean hasObjectType) {
}

private record ReferenceMapHolder(byte[] refMap) {
@Override
public int hashCode() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@
*/
package com.oracle.svm.core.hub;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.RecordComponent;
import java.util.ArrayList;

import com.oracle.svm.core.configure.RuntimeConditionSet;
import com.oracle.svm.core.hub.crema.CremaResolvedJavaField;
import com.oracle.svm.core.hub.crema.CremaResolvedJavaMethod;
Expand All @@ -36,13 +43,6 @@
import jdk.vm.ci.meta.ResolvedJavaType;
import jdk.vm.ci.meta.UnresolvedJavaType;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.RecordComponent;
import java.util.ArrayList;

/**
* Instances of this class are used to represent the reflection metadata for Dynamic hubs loaded at
* runtime. Note, the use of the term 'Runtime' is not to be confused with e.g.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@

import java.util.List;

import com.oracle.svm.core.hub.DynamicHub;
import org.graalvm.nativeimage.ImageSingletons;
import org.graalvm.nativeimage.Platform;
import org.graalvm.nativeimage.Platforms;

import com.oracle.svm.core.hub.DynamicHub;
import com.oracle.svm.espresso.classfile.ParserKlass;

import jdk.vm.ci.meta.JavaType;
Expand All @@ -47,6 +47,10 @@ interface CremaDispatchTable {
int vtableLength();

int itableLength(Class<?> iface);

int afterFieldsOffset(int superAfterFieldsOffset);

int[] getDeclaredInstanceReferenceFieldOffsets();
}

CremaDispatchTable getDispatchTable(ParserKlass parsed, Class<?> superClass, List<Class<?>> superInterfaces);
Expand All @@ -63,6 +67,8 @@ interface CremaDispatchTable {

Class<?> resolveOrNull(JavaType unresolvedJavaType, ResolvedJavaType accessingClass);

Class<?> findLoadedClass(JavaType unresolvedJavaType, ResolvedJavaType accessingClass);

static CremaSupport singleton() {
return ImageSingletons.lookup(CremaSupport.class);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@
import com.oracle.svm.espresso.classfile.ClassfileStream;
import com.oracle.svm.espresso.classfile.ParserConstantPool;
import com.oracle.svm.espresso.classfile.ParserException;
import com.oracle.svm.espresso.classfile.ParserField;
import com.oracle.svm.espresso.classfile.ParserKlass;
import com.oracle.svm.espresso.classfile.ParserMethod;
import com.oracle.svm.espresso.classfile.attributes.Attribute;
Expand Down Expand Up @@ -395,15 +394,7 @@ private Class<?> createClass(ParserKlass parsed, ClassDefinitionInfo info, Symbo
afterFieldsOffset = 0;
} else {
int superAfterFieldsOffset = CremaSupport.singleton().getAfterFieldsOffset(superHub);
// GR-60069: field layout
int numDeclaredInstanceFields = 0;
for (ParserField field : parsed.getFields()) {
if (!field.isStatic()) {
numDeclaredInstanceFields += 1;
}
}
assert numDeclaredInstanceFields == 0;
afterFieldsOffset = Math.toIntExact(superAfterFieldsOffset);
afterFieldsOffset = dispatchTable.afterFieldsOffset(superAfterFieldsOffset);
}
boolean isValueBased = (parsed.getFlags() & ACC_VALUE_BASED) != 0;

Expand All @@ -415,7 +406,8 @@ private Class<?> createClass(ParserKlass parsed, ClassDefinitionInfo info, Symbo
DynamicHub hub = DynamicHub.allocate(externalName, superHub, interfacesEncoding, null,
sourceFile, modifiers, classFileAccessFlags, flags, getClassLoader(), simpleBinaryName, module, enclosingClass, classSignature,
typeID, interfaceID, numClassTypes, typeIDDepth, numIterableInterfaces, openTypeWorldTypeCheckSlots, openTypeWorldInterfaceHashTable, openTypeWorldInterfaceHashParam,
dispatchTableLength, afterFieldsOffset, isValueBased);
dispatchTableLength,
dispatchTable.getDeclaredInstanceReferenceFieldOffsets(), afterFieldsOffset, isValueBased);

CremaSupport.singleton().fillDynamicHubInfo(hub, dispatchTable, transitiveSuperInterfaces, iTableStartingIndices);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@

public interface CremaMethodAccess extends WithModifiers, MethodAccess<InterpreterResolvedJavaType, InterpreterResolvedJavaMethod, InterpreterResolvedJavaField> {
static LineNumberTable toJVMCI(LineNumberTableAttribute parserTable) {
if (parserTable == LineNumberTableAttribute.EMPTY) {
return null;
}
List<LineNumberTableAttribute.Entry> entries = parserTable.getEntries();
int[] bcis = new int[entries.size()];
int[] lineNumbers = new int[entries.size()];
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/*
* Copyright (c) 2025, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 com.oracle.svm.interpreter.metadata;

import com.oracle.svm.core.hub.DynamicHub;
import com.oracle.svm.core.hub.crema.CremaResolvedJavaField;
import com.oracle.svm.core.hub.crema.CremaSupport;
import com.oracle.svm.espresso.classfile.ParserField;

import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.UnresolvedJavaType;

public class CremaResolvedJavaFieldImpl extends InterpreterResolvedJavaField implements CremaResolvedJavaField {
public static final CremaResolvedJavaFieldImpl[] EMPTY_ARRAY = new CremaResolvedJavaFieldImpl[0];

CremaResolvedJavaFieldImpl(InterpreterResolvedObjectType declaringClass, ParserField f, int offset) {
super(f.getName(), f.getType(), f.getFlags(),
/*- resolvedType */ null,
declaringClass,
offset,
/*- constantValue */ null,
/*- isWordStorage */ false);
}

public static CremaResolvedJavaFieldImpl createAtRuntime(InterpreterResolvedObjectType declaringClass, ParserField f, int offset) {
return new CremaResolvedJavaFieldImpl(declaringClass, f, offset);
}

@Override
public JavaType getType() {
/*
* For fields created at build-time, the type is set if it is available. We explicitly do
* not want to trigger field type resolution at build-time.
*
* If the resolvedType is null, the type was not included in the image. If we were to
* eagerly create a ResolvedJavaType for it, we would force it back in.
*/
if (resolvedType == null) {
UnresolvedJavaType unresolvedJavaType = UnresolvedJavaType.create(getSymbolicType().toString());
/*
* This should not trigger actual class loading. Instead, we query the loader registry
* for an already loaded class.
*/
Class<?> cls = CremaSupport.singleton().findLoadedClass(unresolvedJavaType, getDeclaringClass());
if (cls == null) {
// Not loaded: return the unresolved type
return unresolvedJavaType;
}
resolvedType = (InterpreterResolvedJavaType) DynamicHub.fromClass(cls).getInterpreterType();
}
return resolvedType;
}

@Override
public InterpreterResolvedJavaType getResolvedType() {
if (resolvedType == null) {
Class<?> cls = CremaSupport.singleton().resolveOrThrow(UnresolvedJavaType.create(getSymbolicType().toString()), getDeclaringClass());
resolvedType = (InterpreterResolvedJavaType) DynamicHub.fromClass(cls).getInterpreterType();
}
return resolvedType;
}

@Override
public boolean isTrustedFinal() {
return isFinal() && (isStatic() || Record.class.isAssignableFrom(getDeclaringClass().getJavaClass()) /*- GR-69549: || getDeclaringClass().isHidden() */);
}

@Override
public byte[] getRawAnnotations() {
/* (GR-69096) resolvedJavaField.getRawAnnotations() */
return new byte[0];
}

@Override
public byte[] getRawTypeAnnotations() {
/* (GR-69096) resolvedJavaMethod.getRawTypeAnnotations() */
return new byte[0];
}

@Override
public String getGenericSignature() {
/* (GR-69096) resolvedJavaMethod.getGenericSignature() */
return getSymbolicType().toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@
*/
package com.oracle.svm.interpreter.metadata;

import com.oracle.svm.core.hub.crema.CremaResolvedJavaField;
import java.util.ArrayList;

import com.oracle.svm.core.hub.crema.CremaResolvedJavaMethod;
import com.oracle.svm.core.hub.crema.CremaResolvedJavaRecordComponent;
import com.oracle.svm.core.hub.crema.CremaResolvedJavaType;
Expand All @@ -35,8 +36,6 @@
import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.ResolvedJavaType;

import java.util.ArrayList;

public final class CremaResolvedObjectType extends InterpreterResolvedObjectType implements CremaResolvedJavaType {

public CremaResolvedObjectType(Symbol<Type> type, int modifiers, InterpreterResolvedJavaType componentType, InterpreterResolvedObjectType superclass, InterpreterResolvedObjectType[] interfaces,
Expand All @@ -45,9 +44,8 @@ public CremaResolvedObjectType(Symbol<Type> type, int modifiers, InterpreterReso
}

@Override
public CremaResolvedJavaField[] getDeclaredFields() {
// (GR-69098)
throw VMError.unimplemented("getDeclaredFields");
public CremaResolvedJavaFieldImpl[] getDeclaredFields() {
return (CremaResolvedJavaFieldImpl[]) declaredFields;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,11 @@
import com.oracle.svm.core.hub.registry.SymbolsSupport;
import com.oracle.svm.espresso.classfile.descriptors.Symbol;
import com.oracle.svm.espresso.classfile.descriptors.Type;
import com.oracle.svm.espresso.classfile.descriptors.TypeSymbols;
import com.oracle.svm.espresso.shared.meta.TypeAccess;

import jdk.vm.ci.meta.JavaKind;

public interface CremaTypeAccess extends WithModifiers, TypeAccess<InterpreterResolvedJavaType, InterpreterResolvedJavaMethod, InterpreterResolvedJavaField> {
static Symbol<Type> jvmciNameToType(String name) {
// hidden classes and SVM stable proxy name contain a `.`
Expand All @@ -39,4 +42,11 @@ static Symbol<Type> jvmciNameToType(String name) {
}
return type;
}

static JavaKind symbolToJvmciKind(Symbol<Type> type) {
if (TypeSymbols.isPrimitive(type)) {
return JavaKind.fromPrimitiveOrVoidTypeChar((char) type.byteAt(0));
}
return JavaKind.Object;
}
}
Loading