Skip to content

Commit be5cf4d

Browse files
committed
[GR-32104] Reflection metadata bugfixes
PullRequest: graal/9841
2 parents f91185a + eb20426 commit be5cf4d

File tree

7 files changed

+80
-63
lines changed

7 files changed

+80
-63
lines changed

espresso/mx.espresso/mx_espresso.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,14 @@ def _espresso_gate_runner(args, tasks):
129129
break
130130

131131
with open(generated_header, 'r') as generated_header_file:
132-
generated_header_lines = generated_header_file.readlines()
132+
generated_header_lines = []
133+
for line in generated_header_file.readlines():
134+
# Ignore definitions that are not needed for Espresso
135+
if not line.startswith("typedef") or "(*Espresso_" in line or "__graal" in line or "(*graal_" in line:
136+
generated_header_lines.append(line)
137+
else:
138+
newline = generated_header_lines.pop() # Remove newline before ignored declaration
139+
assert newline == "\n"
133140

134141
errors = errors or mx.update_file(committed_header, ''.join(committed_header_copyright + generated_header_lines), showDiff=True)
135142

espresso/src/com.oracle.truffle.espresso.mokapot/include/libespresso_dynamic.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,6 @@ typedef int (*Espresso_CloseContext_fn_t)(graal_isolatethread_t* thread, struct
4242

4343
typedef void (*Espresso_Exit_fn_t)(graal_isolatethread_t* thread, struct JavaVM_* javaVM);
4444

45-
typedef void (*vmLocatorSymbol_fn_t)(graal_isolatethread_t* thread);
46-
4745
#if defined(__cplusplus)
4846
}
4947
#endif

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

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -568,9 +568,9 @@ public static Executable[] getMethodMetadata(int typeID) {
568568

569569
int modifiers = dataReader.getUVInt();
570570

571-
int paramCount = dataReader.getUVInt();
572-
Class<?>[] paramTypes = new Class<?>[paramCount];
573-
for (int j = 0; j < paramCount; ++j) {
571+
int paramTypeCount = dataReader.getUVInt();
572+
Class<?>[] paramTypes = new Class<?>[paramTypeCount];
573+
for (int j = 0; j < paramTypeCount; ++j) {
574574
int paramTypeIndex = dataReader.getSVInt();
575575
paramTypes[j] = NonmovableArrays.getObject(CodeInfoAccess.getFrameInfoSourceClasses(info), paramTypeIndex);
576576
}
@@ -606,27 +606,27 @@ public static Executable[] getMethodMetadata(int typeID) {
606606
typeAnnotations[j] = (byte) dataReader.getS1();
607607
}
608608

609-
boolean parameterDataPresent = dataReader.getU1() == 1;
610-
String[] parameterNames = null;
611-
int[] parameterModifiers = null;
612-
if (parameterDataPresent) {
613-
int parameterCount = dataReader.getUVInt();
614-
parameterNames = new String[parameterCount];
615-
parameterModifiers = new int[parameterCount];
616-
for (int j = 0; j < paramCount; ++j) {
617-
int parameterNameIndex = dataReader.getSVInt();
618-
parameterNames[j] = NonmovableArrays.getObject(CodeInfoAccess.getFrameInfoSourceMethodNames(info), parameterNameIndex);
619-
parameterModifiers[j] = dataReader.getS4();
609+
boolean reflectParameterDataPresent = dataReader.getU1() == 1;
610+
String[] reflectParameterNames = null;
611+
int[] reflectParameterModifiers = null;
612+
if (reflectParameterDataPresent) {
613+
int reflectParameterCount = dataReader.getUVInt();
614+
reflectParameterNames = new String[reflectParameterCount];
615+
reflectParameterModifiers = new int[reflectParameterCount];
616+
for (int j = 0; j < reflectParameterCount; ++j) {
617+
int reflectParameterNameIndex = dataReader.getSVInt();
618+
reflectParameterNames[j] = NonmovableArrays.getObject(CodeInfoAccess.getFrameInfoSourceMethodNames(info), reflectParameterNameIndex);
619+
reflectParameterModifiers[j] = dataReader.getS4();
620620
}
621621
}
622622

623623
if (name.equals("<init>")) {
624624
assert returnType == void.class;
625625
methods[i] = ImageSingletons.lookup(RuntimeReflectionConstructors.class).newConstructor(declaringClass, paramTypes, exceptionTypes, modifiers, signature,
626-
annotations, parameterAnnotations, typeAnnotations, parameterNames, parameterModifiers);
626+
annotations, parameterAnnotations, typeAnnotations, reflectParameterNames, reflectParameterModifiers);
627627
} else {
628628
methods[i] = ImageSingletons.lookup(RuntimeReflectionConstructors.class).newMethod(declaringClass, name, paramTypes, returnType, exceptionTypes, modifiers, signature,
629-
annotations, parameterAnnotations, null, typeAnnotations, parameterNames, parameterModifiers);
629+
annotations, parameterAnnotations, null, typeAnnotations, reflectParameterNames, reflectParameterModifiers);
630630
}
631631
}
632632
return methods;

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

Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
import java.util.Set;
4545
import java.util.TreeMap;
4646

47+
import org.graalvm.collections.Pair;
4748
import org.graalvm.compiler.core.common.util.TypeConversion;
4849
import org.graalvm.compiler.core.common.util.UnsafeArrayTypeWriter;
4950
import org.graalvm.nativeimage.ImageSingletons;
@@ -57,6 +58,7 @@
5758
import com.oracle.svm.core.util.ByteArrayReader;
5859
import com.oracle.svm.util.ReflectionUtil;
5960

61+
import jdk.vm.ci.meta.JavaType;
6062
import sun.invoke.util.Wrapper;
6163
import sun.reflect.annotation.AnnotationType;
6264
import sun.reflect.annotation.TypeAnnotation;
@@ -67,7 +69,7 @@ public class MethodMetadataEncoder {
6769
public static final int NO_METHOD_METADATA = -1;
6870

6971
private CodeInfoEncoder.Encoders encoders;
70-
private TreeMap<SharedType, Set<Executable>> methodData;
72+
private TreeMap<SharedType, Set<Pair<SharedMethod, Executable>>> methodData;
7173

7274
private byte[] methodDataEncoding;
7375
private byte[] methodDataIndexEncoding;
@@ -111,7 +113,7 @@ public void prepareMetadataForMethod(SharedMethod method, Executable reflectMeth
111113
}
112114

113115
/* Register string values in annotations */
114-
registerStrings(GuardedAnnotationAccess.getDeclaredAnnotations(reflectMethod));
116+
registerStrings(GuardedAnnotationAccess.getDeclaredAnnotations(method));
115117
for (Annotation[] annotations : reflectMethod.getParameterAnnotations()) {
116118
registerStrings(annotations);
117119
}
@@ -126,7 +128,7 @@ public void prepareMetadataForMethod(SharedMethod method, Executable reflectMeth
126128
}
127129

128130
SharedType declaringType = (SharedType) method.getDeclaringClass();
129-
methodData.computeIfAbsent(declaringType, t -> new HashSet<>()).add(reflectMethod);
131+
methodData.computeIfAbsent(declaringType, t -> new HashSet<>()).add(Pair.create(method, reflectMethod));
130132
}
131133

132134
private static final Method hasRealParameterData = ReflectionUtil.lookupMethod(Executable.class, "hasRealParameterData");
@@ -135,9 +137,9 @@ private void encodeMethodMetadata() {
135137
UnsafeArrayTypeWriter dataEncodingBuffer = UnsafeArrayTypeWriter.create(ByteArrayReader.supportsUnalignedMemoryAccess());
136138
UnsafeArrayTypeWriter indexEncodingBuffer = UnsafeArrayTypeWriter.create(ByteArrayReader.supportsUnalignedMemoryAccess());
137139
long lastTypeID = -1;
138-
for (Map.Entry<SharedType, Set<Executable>> entry : methodData.entrySet()) {
140+
for (Map.Entry<SharedType, Set<Pair<SharedMethod, Executable>>> entry : methodData.entrySet()) {
139141
SharedType declaringType = entry.getKey();
140-
Set<Executable> methods = entry.getValue();
142+
Set<Pair<SharedMethod, Executable>> methods = entry.getValue();
141143
long typeID = declaringType.getHub().getTypeID();
142144
assert typeID > lastTypeID;
143145
lastTypeID++;
@@ -148,62 +150,70 @@ private void encodeMethodMetadata() {
148150
long index = dataEncodingBuffer.getBytesWritten();
149151
indexEncodingBuffer.putS4(index);
150152
dataEncodingBuffer.putUV(methods.size());
151-
for (Executable method : methods) {
152-
Class<?> declaringClass = method.getDeclaringClass();
153+
for (Pair<SharedMethod, Executable> method : methods) {
154+
SharedMethod hostedMethod = method.getLeft();
155+
Executable reflectMethod = method.getRight();
156+
157+
Class<?> declaringClass = getJavaClass((SharedType) hostedMethod.getDeclaringClass());
153158
final int classIndex = encoders.sourceClasses.getIndex(declaringClass);
154159
dataEncodingBuffer.putSV(classIndex);
155160

156-
String name = method instanceof Constructor<?> ? "<init>" : ((Method) method).getName();
161+
String name = hostedMethod.isConstructor() ? "<init>" : hostedMethod.getName();
157162
final int nameIndex = encoders.sourceMethodNames.getIndex(name);
158163
dataEncodingBuffer.putSV(nameIndex);
159164

160-
dataEncodingBuffer.putUV(method.getModifiers());
165+
dataEncodingBuffer.putUV(reflectMethod.getModifiers());
161166

162-
Class<?>[] parameterTypes = method.getParameterTypes();
167+
/* Parameter types do not include the receiver */
168+
JavaType[] parameterTypes = hostedMethod.getSignature().toParameterTypes(null);
163169
dataEncodingBuffer.putUV(parameterTypes.length);
164-
for (Class<?> parameterType : parameterTypes) {
165-
final int paramClassIndex = encoders.sourceClasses.getIndex(parameterType);
170+
for (JavaType parameterType : parameterTypes) {
171+
Class<?> parameterClass = getJavaClass((SharedType) parameterType);
172+
final int paramClassIndex = encoders.sourceClasses.getIndex(parameterClass);
166173
dataEncodingBuffer.putSV(paramClassIndex);
167174
}
168175

169-
Class<?> returnType = method instanceof Constructor<?> ? void.class : ((Method) method).getReturnType();
176+
Class<?> returnType = void.class;
177+
if (!hostedMethod.isConstructor()) {
178+
returnType = getJavaClass((SharedType) hostedMethod.getSignature().getReturnType(null));
179+
}
170180
final int returnTypeIndex = encoders.sourceClasses.getIndex(returnType);
171181
dataEncodingBuffer.putSV(returnTypeIndex);
172182

173183
/* Only include types that are in the image (i.e. that can actually be thrown) */
174-
Class<?>[] exceptionTypes = filterTypes(method.getExceptionTypes());
184+
Class<?>[] exceptionTypes = filterTypes(reflectMethod.getExceptionTypes());
175185
dataEncodingBuffer.putUV(exceptionTypes.length);
176186
for (Class<?> exceptionClazz : exceptionTypes) {
177187
final int exceptionClassIndex = encoders.sourceClasses.getIndex(exceptionClazz);
178188
dataEncodingBuffer.putSV(exceptionClassIndex);
179189
}
180190

181-
final int signatureIndex = encoders.sourceMethodNames.getIndex(getSignature(method));
191+
final int signatureIndex = encoders.sourceMethodNames.getIndex(getSignature(reflectMethod));
182192
dataEncodingBuffer.putSV(signatureIndex);
183193

184194
try {
185-
byte[] annotations = encodeAnnotations(GuardedAnnotationAccess.getDeclaredAnnotations(method));
195+
byte[] annotations = encodeAnnotations(GuardedAnnotationAccess.getDeclaredAnnotations(hostedMethod));
186196
dataEncodingBuffer.putUV(annotations.length);
187197
for (byte b : annotations) {
188198
dataEncodingBuffer.putS1(b);
189199
}
190200

191-
byte[] parameterAnnotations = encodeParameterAnnotations(method.getParameterAnnotations());
201+
byte[] parameterAnnotations = encodeParameterAnnotations(reflectMethod.getParameterAnnotations());
192202
dataEncodingBuffer.putUV(parameterAnnotations.length);
193203
for (byte b : parameterAnnotations) {
194204
dataEncodingBuffer.putS1(b);
195205
}
196206

197-
byte[] typeAnnotations = encodeTypeAnnotations((TypeAnnotation[]) parseAllTypeAnnotations.invoke(null, method));
207+
byte[] typeAnnotations = encodeTypeAnnotations((TypeAnnotation[]) parseAllTypeAnnotations.invoke(null, reflectMethod));
198208
dataEncodingBuffer.putUV(typeAnnotations.length);
199209
for (byte b : typeAnnotations) {
200210
dataEncodingBuffer.putS1(b);
201211
}
202212

203-
boolean parameterDataPresent = (boolean) hasRealParameterData.invoke(method);
213+
boolean parameterDataPresent = (boolean) hasRealParameterData.invoke(reflectMethod);
204214
dataEncodingBuffer.putU1(parameterDataPresent ? 1 : 0);
205215
if (parameterDataPresent) {
206-
Parameter[] parameters = method.getParameters();
216+
Parameter[] parameters = reflectMethod.getParameters();
207217
dataEncodingBuffer.putUV(parameters.length);
208218
for (Parameter parameter : parameters) {
209219
final int parameterNameIndex = encoders.sourceMethodNames.getIndex(parameter.getName());
@@ -226,6 +236,10 @@ private void encodeMethodMetadata() {
226236
indexEncodingBuffer.toArray(methodDataIndexEncoding);
227237
}
228238

239+
private static Class<?> getJavaClass(SharedType sharedType) {
240+
return sharedType.getHub().getHostedJavaClass();
241+
}
242+
229243
private Class<?>[] filterTypes(Class<?>[] types) {
230244
List<Class<?>> filteredTypes = new ArrayList<>();
231245
for (Class<?> type : types) {

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/reflect/RuntimeReflectionConstructors.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ Method newMethod(Class<?> declaringClass,
4141
byte[] parameterAnnotations,
4242
byte[] annotationDefault,
4343
byte[] typeAnnotations,
44-
String[] parameterNames,
45-
int[] parameterModifiers);
44+
String[] reflectParameterNames,
45+
int[] reflectParameterModifiers);
4646

4747
Constructor<?> newConstructor(Class<?> declaringClass,
4848
Class<?>[] parameterTypes,
@@ -52,6 +52,6 @@ Constructor<?> newConstructor(Class<?> declaringClass,
5252
byte[] annotations,
5353
byte[] parameterAnnotations,
5454
byte[] typeAnnotations,
55-
String[] parameterNames,
56-
int[] parameterModifiers);
55+
String[] reflectParameterNames,
56+
int[] reflectParameterModifiers);
5757
}

substratevm/src/com.oracle.svm.reflect/src/com/oracle/svm/reflect/hosted/ReflectionDataBuilder.java

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -231,12 +231,10 @@ private void processReachableTypes(DuringAnalysisAccessImpl access) {
231231

232232
protected void processMethodMetadata(DuringAnalysisAccessImpl access) {
233233
if (SubstrateOptions.ConfigureReflectionMetadata.getValue()) {
234-
/* Trigger creation of the AnalysisMethod objects needed to store metadata */
235234
Set<Executable> newQueriedMethods = new HashSet<>();
236235
for (Executable method : queriedMethods) {
237236
if (!SubstitutionReflectivityFilter.shouldExclude(method, access.getMetaAccess(), access.getUniverse())) {
238-
access.getMetaAccess().lookupJavaMethod(method);
239-
registerMetadataForReflection(access, method);
237+
registerMetadataForReflection(access, access.getMetaAccess().lookupJavaMethod(method), method);
240238
newQueriedMethods.add(method);
241239
}
242240
}
@@ -248,26 +246,26 @@ protected void processMethodMetadata(DuringAnalysisAccessImpl access) {
248246
* method.
249247
*/
250248
if (method.isReachable() && method.hasJavaMethod()) {
251-
registerMetadataForReflection(access, method.getJavaMethod());
249+
registerMetadataForReflection(access, method, method.getJavaMethod());
252250
}
253251
}
254252
}
255253
}
256254

257255
private static final Method parseAllTypeAnnotations = ReflectionUtil.lookupMethod(TypeAnnotationParser.class, "parseAllTypeAnnotations", AnnotatedElement.class);
258256

259-
private void registerMetadataForReflection(DuringAnalysisAccessImpl access, Executable reflectMethod) {
257+
private void registerMetadataForReflection(DuringAnalysisAccessImpl access, AnalysisMethod analysisMethod, Executable reflectMethod) {
260258
/*
261259
* Reflection signature parsing will try to instantiate classes via Class.forName().
262260
*/
263-
makeTypeReachable(access, reflectMethod.getDeclaringClass(), false);
261+
makeTypeReachable(access, analysisMethod.getDeclaringClass().getJavaClass(), false);
264262
for (TypeVariable<?> type : reflectMethod.getTypeParameters()) {
265263
makeTypeReachable(access, type, true);
266264
}
267-
for (Type paramType : reflectMethod.getGenericParameterTypes()) {
265+
for (Type paramType : analysisMethod.getGenericParameterTypes()) {
268266
makeTypeReachable(access, paramType, true);
269267
}
270-
if (reflectMethod instanceof Method) {
268+
if (!analysisMethod.isConstructor()) {
271269
makeTypeReachable(access, ((Method) reflectMethod).getGenericReturnType(), true);
272270
}
273271
for (Type exceptionType : reflectMethod.getGenericExceptionTypes()) {
@@ -277,7 +275,7 @@ private void registerMetadataForReflection(DuringAnalysisAccessImpl access, Exec
277275
/*
278276
* Enable runtime parsing of annotations
279277
*/
280-
for (Annotation annotation : GuardedAnnotationAccess.getDeclaredAnnotations(reflectMethod)) {
278+
for (Annotation annotation : GuardedAnnotationAccess.getDeclaredAnnotations(analysisMethod)) {
281279
makeTypeReachable(access, annotation.annotationType(), false);
282280
}
283281
for (Annotation[] parameterAnnotations : reflectMethod.getParameterAnnotations()) {
@@ -304,7 +302,7 @@ private void makeTypeReachable(DuringAnalysisAccessImpl access, Type type, boole
304302
return;
305303
}
306304
seenTypes.add(type);
307-
if (type instanceof Class<?>) {
305+
if (type instanceof Class<?> && !SubstitutionReflectivityFilter.shouldExclude((Class<?>) type, access.getMetaAccess(), access.getUniverse())) {
308306
Class<?> clazz = (Class<?>) type;
309307
if (access.getMetaAccess().lookupJavaType(clazz).registerAsReachable()) {
310308
access.requireAnalysisIteration();

0 commit comments

Comments
 (0)