diff --git a/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/c/function/CFunctionPointer.java b/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/c/function/CFunctionPointer.java index 57b27294179a..35ef2117b098 100644 --- a/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/c/function/CFunctionPointer.java +++ b/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/c/function/CFunctionPointer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, 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 diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/meta/AnalysisMethod.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/meta/AnalysisMethod.java index 61f4567aebe6..5f6d80dfcd08 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/meta/AnalysisMethod.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/meta/AnalysisMethod.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -119,6 +119,8 @@ public abstract class AnalysisMethod extends AnalysisElement implements WrappedJ private static final AtomicReferenceFieldUpdater reachableInCurrentLayerUpdater = AtomicReferenceFieldUpdater .newUpdater(AnalysisMethod.class, Boolean.class, "reachableInCurrentLayer"); + public static final AnalysisMethod[] EMPTY_ARRAY = new AnalysisMethod[0]; + public record Signature(String name, AnalysisType[] parameterTypes) { } diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/meta/AnalysisType.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/meta/AnalysisType.java index 33bec09f8d62..ad8ea80cd485 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/meta/AnalysisType.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/meta/AnalysisType.java @@ -115,6 +115,8 @@ public abstract class AnalysisType extends AnalysisElement implements WrappedJav private static final AtomicReferenceFieldUpdater RESOLVED_METHODS_UPDATER = AtomicReferenceFieldUpdater.newUpdater(AnalysisType.class, Object.class, "resolvedMethods"); + public static final AnalysisType[] EMPTY_ARRAY = new AnalysisType[0]; + protected final AnalysisUniverse universe; private final ResolvedJavaType wrapped; private final String qualifiedName; @@ -360,7 +362,7 @@ private AnalysisType[] convertTypes(ResolvedJavaType[] originalTypes) { } result.add(universe.lookup(originalType)); } - return result.toArray(new AnalysisType[result.size()]); + return result.toArray(AnalysisType.EMPTY_ARRAY); } public AnalysisType getArrayClass(int dim) { diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/meta/AnalysisUniverse.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/meta/AnalysisUniverse.java index f5350fda5620..cf08d82dacca 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/meta/AnalysisUniverse.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/meta/AnalysisUniverse.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -471,7 +471,7 @@ public AnalysisMethod[] lookup(JavaMethod[] inputs) { } } } - return result.toArray(new AnalysisMethod[result.size()]); + return result.toArray(AnalysisMethod.EMPTY_ARRAY); } @Override diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/CodeBreakdownProvider.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/CodeBreakdownProvider.java index 8497ff04d50c..06f978b845b9 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/CodeBreakdownProvider.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/CodeBreakdownProvider.java @@ -36,7 +36,7 @@ import com.oracle.svm.hosted.meta.HostedMethod; class CodeBreakdownProvider { - private final Map codeBreakdown; + private Map codeBreakdown; CodeBreakdownProvider(Collection compilationTasks) { Map nameToSizeMap = new HashMap<>(); @@ -60,8 +60,17 @@ class CodeBreakdownProvider { codeBreakdown = Collections.unmodifiableMap(nameToSizeMap); } - public static Map get() { - return ImageSingletons.lookup(CodeBreakdownProvider.class).codeBreakdown; + /** + * Provides the code breakdown as map from name to size, and clears the cache to avoid memory + * footprint. + * + * @return the code breakdown + */ + public static Map getAndClear() { + CodeBreakdownProvider singleton = ImageSingletons.lookup(CodeBreakdownProvider.class); + Map map = singleton.codeBreakdown; + singleton.codeBreakdown = null; + return map; } private static String findJARFile(Class javaClass) { diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ProgressReporter.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ProgressReporter.java index d17651603c89..c8e5304afbd8 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ProgressReporter.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ProgressReporter.java @@ -641,7 +641,7 @@ private void printBreakdowns() { return; } l().printLineSeparator(); - Map codeBreakdown = CodeBreakdownProvider.get(); + Map codeBreakdown = CodeBreakdownProvider.getAndClear(); Iterator> packagesBySize = codeBreakdown.entrySet().stream() .sorted(Entry.comparingByValue(Comparator.reverseOrder())).iterator(); diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/annotation/SubstrateAnnotationExtractor.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/annotation/SubstrateAnnotationExtractor.java index 349bcf22fa06..fcef1e995250 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/annotation/SubstrateAnnotationExtractor.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/annotation/SubstrateAnnotationExtractor.java @@ -279,6 +279,9 @@ private AnnotationValue[][] getParameterAnnotationDataFromRoot(Executable rootEl ByteBuffer buf = ByteBuffer.wrap(rawParameterAnnotations); try { int numParameters = buf.get() & 0xFF; + if (numParameters == 0) { + return NO_PARAMETER_ANNOTATIONS; + } AnnotationValue[][] parameterAnnotations = new AnnotationValue[numParameters][]; for (int i = 0; i < numParameters; i++) { List parameterAnnotationList = new ArrayList<>(); diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/CEntryPointData.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/CEntryPointData.java index 23e41a1fcd6f..6c0c54d7f75b 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/CEntryPointData.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/CEntryPointData.java @@ -91,7 +91,7 @@ public static CEntryPointData createCustomUnpublished() { private static CEntryPointData create(CEntryPoint annotation, CEntryPointOptions options, Supplier alternativeNameSupplier) { String annotatedName = annotation.name(); Class> nameTransformation = DEFAULT_NAME_TRANSFORMATION; - String documentation = String.join(System.lineSeparator(), annotation.documentation()); + String documentation = annotation.documentation().length == 0 ? "" : String.join(System.lineSeparator(), annotation.documentation()); CEntryPoint.Builtin builtin = annotation.builtin(); Class prologue = DEFAULT_PROLOGUE; Class prologueBailout = DEFAULT_PROLOGUE_BAILOUT; diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/RestrictHeapAccessCalleesImpl.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/RestrictHeapAccessCalleesImpl.java index ad0691e4b2b3..6ee83be3ce5f 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/RestrictHeapAccessCalleesImpl.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/RestrictHeapAccessCalleesImpl.java @@ -114,7 +114,7 @@ public void aggregateMethods(Collection methods) { } MethodAggregator visitor = new MethodAggregator(aggregation, assertionErrorConstructorList); AnalysisMethodCalleeWalker walker = new AnalysisMethodCalleeWalker(); - for (AnalysisMethod method : aggregation.keySet().toArray(new AnalysisMethod[0])) { + for (AnalysisMethod method : aggregation.keySet().toArray(AnalysisMethod.EMPTY_ARRAY)) { walker.walkMethod(method, visitor); } calleeToCallerMap = Collections.unmodifiableMap(aggregation); diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/RuntimeMetadataEncoderImpl.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/RuntimeMetadataEncoderImpl.java index 94c407a6b367..e0e2d84601ea 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/RuntimeMetadataEncoderImpl.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/RuntimeMetadataEncoderImpl.java @@ -720,7 +720,8 @@ public void addRecordComponentsLookupError(HostedType declaringClass, Throwable } private static HostedType[] getParameterTypes(HostedMethod method) { - HostedType[] parameterTypes = new HostedType[method.getSignature().getParameterCount(false)]; + int len = method.getSignature().getParameterCount(false); + HostedType[] parameterTypes = len == 0 ? HostedType.EMPTY_ARRAY : new HostedType[len]; for (int i = 0; i < parameterTypes.length; ++i) { parameterTypes[i] = method.getSignature().getParameterType(i); } @@ -737,7 +738,7 @@ private static String[] getParameterTypeNames(HostedMethod method) { private static HostedType[] getExceptionTypes(MetaAccessProvider metaAccess, Executable reflectMethod) { Class[] exceptionClasses = reflectMethod.getExceptionTypes(); - HostedType[] exceptionTypes = new HostedType[exceptionClasses.length]; + HostedType[] exceptionTypes = exceptionClasses.length == 0 ? HostedType.EMPTY_ARRAY : new HostedType[exceptionClasses.length]; for (int i = 0; i < exceptionClasses.length; ++i) { exceptionTypes[i] = (HostedType) metaAccess.lookupJavaType(exceptionClasses[i]); } diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageHeapWriter.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageHeapWriter.java index e88cc998339d..22872c39940c 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageHeapWriter.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageHeapWriter.java @@ -104,7 +104,7 @@ public NativeImageHeapWriter(NativeImageHeap heap, ImageHeapLayoutInfo heapLayou public long writeHeap(DebugContext debug, RelocatableBuffer buffer) { try (Indent perHeapIndent = debug.logAndIndent("NativeImageHeap.writeHeap:")) { for (ObjectInfo info : heap.getObjects()) { - assert !heap.isBlacklisted(info.getObject()); + assert !heap.isBlacklisted(info.getObject()) : "Backlisted object: " + info.getObject(); if (info.getConstant().isWrittenInPreviousLayer()) { /* * Base layer constants already written in the base layer heap are only added to diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/meta/HostedArrayClass.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/meta/HostedArrayClass.java index 161491015ac0..011991d34145 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/meta/HostedArrayClass.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/meta/HostedArrayClass.java @@ -81,7 +81,7 @@ public int getArrayDimension() { @Override public HostedField[] getInstanceFields(boolean includeSuperclasses) { - return new HostedField[0]; + return HostedField.EMPTY_ARRAY; } @Override diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/meta/HostedField.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/meta/HostedField.java index e424b1f536b3..1f53ac0c42a5 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/meta/HostedField.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/meta/HostedField.java @@ -43,6 +43,10 @@ */ public class HostedField extends HostedElement implements OriginalFieldProvider, SharedField, WrappedJavaField { + static final int LOC_UNMATERIALIZED_STATIC_CONSTANT = -10; + + public static final HostedField[] EMPTY_ARRAY = new HostedField[0]; + public final AnalysisField wrapped; private final HostedType holder; @@ -51,8 +55,6 @@ public class HostedField extends HostedElement implements OriginalFieldProvider, protected int location; private int installedLayerNum; - static final int LOC_UNMATERIALIZED_STATIC_CONSTANT = -10; - public HostedField(AnalysisField wrapped, HostedType holder, HostedType type) { this.wrapped = wrapped; this.holder = holder; diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/meta/HostedInterface.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/meta/HostedInterface.java index 0147510fc8b0..3ac6d0f87c05 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/meta/HostedInterface.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/meta/HostedInterface.java @@ -36,6 +36,8 @@ */ public class HostedInterface extends HostedType { + public static final HostedInterface[] EMPTY_ARRAY = new HostedInterface[0]; + public HostedInterface(HostedUniverse universe, AnalysisType wrapped, JavaKind kind, JavaKind storageKind, HostedInterface[] interfaces) { super(universe, wrapped, kind, storageKind, null, interfaces); } @@ -87,6 +89,6 @@ public int getArrayDimension() { @Override public HostedField[] getInstanceFields(boolean includeSuperclasses) { - return new HostedField[0]; + return HostedField.EMPTY_ARRAY; } } diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/meta/HostedPrimitiveType.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/meta/HostedPrimitiveType.java index 096df6b96ff9..690bc721e8fa 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/meta/HostedPrimitiveType.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/meta/HostedPrimitiveType.java @@ -31,7 +31,7 @@ public class HostedPrimitiveType extends HostedType { public HostedPrimitiveType(HostedUniverse universe, AnalysisType wrapped, JavaKind kind, JavaKind storageKind) { - super(universe, wrapped, kind, storageKind, null, new HostedInterface[0]); + super(universe, wrapped, kind, storageKind, null, HostedInterface.EMPTY_ARRAY); } @Override @@ -81,7 +81,7 @@ public int getArrayDimension() { @Override public HostedField[] getInstanceFields(boolean includeSuperclasses) { - return new HostedField[0]; + return HostedField.EMPTY_ARRAY; } @Override diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/meta/HostedUniverse.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/meta/HostedUniverse.java index ade7c8c7cbe1..b5ae3b400ed1 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/meta/HostedUniverse.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/meta/HostedUniverse.java @@ -355,7 +355,7 @@ public HostedType optionalLookup(JavaType type) { } public HostedType[] optionalLookup(JavaType... javaTypes) { - HostedType[] result = new HostedType[javaTypes.length]; + HostedType[] result = new HostedType[javaTypes.length]; // EMPTY_ARRAY failing here for (int i = 0; i < javaTypes.length; ++i) { result[i] = optionalLookup(javaTypes[i]); if (result[i] == null) { @@ -421,7 +421,7 @@ public HostedMethod optionalLookup(JavaMethod method) { } public HostedMethod[] lookup(JavaMethod[] inputs) { - HostedMethod[] result = new HostedMethod[inputs.length]; + HostedMethod[] result = new HostedMethod[inputs.length]; // EMPTY_ARRAY failing here for (int i = 0; i < result.length; i++) { result[i] = lookup(inputs[i]); } diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/meta/UniverseBuilder.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/meta/UniverseBuilder.java index d5513b9c3c87..6268516f4d4f 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/meta/UniverseBuilder.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/meta/UniverseBuilder.java @@ -45,6 +45,8 @@ import java.util.stream.Collectors; import org.graalvm.nativeimage.ImageInfo; +import org.graalvm.nativeimage.Platform; +import org.graalvm.nativeimage.Platforms; import org.graalvm.nativeimage.c.function.CEntryPointLiteral; import org.graalvm.nativeimage.c.function.CFunction; import org.graalvm.nativeimage.c.function.CFunctionPointer; @@ -119,6 +121,7 @@ public class UniverseBuilder { + @Platforms(Platform.HOSTED_ONLY.class) private static final CFunctionPointer[] EMPTY_ARRAY = new CFunctionPointer[0]; private final AnalysisUniverse aUniverse; private final AnalysisMetaAccess aMetaAccess; private final HostedUniverse hUniverse; @@ -227,7 +230,7 @@ private HostedType makeType(AnalysisType aType) { assert !typeName.contains("/hosted/meta/") : "Hosted meta object in image " + typeName; AnalysisType[] aInterfaces = aType.getInterfaces(); - HostedInterface[] sInterfaces = new HostedInterface[aInterfaces.length]; + HostedInterface[] sInterfaces = aInterfaces.length == 0 ? HostedInterface.EMPTY_ARRAY : new HostedInterface[aInterfaces.length]; for (int i = 0; i < aInterfaces.length; i++) { sInterfaces[i] = (HostedInterface) makeType(aInterfaces[i]); } @@ -469,7 +472,7 @@ public static boolean isKnownImmutableType(Class clazz) { private void layoutInstanceFields(int numTypeCheckSlots) { BitSet usedBytes = new BitSet(); usedBytes.set(0, ConfigurationValues.getObjectLayout().getFirstFieldOffset()); - layoutInstanceFields(hUniverse.getObjectClass(), new HostedField[0], usedBytes, numTypeCheckSlots); + layoutInstanceFields(hUniverse.getObjectClass(), HostedField.EMPTY_ARRAY, usedBytes, numTypeCheckSlots); } private static boolean mustReserveArrayFields(HostedInstanceClass clazz) { @@ -640,7 +643,7 @@ private void layoutInstanceFields(HostedInstanceClass clazz, HostedField[] super clazz.setIdentityHashOffset(offset); } - clazz.instanceFieldsWithoutSuper = allFields.toArray(new HostedField[0]); + clazz.instanceFieldsWithoutSuper = allFields.toArray(HostedField.EMPTY_ARRAY); clazz.firstInstanceFieldOffset = firstInstanceFieldOffset; clazz.afterFieldsOffset = afterFieldsOffset; clazz.instanceSize = layout.alignUp(afterFieldsOffset); @@ -840,13 +843,12 @@ private void layoutStaticFields() { fieldsOfTypes[typeId].add(field); } - HostedField[] noFields = new HostedField[0]; for (HostedType type : hUniverse.getTypes()) { List fieldsOfType = fieldsOfTypes[type.getTypeID()]; if (fieldsOfType != null) { type.staticFields = fieldsOfType.toArray(new HostedField[fieldsOfType.size()]); } else { - type.staticFields = noFields; + type.staticFields = HostedField.EMPTY_ARRAY; } } @@ -886,7 +888,7 @@ private void collectMethodImplementations() { for (HostedMethod method : hUniverse.methods.values()) { // Reuse the implementations from the analysis method. - method.implementations = hUniverse.lookup(method.wrapped.collectMethodImplementations(false).toArray(new AnalysisMethod[0])); + method.implementations = hUniverse.lookup(method.wrapped.collectMethodImplementations(false).toArray(AnalysisMethod.EMPTY_ARRAY)); Arrays.sort(method.implementations, HostedUniverse.METHOD_COMPARATOR); } } @@ -955,7 +957,7 @@ private void buildHubs() { hub.setSharedData(layoutHelper, monitorOffset, identityHashOffset, referenceMapIndex, type.isInstantiated()); if (SubstrateOptions.useClosedTypeWorldHubLayout()) { - CFunctionPointer[] vtable = new CFunctionPointer[type.closedTypeWorldVTable.length]; + CFunctionPointer[] vtable = type.closedTypeWorldVTable.length == 0 ? EMPTY_ARRAY : new CFunctionPointer[type.closedTypeWorldVTable.length]; for (int idx = 0; idx < type.closedTypeWorldVTable.length; idx++) { /* * We install a CodePointer in the vtable; when generating relocation info, we @@ -994,7 +996,7 @@ private void buildHubs() { typeSlotIdx += 2; } - CFunctionPointer[] vtable = new CFunctionPointer[type.openTypeWorldDispatchTables.length]; + CFunctionPointer[] vtable = type.openTypeWorldDispatchTables.length == 0 ? EMPTY_ARRAY : new CFunctionPointer[type.openTypeWorldDispatchTables.length]; for (int idx = 0; idx < type.openTypeWorldDispatchTables.length; idx++) { /* * We install a CodePointer in the open world vtable; when generating relocation diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/meta/VTableBuilder.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/meta/VTableBuilder.java index e31c6b376059..73572cdf63f6 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/meta/VTableBuilder.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/meta/VTableBuilder.java @@ -430,8 +430,8 @@ private void buildClosedTypeWorldVTables() { if (type.isArray()) { type.closedTypeWorldVTable = objectClass.closedTypeWorldVTable; } - if (type.closedTypeWorldVTable == null) { - assert type.isInterface() || type.isPrimitive(); + if (type.closedTypeWorldVTable == null || type.closedTypeWorldVTable.length == 0) { + assert type.isInterface() || type.isPrimitive() || type.closedTypeWorldVTable.length == 0; type.closedTypeWorldVTable = HostedMethod.EMPTY_ARRAY; } diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/reflect/ReflectionDataBuilder.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/reflect/ReflectionDataBuilder.java index 204208ab871c..140b483d205d 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/reflect/ReflectionDataBuilder.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/reflect/ReflectionDataBuilder.java @@ -965,7 +965,7 @@ private void registerTypesForAnnotations(AnnotatedElement annotatedElement) { registerTypesForAnnotation(annotation); } } - filteredAnnotations.put(annotatedElement, includedAnnotations.toArray(new AnnotationValue[0])); + filteredAnnotations.put(annotatedElement, includedAnnotations.toArray(NO_ANNOTATIONS)); } } } @@ -974,7 +974,7 @@ private void registerTypesForParameterAnnotations(AnalysisMethod method) { if (method != null) { if (!filteredParameterAnnotations.containsKey(method)) { AnnotationValue[][] parameterAnnotations = annotationExtractor.getParameterAnnotationData(method); - AnnotationValue[][] includedParameterAnnotations = new AnnotationValue[parameterAnnotations.length][]; + AnnotationValue[][] includedParameterAnnotations = parameterAnnotations.length == 0 ? NO_PARAMETER_ANNOTATIONS : new AnnotationValue[parameterAnnotations.length][]; for (int i = 0; i < includedParameterAnnotations.length; ++i) { AnnotationValue[] annotations = parameterAnnotations[i]; List includedAnnotations = new ArrayList<>(); @@ -984,7 +984,7 @@ private void registerTypesForParameterAnnotations(AnalysisMethod method) { registerTypesForAnnotation(annotation); } } - includedParameterAnnotations[i] = includedAnnotations.toArray(new AnnotationValue[0]); + includedParameterAnnotations[i] = includedAnnotations.toArray(NO_ANNOTATIONS); } filteredParameterAnnotations.put(method, includedParameterAnnotations); } @@ -1001,7 +1001,7 @@ private void registerTypesForTypeAnnotations(AnnotatedElement annotatedElement) registerTypesForAnnotation(typeAnnotation.getAnnotationData()); } } - filteredTypeAnnotations.put(annotatedElement, includedTypeAnnotations.toArray(new TypeAnnotationValue[0])); + filteredTypeAnnotations.put(annotatedElement, includedTypeAnnotations.toArray(NO_TYPE_ANNOTATIONS)); } } }