Skip to content

Commit

Permalink
[GR-36431] Use reflection metadata for all objects
Browse files Browse the repository at this point in the history
PullRequest: graal/10820
  • Loading branch information
loicottet committed Mar 13, 2022
2 parents 7813ac7 + 830e38c commit 8a42ff9
Show file tree
Hide file tree
Showing 49 changed files with 3,737 additions and 3,252 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
10 changes: 5 additions & 5 deletions docs/reference-manual/native-image/BuildOutput.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ To reduce overhead, please ensure that the classpath only contains entries that
#### <a name="glossary-reflection-registrations"></a>Reflection Registrations
The number of classes, fields, and methods that are registered for reflection.
Large numbers can cause significant reflection overheads, slow down the build process, and increase the size of the native image (see [method metadata](#glossary-method-metadata)).
Large numbers can cause significant reflection overheads, slow down the build process, and increase the size of the native image (see [reflection metadata](#glossary-reflection-metadata)).
#### <a name="glossary-jni-access-registrations"></a>JNI Access Registrations
The number of classes, fields, and methods that are registered for [JNI][doc_jni] access.
Expand Down Expand Up @@ -136,16 +136,16 @@ Therefore, reducing the number of [reachable methods](#glossary-reachability) al
The image heap contains reachable objects such as static application data, metadata, and `byte[]` for different purposes.
##### <a name="glossary-general-heap-data"></a>General Heap Data Stored in `byte[]`
The total size of all `byte[]` objects that are neither used for `java.lang.String`, nor [code metadata](#glossary-code-metadata), nor [method metadata](#glossary-method-metadata), nor [graph encodings](#glossary-graph-encodings).
The total size of all `byte[]` objects that are neither used for `java.lang.String`, nor [code metadata](#glossary-code-metadata), nor [reflection metadata](#glossary-reflection-metadata), nor [graph encodings](#glossary-graph-encodings).
Therefore, this can also include `byte[]` objects from application code.
##### <a name="glossary-code-metadata"></a>Code Metadata Stored in `byte[]`
The total size of all `byte[]` objects used for metadata for the [code area](#glossary-code-area).
Therefore, reducing the number of [reachable methods](#glossary-reachability) also reduces the size of this metadata.
##### <a name="glossary-method-metadata"></a>Method Metadata Stored in `byte[]`
The total size of all `byte[]` objects used for method metadata, a type of reflection metadata.
To reduce the amount of method metadata, reduce the number of [classes registered for reflection](#glossary-reflection-classes).
##### <a name="glossary-reflection-metadata"></a>Reflection Metadata Stored in `byte[]`
The total size of all `byte[]` objects used for reflection metadata, including class, field, method and constructor data.
To reduce the amount of reflection metadata, reduce the number of [elements registered for reflection](#glossary-reflection-registrations).
##### <a name="glossary-graph-encodings"></a>Graph Encodings Stored in `byte[]`
The total size of all `byte[]` objects used for graph encodings.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
Expand Down Expand Up @@ -47,6 +47,8 @@
import java.util.Collections;
import java.util.List;

import org.graalvm.nativeimage.Platform;
import org.graalvm.nativeimage.Platforms;
import org.graalvm.nativeimage.c.function.CLibrary;

/**
Expand All @@ -58,6 +60,7 @@
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Platforms(Platform.HOSTED_ONLY.class)
public @interface CContext {

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,18 +40,36 @@
*/
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 registerHeapDynamicHub(Object hub);

Set<?> getHeapDynamicHubs();

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 @@ -159,6 +159,9 @@ protected final void scanField(AnalysisField field, JavaConstant receiver, ScanR
throw AnalysisError.shouldNotReachHere("Could not find field " + field.format("%H.%n") +
(receiver == null ? "" : " on " + constantType(bb, receiver).toJavaName()) +
System.lineSeparator() + backtrace);
} else if (fieldValue.getJavaKind() == JavaKind.Illegal) {
/* The value is not available yet */
return;
}

if (fieldValue.getJavaKind() == JavaKind.Object && bb.getHostVM().isRelocatedPointer(constantAsObject(bb, fieldValue))) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,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,8 +720,9 @@ protected void onValueUpdate(EconomicMap<OptionKey<?>, Object> values, String ol
}
};

@SuppressWarnings("unused")//
@APIOption(name = "configure-reflection-metadata")//
@Option(help = "Enable runtime instantiation of reflection objects for non-invoked methods.", type = OptionType.Expert)//
@Option(help = "Enable runtime instantiation of reflection objects for non-invoked methods.", type = OptionType.Expert, deprecated = true)//
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)//
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 8a42ff9

Please sign in to comment.