Skip to content

Commit 8a42ff9

Browse files
committed
[GR-36431] Use reflection metadata for all objects
PullRequest: graal/10820
2 parents 7813ac7 + 830e38c commit 8a42ff9

File tree

49 files changed

+3737
-3252
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+3737
-3252
lines changed

compiler/src/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/util/UnsafeArrayTypeWriter.java

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,13 @@ protected Chunk(int arrayLength) {
7474
protected int totalSize;
7575

7676
public static UnsafeArrayTypeWriter create(boolean supportsUnalignedMemoryAccess) {
77-
if (supportsUnalignedMemoryAccess) {
77+
return create(supportsUnalignedMemoryAccess, false);
78+
}
79+
80+
public static UnsafeArrayTypeWriter create(boolean supportsUnalignedMemoryAccess, boolean bigEndian) {
81+
if (bigEndian) {
82+
return new BigEndianUnsafeArrayTypeWriter();
83+
} else if (supportsUnalignedMemoryAccess) {
7884
return new UnalignedUnsafeArrayTypeWriter();
7985
} else {
8086
return new AlignedUnsafeArrayTypeWriter();
@@ -287,3 +293,35 @@ protected void putS8(long value, Chunk chunk, long offset) {
287293
UNSAFE.putByte(chunk.data, offset + 7, (byte) (value >> 56));
288294
}
289295
}
296+
297+
final class BigEndianUnsafeArrayTypeWriter extends UnsafeArrayTypeWriter {
298+
private static final Unsafe UNSAFE = getUnsafe();
299+
300+
@Override
301+
protected void putS2(long value, Chunk chunk, long offset) {
302+
assert TypeConversion.isS2(value);
303+
UNSAFE.putByte(chunk.data, offset + 0, (byte) (value >> 8));
304+
UNSAFE.putByte(chunk.data, offset + 1, (byte) (value >> 0));
305+
}
306+
307+
@Override
308+
protected void putS4(long value, Chunk chunk, long offset) {
309+
assert TypeConversion.isS4(value);
310+
UNSAFE.putByte(chunk.data, offset + 0, (byte) (value >> 24));
311+
UNSAFE.putByte(chunk.data, offset + 1, (byte) (value >> 16));
312+
UNSAFE.putByte(chunk.data, offset + 2, (byte) (value >> 8));
313+
UNSAFE.putByte(chunk.data, offset + 3, (byte) (value >> 0));
314+
}
315+
316+
@Override
317+
protected void putS8(long value, Chunk chunk, long offset) {
318+
UNSAFE.putByte(chunk.data, offset + 0, (byte) (value >> 56));
319+
UNSAFE.putByte(chunk.data, offset + 1, (byte) (value >> 48));
320+
UNSAFE.putByte(chunk.data, offset + 2, (byte) (value >> 40));
321+
UNSAFE.putByte(chunk.data, offset + 3, (byte) (value >> 32));
322+
UNSAFE.putByte(chunk.data, offset + 4, (byte) (value >> 24));
323+
UNSAFE.putByte(chunk.data, offset + 5, (byte) (value >> 16));
324+
UNSAFE.putByte(chunk.data, offset + 6, (byte) (value >> 8));
325+
UNSAFE.putByte(chunk.data, offset + 7, (byte) (value >> 0));
326+
}
327+
}

compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/BoxingSnippets.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,12 @@ private static LocationIdentity getCacheLocation(CoreProviders providers, JavaKi
221221
if (innerClasses == null || innerClasses.length == 0) {
222222
throw GraalError.shouldNotReachHere("Inner classes must exist");
223223
}
224-
return new FieldLocationIdentity(providers.getMetaAccess().lookupJavaField(innerClasses[0].getDeclaredField("cache")));
224+
for (Class<?> innerClass : innerClasses) {
225+
if (innerClass.getName().endsWith("Cache")) {
226+
return new FieldLocationIdentity(providers.getMetaAccess().lookupJavaField(innerClass.getDeclaredField("cache")));
227+
}
228+
}
229+
throw GraalError.shouldNotReachHere("No cache inner class found");
225230
} catch (Throwable e) {
226231
throw GraalError.shouldNotReachHere(e);
227232
}

docs/reference-manual/native-image/BuildOutput.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ To reduce overhead, please ensure that the classpath only contains entries that
9999
100100
#### <a name="glossary-reflection-registrations"></a>Reflection Registrations
101101
The number of classes, fields, and methods that are registered for reflection.
102-
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)).
102+
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)).
103103
104104
#### <a name="glossary-jni-access-registrations"></a>JNI Access Registrations
105105
The number of classes, fields, and methods that are registered for [JNI][doc_jni] access.
@@ -136,16 +136,16 @@ Therefore, reducing the number of [reachable methods](#glossary-reachability) al
136136
The image heap contains reachable objects such as static application data, metadata, and `byte[]` for different purposes.
137137
138138
##### <a name="glossary-general-heap-data"></a>General Heap Data Stored in `byte[]`
139-
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).
139+
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).
140140
Therefore, this can also include `byte[]` objects from application code.
141141
142142
##### <a name="glossary-code-metadata"></a>Code Metadata Stored in `byte[]`
143143
The total size of all `byte[]` objects used for metadata for the [code area](#glossary-code-area).
144144
Therefore, reducing the number of [reachable methods](#glossary-reachability) also reduces the size of this metadata.
145145
146-
##### <a name="glossary-method-metadata"></a>Method Metadata Stored in `byte[]`
147-
The total size of all `byte[]` objects used for method metadata, a type of reflection metadata.
148-
To reduce the amount of method metadata, reduce the number of [classes registered for reflection](#glossary-reflection-classes).
146+
##### <a name="glossary-reflection-metadata"></a>Reflection Metadata Stored in `byte[]`
147+
The total size of all `byte[]` objects used for reflection metadata, including class, field, method and constructor data.
148+
To reduce the amount of reflection metadata, reduce the number of [elements registered for reflection](#glossary-reflection-registrations).
149149
150150
##### <a name="glossary-graph-encodings"></a>Graph Encodings Stored in `byte[]`
151151
The total size of all `byte[]` objects used for graph encodings.

sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/c/CContext.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -47,6 +47,8 @@
4747
import java.util.Collections;
4848
import java.util.List;
4949

50+
import org.graalvm.nativeimage.Platform;
51+
import org.graalvm.nativeimage.Platforms;
5052
import org.graalvm.nativeimage.c.function.CLibrary;
5153

5254
/**
@@ -58,6 +60,7 @@
5860
*/
5961
@Retention(RetentionPolicy.RUNTIME)
6062
@Target({ElementType.TYPE})
63+
@Platforms(Platform.HOSTED_ONLY.class)
6164
public @interface CContext {
6265

6366
/**

sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/impl/RuntimeReflectionSupport.java

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,18 +40,36 @@
4040
*/
4141
package org.graalvm.nativeimage.impl;
4242

43+
import java.lang.reflect.AccessibleObject;
4344
import java.lang.reflect.Executable;
45+
import java.lang.reflect.Field;
46+
import java.util.Map;
4447
import java.util.Set;
4548

4649
public interface RuntimeReflectionSupport extends ReflectionRegistry {
47-
// specific to java.lang.reflect reflection
48-
Set<Executable> getQueriedOnlyMethods();
50+
Map<Class<?>, Set<Class<?>>> getReflectionInnerClasses();
51+
52+
Set<Field> getReflectionFields();
53+
54+
Set<Executable> getReflectionExecutables();
55+
56+
Object getAccessor(Executable method);
4957

5058
/*
5159
* Returns the methods that shadow a superclass method registered for reflection, to be excluded
5260
* from reflection queries.
5361
*/
54-
Set<?> getHidingMethods();
62+
Set<?> getHidingReflectionMethods();
63+
64+
Object[] getRecordComponents(Class<?> type);
65+
66+
void registerHeapDynamicHub(Object hub);
67+
68+
Set<?> getHeapDynamicHubs();
69+
70+
void registerHeapReflectionObject(AccessibleObject object);
71+
72+
Set<AccessibleObject> getHeapReflectionObjects();
5573

5674
int getReflectionClassesCount();
5775

substratevm/mx.substratevm/suite.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,9 @@
194194
"sun.invoke.util",
195195
"sun.net",
196196
"sun.reflect.annotation",
197+
"sun.reflect.generics.factory",
197198
"sun.reflect.generics.reflectiveObjects",
199+
"sun.reflect.generics.repository",
198200
"sun.reflect.generics.tree",
199201
"sun.security.jca",
200202
"sun.security.ssl",

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/ObjectScanner.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,9 @@ protected final void scanField(AnalysisField field, JavaConstant receiver, ScanR
159159
throw AnalysisError.shouldNotReachHere("Could not find field " + field.format("%H.%n") +
160160
(receiver == null ? "" : " on " + constantType(bb, receiver).toJavaName()) +
161161
System.lineSeparator() + backtrace);
162+
} else if (fieldValue.getJavaKind() == JavaKind.Illegal) {
163+
/* The value is not available yet */
164+
return;
162165
}
163166

164167
if (fieldValue.getJavaKind() == JavaKind.Object && bb.getHostVM().isRelocatedPointer(constantAsObject(bb, fieldValue))) {

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/heap/ImageHeapScanner.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,7 @@ private boolean notifyAnalysis(JavaConstant array, AnalysisType arrayType, JavaC
400400
return analysisModified;
401401
}
402402

403-
void onObjectReachable(ImageHeapObject imageHeapObject) {
403+
protected void onObjectReachable(ImageHeapObject imageHeapObject) {
404404
AnalysisType objectType = metaAccess.lookupJavaType(imageHeapObject.getObject());
405405
imageHeap.add(objectType, imageHeapObject);
406406

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -720,8 +720,9 @@ protected void onValueUpdate(EconomicMap<OptionKey<?>, Object> values, String ol
720720
}
721721
};
722722

723+
@SuppressWarnings("unused")//
723724
@APIOption(name = "configure-reflection-metadata")//
724-
@Option(help = "Enable runtime instantiation of reflection objects for non-invoked methods.", type = OptionType.Expert)//
725+
@Option(help = "Enable runtime instantiation of reflection objects for non-invoked methods.", type = OptionType.Expert, deprecated = true)//
725726
public static final HostedOptionKey<Boolean> ConfigureReflectionMetadata = new HostedOptionKey<>(true);
726727

727728
@Option(help = "Include a list of methods included in the image for runtime inspection.", type = OptionType.Expert)//

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/code/CodeInfoEncoder.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ public void addToReferenceMapSize(long size) {
106106
}
107107

108108
public static final class Encoders {
109-
final FrequencyEncoder<JavaConstant> objectConstants;
109+
public final FrequencyEncoder<JavaConstant> objectConstants;
110110
public final FrequencyEncoder<Class<?>> sourceClasses;
111111
public final FrequencyEncoder<String> sourceMethodNames;
112112
final FrequencyEncoder<String> names;

0 commit comments

Comments
 (0)