Skip to content

Commit

Permalink
Create reflection objects at runtime using metadata
Browse files Browse the repository at this point in the history
  • Loading branch information
loicottet committed Mar 7, 2022
1 parent 40496fa commit 1c8ecae
Show file tree
Hide file tree
Showing 40 changed files with 2,310 additions and 2,123 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,13 @@ protected Chunk(int arrayLength) {
protected int totalSize;

public static UnsafeArrayTypeWriter create(boolean supportsUnalignedMemoryAccess) {
if (supportsUnalignedMemoryAccess) {
return create(supportsUnalignedMemoryAccess, false);
}

public static UnsafeArrayTypeWriter create(boolean supportsUnalignedMemoryAccess, boolean bigEndian) {
if (bigEndian) {
return new BigEndianUnsafeArrayTypeWriter();
} else if (supportsUnalignedMemoryAccess) {
return new UnalignedUnsafeArrayTypeWriter();
} else {
return new AlignedUnsafeArrayTypeWriter();
Expand Down Expand Up @@ -287,3 +293,35 @@ protected void putS8(long value, Chunk chunk, long offset) {
UNSAFE.putByte(chunk.data, offset + 7, (byte) (value >> 56));
}
}

final class BigEndianUnsafeArrayTypeWriter extends UnsafeArrayTypeWriter {
private static final Unsafe UNSAFE = getUnsafe();

@Override
protected void putS2(long value, Chunk chunk, long offset) {
assert TypeConversion.isS2(value);
UNSAFE.putByte(chunk.data, offset + 0, (byte) (value >> 8));
UNSAFE.putByte(chunk.data, offset + 1, (byte) (value >> 0));
}

@Override
protected void putS4(long value, Chunk chunk, long offset) {
assert TypeConversion.isS4(value);
UNSAFE.putByte(chunk.data, offset + 0, (byte) (value >> 24));
UNSAFE.putByte(chunk.data, offset + 1, (byte) (value >> 16));
UNSAFE.putByte(chunk.data, offset + 2, (byte) (value >> 8));
UNSAFE.putByte(chunk.data, offset + 3, (byte) (value >> 0));
}

@Override
protected void putS8(long value, Chunk chunk, long offset) {
UNSAFE.putByte(chunk.data, offset + 0, (byte) (value >> 56));
UNSAFE.putByte(chunk.data, offset + 1, (byte) (value >> 48));
UNSAFE.putByte(chunk.data, offset + 2, (byte) (value >> 40));
UNSAFE.putByte(chunk.data, offset + 3, (byte) (value >> 32));
UNSAFE.putByte(chunk.data, offset + 4, (byte) (value >> 24));
UNSAFE.putByte(chunk.data, offset + 5, (byte) (value >> 16));
UNSAFE.putByte(chunk.data, offset + 6, (byte) (value >> 8));
UNSAFE.putByte(chunk.data, offset + 7, (byte) (value >> 0));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,12 @@ private static LocationIdentity getCacheLocation(CoreProviders providers, JavaKi
if (innerClasses == null || innerClasses.length == 0) {
throw GraalError.shouldNotReachHere("Inner classes must exist");
}
return new FieldLocationIdentity(providers.getMetaAccess().lookupJavaField(innerClasses[0].getDeclaredField("cache")));
for (Class<?> innerClass : innerClasses) {
if (innerClass.getName().endsWith("Cache")) {
return new FieldLocationIdentity(providers.getMetaAccess().lookupJavaField(innerClass.getDeclaredField("cache")));
}
}
throw GraalError.shouldNotReachHere("No cache inner class found");
} catch (Throwable e) {
throw GraalError.shouldNotReachHere(e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,18 +40,32 @@
*/
package org.graalvm.nativeimage.impl;

import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Executable;
import java.lang.reflect.Field;
import java.util.Map;
import java.util.Set;

public interface RuntimeReflectionSupport extends ReflectionRegistry {
// specific to java.lang.reflect reflection
Set<Executable> getQueriedOnlyMethods();
Map<Class<?>, Set<Class<?>>> getReflectionInnerClasses();

Set<Field> getReflectionFields();

Set<Executable> getReflectionExecutables();

Object getAccessor(Executable method);

/*
* Returns the methods that shadow a superclass method registered for reflection, to be excluded
* from reflection queries.
*/
Set<?> getHidingMethods();
Set<?> getHidingReflectionMethods();

Object[] getRecordComponents(Class<?> type);

void registerHeapReflectionObject(AccessibleObject object);

Set<AccessibleObject> getHeapReflectionObjects();

int getReflectionClassesCount();

Expand Down
2 changes: 2 additions & 0 deletions substratevm/mx.substratevm/suite.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,9 @@
"sun.invoke.util",
"sun.net",
"sun.reflect.annotation",
"sun.reflect.generics.factory",
"sun.reflect.generics.reflectiveObjects",
"sun.reflect.generics.repository",
"sun.reflect.generics.tree",
"sun.security.jca",
"sun.security.ssl",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,7 @@ private boolean notifyAnalysis(JavaConstant array, AnalysisType arrayType, JavaC
return analysisModified;
}

void onObjectReachable(ImageHeapObject imageHeapObject) {
protected void onObjectReachable(ImageHeapObject imageHeapObject) {
AnalysisType objectType = metaAccess.lookupJavaType(imageHeapObject.getObject());
imageHeap.add(objectType, imageHeapObject);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -720,10 +720,6 @@ protected void onValueUpdate(EconomicMap<OptionKey<?>, Object> values, String ol
}
};

@APIOption(name = "configure-reflection-metadata")//
@Option(help = "Enable runtime instantiation of reflection objects for non-invoked methods.", type = OptionType.Expert)//
public static final HostedOptionKey<Boolean> ConfigureReflectionMetadata = new HostedOptionKey<>(true);

@Option(help = "Include a list of methods included in the image for runtime inspection.", type = OptionType.Expert)//
public static final HostedOptionKey<Boolean> IncludeMethodData = new HostedOptionKey<>(true);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ public void addToReferenceMapSize(long size) {
}

public static final class Encoders {
final FrequencyEncoder<JavaConstant> objectConstants;
public final FrequencyEncoder<JavaConstant> objectConstants;
public final FrequencyEncoder<Class<?>> sourceClasses;
public final FrequencyEncoder<String> sourceMethodNames;
final FrequencyEncoder<String> names;
Expand Down
Loading

0 comments on commit 1c8ecae

Please sign in to comment.