Skip to content
Closed
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 @@ -45,6 +45,8 @@
import com.oracle.svm.core.heap.RestrictHeapAccess;
import com.oracle.svm.core.heap.RestrictHeapAccess.Access;
import com.oracle.svm.core.heap.VMOperationInfos;
import com.oracle.svm.core.imagelayer.ImageLayerBuildingSupport;
import com.oracle.svm.core.layeredimagesingleton.MultiLayeredImageSingleton;
import com.oracle.svm.core.log.Log;
import com.oracle.svm.core.meta.SharedMethod;
import com.oracle.svm.core.option.HostedOptionKey;
Expand Down Expand Up @@ -99,6 +101,17 @@ public static CodeInfo getFirstImageCodeInfo() {
return imageCodeInfo;
}

@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
public static CodeInfo getFirstImageCodeInfo(int layerNumber) {
if (ImageLayerBuildingSupport.buildingImageLayer()) {
ImageCodeInfoStorage[] runtimeCodeInfos = MultiLayeredImageSingleton.getAllLayers(ImageCodeInfoStorage.class);
return runtimeCodeInfos[layerNumber].getData();
} else {
assert layerNumber == 0;
return imageCodeInfo;
}
}

@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
public static CodeInfo getImageCodeInfo(CodePointer ip) {
CodeInfo info = lookupImageCodeInfo(ip);
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,18 @@
*/
package com.oracle.svm.core.code;

import java.util.EnumSet;

import org.graalvm.nativeimage.Platform;
import org.graalvm.nativeimage.Platforms;

import com.oracle.svm.core.BuildPhaseProvider.AfterCompilation;
import com.oracle.svm.core.code.RuntimeMetadataDecoderImpl.MetadataAccessorImpl;
import com.oracle.svm.core.feature.AutomaticallyRegisteredImageSingleton;
import com.oracle.svm.core.heap.UnknownObjectField;
import com.oracle.svm.core.layeredimagesingleton.LayeredImageSingletonBuilderFlags;
import com.oracle.svm.core.layeredimagesingleton.MultiLayeredImageSingleton;
import com.oracle.svm.core.layeredimagesingleton.UnsavedSingleton;

/**
* Stores the encoding of all runtime metadata.
Expand All @@ -43,7 +48,7 @@
* we would need an index to locate all relevant runtime metadata of an entity from all layers.
*/
@AutomaticallyRegisteredImageSingleton
public class RuntimeMetadataEncoding {
public class RuntimeMetadataEncoding implements MultiLayeredImageSingleton, UnsavedSingleton {
@UnknownObjectField(availability = AfterCompilation.class) private byte[] encoding;

public byte[] getEncoding() {
Expand All @@ -54,4 +59,9 @@ public byte[] getEncoding() {
public void setEncoding(byte[] encoding) {
this.encoding = encoding;
}

@Override
public EnumSet<LayeredImageSingletonBuilderFlags> getImageBuilderFlags() {
return LayeredImageSingletonBuilderFlags.ALL_ACCESS;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

import static com.oracle.svm.core.MissingRegistrationUtils.throwMissingRegistrationErrors;

import java.util.EnumSet;
import java.util.Objects;

import org.graalvm.collections.EconomicMap;
Expand All @@ -37,12 +38,15 @@
import com.oracle.svm.core.configure.ConditionalRuntimeValue;
import com.oracle.svm.core.configure.RuntimeConditionSet;
import com.oracle.svm.core.feature.AutomaticallyRegisteredImageSingleton;
import com.oracle.svm.core.layeredimagesingleton.LayeredImageSingletonBuilderFlags;
import com.oracle.svm.core.layeredimagesingleton.MultiLayeredImageSingleton;
import com.oracle.svm.core.layeredimagesingleton.UnsavedSingleton;
import com.oracle.svm.core.reflect.MissingReflectionRegistrationUtils;
import com.oracle.svm.core.util.ImageHeapMap;
import com.oracle.svm.core.util.VMError;

@AutomaticallyRegisteredImageSingleton
public final class ClassForNameSupport {
public final class ClassForNameSupport implements MultiLayeredImageSingleton, UnsavedSingleton {

public static ClassForNameSupport singleton() {
return ImageSingletons.lookup(ClassForNameSupport.class);
Expand Down Expand Up @@ -159,31 +163,25 @@ private void updateCondition(ConfigurationCondition condition, String className,
}
}

public Class<?> forNameOrNull(String className, ClassLoader classLoader) {
public static Class<?> forNameOrNull(String className, ClassLoader classLoader) {
try {
return forName(className, classLoader, true);
} catch (ClassNotFoundException e) {
throw VMError.shouldNotReachHere("ClassForNameSupport#forNameOrNull should not throw", e);
}
}

public Class<?> forName(String className, ClassLoader classLoader) throws ClassNotFoundException {
public static Class<?> forName(String className, ClassLoader classLoader) throws ClassNotFoundException {
return forName(className, classLoader, false);
}

private Class<?> forName(String className, ClassLoader classLoader, boolean returnNullOnException) throws ClassNotFoundException {
private static Class<?> forName(String className, ClassLoader classLoader, boolean returnNullOnException) throws ClassNotFoundException {
if (className == null) {
return null;
}
var conditional = knownClasses.get(className);
Object result = conditional == null ? null : conditional.getValue();
if (result == NEGATIVE_QUERY || className.endsWith("[]")) {
/* Querying array classes with their "TypeName[]" name always throws */
result = new ClassNotFoundException(className);
}
if (result == null) {
result = PredefinedClassesSupport.getLoadedForNameOrNull(className, classLoader);
}
ClassForNameSupport classForNameSupport = singleton();
Object result = classForNameSupport.getSingletonData(classForNameSupport, MultiLayeredImageSingleton.getAllLayers(ClassForNameSupport.class),
singleton -> singleton.forName0(className, classLoader));
// Note: for non-predefined classes, we (currently) don't need to check the provided loader
// TODO rewrite stack traces (GR-42813)
if (result instanceof Class<?>) {
Expand Down Expand Up @@ -212,13 +210,29 @@ private Class<?> forName(String className, ClassLoader classLoader, boolean retu
throw VMError.shouldNotReachHere("Class.forName result should be Class, ClassNotFoundException or Error: " + result);
}

private Object forName0(String className, ClassLoader classLoader) {
var conditional = knownClasses.get(className);
Object result = conditional == null ? null : conditional.getValue();
if (result == NEGATIVE_QUERY || className.endsWith("[]")) {
/* Querying array classes with their "TypeName[]" name always throws */
result = new ClassNotFoundException(className);
}
if (result == null) {
result = PredefinedClassesSupport.getLoadedForNameOrNull(className, classLoader);
}
return result;
}

public int count() {
return knownClasses.size();
}

public RuntimeConditionSet getConditionFor(Class<?> jClass) {
public static RuntimeConditionSet getConditionFor(Class<?> jClass) {
Objects.requireNonNull(jClass);
ConditionalRuntimeValue<Object> conditionalClass = knownClasses.get(jClass.getName());
String jClassName = jClass.getName();
ClassForNameSupport classForNameSupport = singleton();
ConditionalRuntimeValue<Object> conditionalClass = classForNameSupport.getSingletonData(classForNameSupport, MultiLayeredImageSingleton.getAllLayers(ClassForNameSupport.class),
singleton -> singleton.knownClasses.get(jClassName));
if (conditionalClass == null) {
return RuntimeConditionSet.unmodifiableEmptySet();
} else {
Expand All @@ -230,8 +244,16 @@ public RuntimeConditionSet getConditionFor(Class<?> jClass) {
* Checks whether {@code hub} can be instantiated with {@code Unsafe.allocateInstance}. Note
* that arrays can't be instantiated and this function will always return false for array types.
*/
public boolean canUnsafeInstantiateAsInstance(DynamicHub hub) {
var conditionSet = unsafeInstantiatedClasses.get(DynamicHub.toClass(hub));
public static boolean canUnsafeInstantiateAsInstance(DynamicHub hub) {
Class<?> clazz = DynamicHub.toClass(hub);
ClassForNameSupport classForNameSupport = singleton();
RuntimeConditionSet conditionSet = classForNameSupport.getSingletonData(classForNameSupport, MultiLayeredImageSingleton.getAllLayers(ClassForNameSupport.class),
singleton -> singleton.unsafeInstantiatedClasses.get(clazz));
return conditionSet != null && conditionSet.satisfied();
}

@Override
public EnumSet<LayeredImageSingletonBuilderFlags> getImageBuilderFlags() {
return LayeredImageSingletonBuilderFlags.ALL_ACCESS;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -762,7 +762,7 @@ public boolean canUnsafeInstantiateAsInstanceFastPath() {
}

public boolean canUnsafeInstantiateAsInstanceSlowPath() {
if (ClassForNameSupport.singleton().canUnsafeInstantiateAsInstance(this)) {
if (ClassForNameSupport.canUnsafeInstantiateAsInstance(this)) {
companion.setUnsafeAllocate();
return true;
} else {
Expand Down Expand Up @@ -1110,7 +1110,7 @@ private Field[] getFields() {
}

private RuntimeConditionSet getConditions() {
return ClassForNameSupport.singleton().getConditionFor(DynamicHub.toClass(this));
return ClassForNameSupport.getConditionFor(DynamicHub.toClass(this));
}

@Substitute
Expand Down Expand Up @@ -1498,7 +1498,7 @@ private static Class<?> forName(String name, boolean initialize, ClassLoader loa
}
Class<?> result;
try {
result = ClassForNameSupport.singleton().forName(name, loader);
result = ClassForNameSupport.forName(name, loader);
} catch (ClassNotFoundException e) {
if (loader != null && PredefinedClassesSupport.hasBytecodeClasses()) {
result = loader.loadClass(name); // may throw
Expand Down Expand Up @@ -1577,7 +1577,7 @@ public Object[] getSigners() {
if (hubMetadata == null || hubMetadata.signersEncodingIndex == NO_DATA) {
return null;
}
return ImageSingletons.lookup(RuntimeMetadataDecoder.class).parseObjects(hubMetadata.signersEncodingIndex);
return ImageSingletons.lookup(RuntimeMetadataDecoder.class).parseObjects(hubMetadata.signersEncodingIndex, this);
}

@Substitute
Expand Down Expand Up @@ -1725,7 +1725,7 @@ private Object[] getEnclosingMethod0() {
if (hubMetadata == null || hubMetadata.enclosingMethodInfoIndex == NO_DATA) {
return null;
}
Object[] enclosingMethod = ImageSingletons.lookup(RuntimeMetadataDecoder.class).parseEnclosingMethod(hubMetadata.enclosingMethodInfoIndex);
Object[] enclosingMethod = ImageSingletons.lookup(RuntimeMetadataDecoder.class).parseEnclosingMethod(hubMetadata.enclosingMethodInfoIndex, this);
if (enclosingMethod != null) {
PredefinedClassesSupport.throwIfUnresolvable((Class<?>) enclosingMethod[0], getClassLoader0());
}
Expand Down Expand Up @@ -1761,15 +1761,15 @@ byte[] getRawAnnotations() {
if (hubMetadata == null || hubMetadata.annotationsIndex == NO_DATA) {
return null;
}
return ImageSingletons.lookup(RuntimeMetadataDecoder.class).parseByteArray(hubMetadata.annotationsIndex);
return ImageSingletons.lookup(RuntimeMetadataDecoder.class).parseByteArray(hubMetadata.annotationsIndex, this);
}

@Substitute
byte[] getRawTypeAnnotations() {
if (hubMetadata == null || hubMetadata.typeAnnotationsIndex == NO_DATA) {
return null;
}
return ImageSingletons.lookup(RuntimeMetadataDecoder.class).parseByteArray(hubMetadata.typeAnnotationsIndex);
return ImageSingletons.lookup(RuntimeMetadataDecoder.class).parseByteArray(hubMetadata.typeAnnotationsIndex, this);
}

@Substitute
Expand Down Expand Up @@ -1806,7 +1806,7 @@ private Class<?>[] getDeclaredClasses0() {
if (hubMetadata == null || hubMetadata.classesEncodingIndex == NO_DATA) {
return new Class<?>[0];
}
Class<?>[] declaredClasses = ImageSingletons.lookup(RuntimeMetadataDecoder.class).parseClasses(hubMetadata.classesEncodingIndex);
Class<?>[] declaredClasses = ImageSingletons.lookup(RuntimeMetadataDecoder.class).parseClasses(hubMetadata.classesEncodingIndex, this);
for (Class<?> clazz : declaredClasses) {
PredefinedClassesSupport.throwIfUnresolvable(clazz, getClassLoader0());
}
Expand All @@ -1825,7 +1825,7 @@ private Class<?>[] getNestMembers0() {
if (hubMetadata == null || hubMetadata.nestMembersEncodingIndex == NO_DATA) {
return new Class<?>[]{DynamicHub.toClass(this)};
}
Class<?>[] nestMembers = ImageSingletons.lookup(RuntimeMetadataDecoder.class).parseClasses(hubMetadata.nestMembersEncodingIndex);
Class<?>[] nestMembers = ImageSingletons.lookup(RuntimeMetadataDecoder.class).parseClasses(hubMetadata.nestMembersEncodingIndex, this);
for (Class<?> clazz : nestMembers) {
PredefinedClassesSupport.throwIfUnresolvable(clazz, getClassLoader0());
}
Expand Down Expand Up @@ -1877,7 +1877,7 @@ private Class<?>[] getPermittedSubclasses0() {
if (hubMetadata == null || hubMetadata.permittedSubclassesEncodingIndex == NO_DATA) {
return new Class<?>[0];
}
Class<?>[] permittedSubclasses = ImageSingletons.lookup(RuntimeMetadataDecoder.class).parseClasses(hubMetadata.permittedSubclassesEncodingIndex);
Class<?>[] permittedSubclasses = ImageSingletons.lookup(RuntimeMetadataDecoder.class).parseClasses(hubMetadata.permittedSubclassesEncodingIndex, this);
for (Class<?> clazz : permittedSubclasses) {
PredefinedClassesSupport.throwIfUnresolvable(clazz, getClassLoader0());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -649,14 +649,14 @@ public static Stream<Package> packages() {

@Substitute
private static Class<?> loadClassOrNull(String name) {
return ClassForNameSupport.singleton().forNameOrNull(name, null);
return ClassForNameSupport.forNameOrNull(name, null);
}

@SuppressWarnings("unused")
@Substitute
private static Class<?> loadClass(Module module, String name) {
/* The module system is not supported for now, therefore the module parameter is ignored. */
return ClassForNameSupport.singleton().forNameOrNull(name, null);
return ClassForNameSupport.forNameOrNull(name, null);
}

@SuppressWarnings("unused")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ Class<?> loadClass(Module module, String name) {
@Substitute //
@SuppressWarnings({"unused"}) //
private Class<?> findLoadedClass0(String name) {
return ClassForNameSupport.singleton().forNameOrNull(name, SubstrateUtil.cast(this, ClassLoader.class));
return ClassForNameSupport.forNameOrNull(name, SubstrateUtil.cast(this, ClassLoader.class));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@
*/
package com.oracle.svm.core.layeredimagesingleton;

import java.util.function.Function;

import com.oracle.svm.core.imagelayer.ImageLayerBuildingSupport;
import com.oracle.svm.core.util.VMError;

public interface MultiLayeredImageSingleton extends LayeredImageSingleton {
Expand All @@ -36,4 +39,18 @@ public interface MultiLayeredImageSingleton extends LayeredImageSingleton {
static <T extends MultiLayeredImageSingleton> T[] getAllLayers(Class<T> key) {
throw VMError.shouldNotReachHere("This can only be called during runtime");
}

default <T extends MultiLayeredImageSingleton, U> U getSingletonData(T singleton, T[] singletons, Function<T, U> getSingletonDataFunction) {
if (ImageLayerBuildingSupport.buildingImageLayer()) {
for (var layerSingleton : singletons) {
U result = getSingletonDataFunction.apply(layerSingleton);
if (result != null) {
return result;
}
}
return null;
} else {
return getSingletonDataFunction.apply(singleton);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,17 +52,19 @@ public interface RuntimeMetadataDecoder {

ConstructorDescriptor[] parseReachableConstructors(DynamicHub declaringType, int index);

Class<?>[] parseClasses(int index);
Class<?>[] parseClasses(int index, DynamicHub declaringType);

Class<?>[] parseAllClasses();

RecordComponent[] parseRecordComponents(DynamicHub declaringType, int index);

Object[] parseObjects(int index);
Object[] parseObjects(int index, DynamicHub declaringType);

Parameter[] parseReflectParameters(Executable executable, byte[] encoding);
Parameter[] parseReflectParameters(Executable executable, byte[] encoding, DynamicHub declaringType);

Object[] parseEnclosingMethod(int index);
Object[] parseEnclosingMethod(int index, DynamicHub declaringType);

byte[] parseByteArray(int index);
byte[] parseByteArray(int index, DynamicHub declaringType);

boolean isHiding(int modifiers);

Expand Down Expand Up @@ -153,12 +155,28 @@ static MetadataAccessor singleton() {
return ImageSingletons.lookup(MetadataAccessor.class);
}

<T> T getObject(int index);
default <T> T getObject(int index) {
return getObject(index, 0);
}

default Class<?> getClass(int index) {
return getClass(index, 0);
}

default String getMemberName(int index) {
return getMemberName(index, 0);
}

default String getOtherString(int index) {
return getOtherString(index, 0);
}

<T> T getObject(int index, int layerId);

Class<?> getClass(int index);
Class<?> getClass(int index, int layerId);

String getMemberName(int index);
String getMemberName(int index, int layerId);

String getOtherString(int index);
String getOtherString(int index, int layerId);
}
}
Loading