diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/PointsToAnalysis.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/PointsToAnalysis.java index 86ee885065c0..4889e621ce3c 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/PointsToAnalysis.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/PointsToAnalysis.java @@ -56,7 +56,6 @@ import com.oracle.graal.pointsto.flow.OffsetLoadTypeFlow.AbstractUnsafeLoadTypeFlow; import com.oracle.graal.pointsto.flow.OffsetStoreTypeFlow.AbstractUnsafeStoreTypeFlow; import com.oracle.graal.pointsto.flow.TypeFlow; -import com.oracle.graal.pointsto.infrastructure.WrappedSignature; import com.oracle.graal.pointsto.meta.AnalysisField; import com.oracle.graal.pointsto.meta.AnalysisMetaAccess; import com.oracle.graal.pointsto.meta.AnalysisMethod; @@ -88,6 +87,7 @@ import jdk.vm.ci.meta.JavaKind; import jdk.vm.ci.meta.JavaType; import jdk.vm.ci.meta.ResolvedJavaField; +import jdk.vm.ci.meta.Signature; public abstract class PointsToAnalysis extends AbstractAnalysisEngine { /** The type of {@link java.lang.Object}. */ @@ -323,7 +323,7 @@ public AnalysisMethod addRootMethod(AnalysisMethod aMethod, boolean invokeSpecia AnalysisError.guarantee(aMethod.isOriginalMethod()); AnalysisType declaringClass = aMethod.getDeclaringClass(); boolean isStatic = aMethod.isStatic(); - WrappedSignature signature = aMethod.getSignature(); + Signature signature = aMethod.getSignature(); int paramCount = signature.getParameterCount(!isStatic); PointsToAnalysisMethod originalPTAMethod = assertPointsToAnalysisMethod(aMethod); diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/infrastructure/ResolvedSignature.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/infrastructure/ResolvedSignature.java new file mode 100644 index 000000000000..173ef1962207 --- /dev/null +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/infrastructure/ResolvedSignature.java @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2023, 2023, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.pointsto.infrastructure; + +import java.lang.invoke.MethodType; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +import jdk.vm.ci.meta.JavaKind; +import jdk.vm.ci.meta.MetaAccessProvider; +import jdk.vm.ci.meta.ResolvedJavaType; +import jdk.vm.ci.meta.Signature; + +/** + * A straightforward implementation of {@link Signature} where all parameter types and the return + * type are {@link ResolvedJavaType}. The generic type allows to further improve type safety of + * usages. + * + * In a regular {@link Signature}, looking up a + * {@link Signature#getParameterType(int, ResolvedJavaType) parameter type} or the + * {@link Signature#getReturnType(ResolvedJavaType) return type} requires to provide the "accessing + * class" for type resolution. Since in this implementation all types are always pre-resolved, these + * parameters are ignored. In addition, methods are offered that allow parameter type and return + * type lookup without providing the accessing class. + */ +public final class ResolvedSignature implements Signature { + + public static ResolvedSignature fromArray(T[] parameterTypes, T returnType) { + return new ResolvedSignature<>(List.of(parameterTypes), returnType); + } + + public static ResolvedSignature fromList(List parameterTypes, T returnType) { + return new ResolvedSignature<>(List.copyOf(parameterTypes), returnType); + } + + public static ResolvedSignature fromKinds(JavaKind[] parameterKinds, JavaKind returnKind, MetaAccessProvider metaAccess) { + return new ResolvedSignature<>( + Arrays.stream(parameterKinds).map(kind -> resolveType(kind, metaAccess)).collect(Collectors.toUnmodifiableList()), + resolveType(returnKind, metaAccess)); + } + + private static ResolvedJavaType resolveType(JavaKind kind, MetaAccessProvider metaAccess) { + return metaAccess.lookupJavaType(kind.isObject() ? Object.class : kind.toJavaClass()); + } + + public static ResolvedSignature fromMethodType(MethodType mt, MetaAccessProvider metaAccess) { + return new ResolvedSignature<>( + Arrays.stream(mt.parameterArray()).map(metaAccess::lookupJavaType).collect(Collectors.toUnmodifiableList()), + metaAccess.lookupJavaType(mt.returnType())); + } + + private final List parameterTypes; + private final T returnType; + + private ResolvedSignature(List parameterTypes, T returnType) { + /* + * All factory methods must pass in an immutable list for the parameter types, so that the + * list can be safely passes out again as the parameter list. Unfortunately, there is no way + * to assert that here. + */ + this.parameterTypes = parameterTypes; + this.returnType = returnType; + } + + @Override + public int getParameterCount(boolean withReceiver) { + return parameterTypes.size() + (withReceiver ? 1 : 0); + } + + @Override + public T getParameterType(int index, ResolvedJavaType accessingClass) { + return getParameterType(index); + } + + public T getParameterType(int index) { + return parameterTypes.get(index); + } + + @Override + public T getReturnType(ResolvedJavaType accessingClass) { + return getReturnType(); + } + + public T getReturnType() { + return returnType; + } + + /** + * A type-safe version of {@link Signature#toParameterTypes}. + * + * @return An unmodifiable list with all parameter types, including the receiverType if it is + * non-null. + */ + public List toParameterList(T receiverType) { + if (receiverType == null) { + /* parameterTypes is always an unmodifiable list, so we can return it directly. */ + return parameterTypes; + } + List withReceiver = new ArrayList<>(parameterTypes.size() + 1); + withReceiver.add(receiverType); + withReceiver.addAll(parameterTypes); + return Collections.unmodifiableList(withReceiver); + } + + @Override + public boolean equals(Object obj) { + return this == obj || (obj instanceof ResolvedSignature other && Objects.equals(parameterTypes, other.parameterTypes) && Objects.equals(returnType, other.returnType)); + } + + @Override + public int hashCode() { + return Objects.hash(parameterTypes, returnType); + } + + @Override + public String toString() { + return toMethodDescriptor(); + } +} diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/infrastructure/Universe.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/infrastructure/Universe.java index a19362f0ff8c..d69f1cd61394 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/infrastructure/Universe.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/infrastructure/Universe.java @@ -24,12 +24,11 @@ */ package com.oracle.graal.pointsto.infrastructure; -import jdk.graal.compiler.api.replacements.SnippetReflectionProvider; - import com.oracle.graal.pointsto.api.HostVM; import com.oracle.graal.pointsto.heap.ImageHeap; import com.oracle.graal.pointsto.heap.ImageHeapConstant; +import jdk.graal.compiler.api.replacements.SnippetReflectionProvider; import jdk.vm.ci.meta.ConstantPool; import jdk.vm.ci.meta.JavaConstant; import jdk.vm.ci.meta.JavaField; @@ -58,7 +57,7 @@ public interface Universe { JavaMethod lookupAllowUnresolved(JavaMethod method); - WrappedSignature lookup(Signature signature, ResolvedJavaType defaultAccessingClass); + ResolvedSignature lookup(Signature signature, ResolvedJavaType defaultAccessingClass); WrappedConstantPool lookup(ConstantPool constantPool, ResolvedJavaType defaultAccessingClass); diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/infrastructure/WrappedConstantPool.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/infrastructure/WrappedConstantPool.java index bfecdd052b7b..8c6cf91844f5 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/infrastructure/WrappedConstantPool.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/infrastructure/WrappedConstantPool.java @@ -31,13 +31,12 @@ import java.util.List; import java.util.stream.Collectors; -import jdk.graal.compiler.core.common.BootstrapMethodIntrospection; -import jdk.graal.compiler.debug.GraalError; -import jdk.graal.compiler.serviceprovider.GraalServices; - import com.oracle.graal.pointsto.constraints.UnresolvedElementException; import com.oracle.svm.util.ReflectionUtil; +import jdk.graal.compiler.core.common.BootstrapMethodIntrospection; +import jdk.graal.compiler.debug.GraalError; +import jdk.graal.compiler.serviceprovider.GraalServices; import jdk.vm.ci.meta.ConstantPool; import jdk.vm.ci.meta.JavaConstant; import jdk.vm.ci.meta.JavaField; @@ -153,7 +152,7 @@ public JavaType lookupType(int cpi, int opcode) { } @Override - public WrappedSignature lookupSignature(int cpi) { + public ResolvedSignature lookupSignature(int cpi) { return universe.lookup(wrapped.lookupSignature(cpi), defaultAccessingClass); } diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/infrastructure/WrappedSignature.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/infrastructure/WrappedSignature.java deleted file mode 100644 index c685e57bd57e..000000000000 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/infrastructure/WrappedSignature.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2012, 2017, 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.pointsto.infrastructure; - -import jdk.vm.ci.meta.JavaType; -import jdk.vm.ci.meta.ResolvedJavaType; -import jdk.vm.ci.meta.Signature; - -public class WrappedSignature implements Signature { - - private final Universe universe; - private final Signature wrapped; - private final ResolvedJavaType defaultAccessingClass; - - public WrappedSignature(Universe universe, Signature wrapped, ResolvedJavaType defaultAccessingClass) { - this.universe = universe; - this.wrapped = wrapped; - this.defaultAccessingClass = defaultAccessingClass; - } - - @Override - public int getParameterCount(boolean receiver) { - return wrapped.getParameterCount(receiver); - } - - @Override - public JavaType getParameterType(int index, ResolvedJavaType accessingClass) { - ResolvedJavaType parameterType; - try { - parameterType = resolve(wrapped.getParameterType(index, defaultAccessingClass)); - } catch (LinkageError e) { - /* - * Type resolution fails if the parameter type is missing. Just erase the type by - * returning the Object type. - */ - return universe.objectType(); - } - return universe.lookup(parameterType); - } - - @Override - public JavaType getReturnType(ResolvedJavaType accessingClass) { - ResolvedJavaType returnType; - try { - returnType = resolve(wrapped.getReturnType(defaultAccessingClass)); - } catch (LinkageError e) { - /* - * Type resolution fails if the return type is missing. Just erase the type by returning - * the Object type. - */ - return universe.objectType(); - } - return universe.lookup(returnType); - } - - /** - * We must not invoke {@link JavaType#resolve} on an already resolved type because it can - * actually fail the accessibility check when synthetic methods and synthetic signatures are - * involved. - */ - private ResolvedJavaType resolve(JavaType type) { - if (type instanceof ResolvedJavaType) { - return (ResolvedJavaType) type; - } else { - return type.resolve(defaultAccessingClass); - } - } - -} 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 d3b99640bbca..108cb2b118e6 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 @@ -53,8 +53,8 @@ import com.oracle.graal.pointsto.flow.AnalysisParsedGraph; import com.oracle.graal.pointsto.infrastructure.GraphProvider; import com.oracle.graal.pointsto.infrastructure.OriginalMethodProvider; +import com.oracle.graal.pointsto.infrastructure.ResolvedSignature; import com.oracle.graal.pointsto.infrastructure.WrappedJavaMethod; -import com.oracle.graal.pointsto.infrastructure.WrappedSignature; import com.oracle.graal.pointsto.reports.ReportUtils; import com.oracle.graal.pointsto.util.AnalysisError; import com.oracle.graal.pointsto.util.AtomicUtils; @@ -119,6 +119,7 @@ public record Signature(String name, AnalysisType[] parameterTypes) { private final String qualifiedName; protected final AnalysisType declaringClass; + protected final ResolvedSignature signature; private final int parsingContextMaxDepth; private final MultiMethodKey multiMethodKey; @@ -181,6 +182,7 @@ protected AnalysisMethod(AnalysisUniverse universe, ResolvedJavaMethod wrapped, id = universe.nextMethodId.getAndIncrement(); declaringClass = universe.lookup(wrapped.getDeclaringClass()); + signature = getUniverse().lookup(wrapped.getSignature(), wrapped.getDeclaringClass()); hasNeverInlineDirective = universe.hostVM().hasNeverInlineDirective(wrapped); name = createName(wrapped, multiMethodKey); @@ -228,6 +230,7 @@ protected AnalysisMethod(AnalysisMethod original, MultiMethodKey multiMethodKey) wrapped = original.wrapped; id = original.id; declaringClass = original.declaringClass; + signature = original.signature; hasNeverInlineDirective = original.hasNeverInlineDirective; exceptionHandlers = original.exceptionHandlers; localVariableTable = original.localVariableTable; @@ -627,8 +630,8 @@ public String getName() { } @Override - public WrappedSignature getSignature() { - return getUniverse().lookup(wrapped.getSignature(), wrapped.getDeclaringClass()); + public jdk.vm.ci.meta.Signature getSignature() { + return signature; } @Override 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 f7945793caab..9a21efcd0105 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 @@ -37,8 +37,6 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Function; -import jdk.graal.compiler.api.replacements.SnippetReflectionProvider; -import jdk.graal.compiler.core.common.SuppressFBWarnings; import org.graalvm.nativeimage.hosted.Feature.DuringAnalysisAccess; import org.graalvm.nativeimage.impl.AnnotationExtractor; import org.graalvm.word.WordBase; @@ -52,16 +50,18 @@ import com.oracle.graal.pointsto.heap.ImageHeapConstant; import com.oracle.graal.pointsto.heap.ImageHeapScanner; import com.oracle.graal.pointsto.infrastructure.AnalysisConstantPool; +import com.oracle.graal.pointsto.infrastructure.ResolvedSignature; import com.oracle.graal.pointsto.infrastructure.SubstitutionProcessor; import com.oracle.graal.pointsto.infrastructure.Universe; import com.oracle.graal.pointsto.infrastructure.WrappedConstantPool; import com.oracle.graal.pointsto.infrastructure.WrappedJavaType; -import com.oracle.graal.pointsto.infrastructure.WrappedSignature; import com.oracle.graal.pointsto.meta.AnalysisType.UsageKind; import com.oracle.graal.pointsto.util.AnalysisError; import com.oracle.graal.pointsto.util.AnalysisFuture; import com.oracle.graal.pointsto.util.GraalAccess; +import jdk.graal.compiler.api.replacements.SnippetReflectionProvider; +import jdk.graal.compiler.core.common.SuppressFBWarnings; import jdk.vm.ci.code.BytecodePosition; import jdk.vm.ci.common.JVMCIError; import jdk.vm.ci.meta.ConstantPool; @@ -88,7 +88,7 @@ public class AnalysisUniverse implements Universe { private final ConcurrentMap types = new ConcurrentHashMap<>(ESTIMATED_NUMBER_OF_TYPES); private final ConcurrentMap fields = new ConcurrentHashMap<>(ESTIMATED_FIELDS_PER_TYPE * ESTIMATED_NUMBER_OF_TYPES); private final ConcurrentMap methods = new ConcurrentHashMap<>(ESTIMATED_METHODS_PER_TYPE * ESTIMATED_NUMBER_OF_TYPES); - private final ConcurrentMap signatures = new ConcurrentHashMap<>(ESTIMATED_METHODS_PER_TYPE * ESTIMATED_NUMBER_OF_TYPES); + private final ConcurrentMap, ResolvedSignature> uniqueSignatures = new ConcurrentHashMap<>(); private final ConcurrentMap constantPools = new ConcurrentHashMap<>(ESTIMATED_NUMBER_OF_TYPES); private final ConcurrentHashMap embeddedRoots = new ConcurrentHashMap<>(ESTIMATED_EMBEDDED_ROOTS); private final ConcurrentMap unsafeAccessedStaticFields = new ConcurrentHashMap<>(); @@ -470,16 +470,37 @@ public AnalysisMethod[] lookup(JavaMethod[] inputs) { } @Override - public WrappedSignature lookup(Signature signature, ResolvedJavaType defaultAccessingClass) { - assert !(signature instanceof WrappedSignature) : signature; + public ResolvedSignature lookup(Signature signature, ResolvedJavaType defaultAccessingClass) { assert !(defaultAccessingClass instanceof WrappedJavaType) : defaultAccessingClass; - WrappedSignature result = signatures.get(signature); - if (result == null) { - WrappedSignature newValue = new WrappedSignature(this, signature, defaultAccessingClass); - WrappedSignature oldValue = signatures.putIfAbsent(signature, newValue); - result = oldValue != null ? oldValue : newValue; + + AnalysisType[] paramTypes = new AnalysisType[signature.getParameterCount(false)]; + for (int i = 0; i < paramTypes.length; i++) { + paramTypes[i] = lookup(resolveSignatureType(signature.getParameterType(i, defaultAccessingClass), defaultAccessingClass)); + } + AnalysisType returnType = lookup(resolveSignatureType(signature.getReturnType(defaultAccessingClass), defaultAccessingClass)); + ResolvedSignature key = ResolvedSignature.fromArray(paramTypes, returnType); + + return uniqueSignatures.computeIfAbsent(key, k -> k); + } + + private ResolvedJavaType resolveSignatureType(JavaType type, ResolvedJavaType defaultAccessingClass) { + /* + * We must not invoke resolve() on an already resolved type because it can actually fail the + * accessibility check when synthetic methods and synthetic signatures are involved. + */ + if (type instanceof ResolvedJavaType resolvedType) { + return resolvedType; + } + + try { + return type.resolve(defaultAccessingClass); + } catch (LinkageError e) { + /* + * Type resolution fails if the parameter type is missing. Just erase the type by + * returning the Object type. + */ + return objectType().getWrapped(); } - return result; } @Override diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/annotation/CustomSubstitutionMethod.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/annotation/CustomSubstitutionMethod.java index ea9aa91d5843..b6d662a7c444 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/annotation/CustomSubstitutionMethod.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/annotation/CustomSubstitutionMethod.java @@ -37,6 +37,7 @@ import jdk.vm.ci.meta.Constant; import jdk.vm.ci.meta.ConstantPool; import jdk.vm.ci.meta.ExceptionHandler; +import jdk.vm.ci.meta.JavaType; import jdk.vm.ci.meta.LineNumberTable; import jdk.vm.ci.meta.LocalVariableTable; import jdk.vm.ci.meta.ProfilingInfo; @@ -75,7 +76,42 @@ public String getName() { @Override public Signature getSignature() { - return original.getSignature(); + /* + * When the substitution method injects a different declaringClass, then type resolution + * with that new declaringClass could fail due to class visibility differences. We try to + * resolve with the original declaringClass, for which the resolving can then succeed. + */ + return new Signature() { + private final Signature wrapped = original.getSignature(); + + @Override + public int getParameterCount(boolean receiver) { + return wrapped.getParameterCount(receiver); + } + + @Override + public JavaType getParameterType(int index, ResolvedJavaType accessingClass) { + JavaType result = wrapped.getParameterType(index, accessingClass); + if (accessingClass != null && !(result instanceof ResolvedJavaType)) { + result = wrapped.getParameterType(index, original.getDeclaringClass()); + } + return result; + } + + @Override + public JavaType getReturnType(ResolvedJavaType accessingClass) { + JavaType result = wrapped.getReturnType(accessingClass); + if (accessingClass != null && !(result instanceof ResolvedJavaType)) { + result = wrapped.getReturnType(original.getDeclaringClass()); + } + return result; + } + + @Override + public String toString() { + return "CustomSubstitutionMethod.Signature<" + wrapped + ">"; + } + }; } @Override diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/CFunctionPointerCallStubMethod.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/CFunctionPointerCallStubMethod.java index d68c3a439113..eb11296acf92 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/CFunctionPointerCallStubMethod.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/CFunctionPointerCallStubMethod.java @@ -63,18 +63,22 @@ private CFunctionPointerCallStubMethod(ResolvedJavaMethod original, int newThrea @Override public Signature getSignature() { + /* + * Inject the declaring class as an additional parameter at the beginning of the parameter + * list, to compensate for making the method `static`. + */ return new Signature() { - private final Signature wrapped = getOriginal().getSignature(); + private final Signature wrapped = CFunctionPointerCallStubMethod.super.getSignature(); @Override public int getParameterCount(boolean receiver) { - return wrapped.getParameterCount(true); + return wrapped.getParameterCount(receiver) + 1; } @Override public JavaType getParameterType(int index, ResolvedJavaType accessingClass) { if (index == 0) { - return getOriginal().getDeclaringClass().resolve(accessingClass); + return getOriginal().getDeclaringClass(); } return wrapped.getParameterType(index - 1, accessingClass); } @@ -83,6 +87,11 @@ public JavaType getParameterType(int index, ResolvedJavaType accessingClass) { public JavaType getReturnType(ResolvedJavaType accessingClass) { return wrapped.getReturnType(accessingClass); } + + @Override + public String toString() { + return "CFunctionPointerCallStubMethod.Signature<" + wrapped + ">"; + } }; } 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 be06ee0698b7..cfbecee9c656 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 @@ -38,8 +38,6 @@ import java.util.Map; import java.util.Optional; -import jdk.graal.compiler.api.replacements.SnippetReflectionProvider; -import jdk.graal.compiler.nodes.StructuredGraph; import org.graalvm.nativeimage.hosted.Feature; import com.oracle.graal.pointsto.BigBang; @@ -49,10 +47,10 @@ import com.oracle.graal.pointsto.infrastructure.OriginalClassProvider; import com.oracle.graal.pointsto.infrastructure.OriginalFieldProvider; import com.oracle.graal.pointsto.infrastructure.OriginalMethodProvider; +import com.oracle.graal.pointsto.infrastructure.ResolvedSignature; import com.oracle.graal.pointsto.infrastructure.SubstitutionProcessor; import com.oracle.graal.pointsto.infrastructure.Universe; import com.oracle.graal.pointsto.infrastructure.WrappedConstantPool; -import com.oracle.graal.pointsto.infrastructure.WrappedSignature; import com.oracle.graal.pointsto.meta.AnalysisField; import com.oracle.graal.pointsto.meta.AnalysisMethod; import com.oracle.graal.pointsto.meta.AnalysisType; @@ -75,6 +73,8 @@ import com.oracle.svm.hosted.substitute.SubstitutionMethod; import com.oracle.svm.hosted.substitute.SubstitutionType; +import jdk.graal.compiler.api.replacements.SnippetReflectionProvider; +import jdk.graal.compiler.nodes.StructuredGraph; import jdk.vm.ci.hotspot.HotSpotResolvedJavaType; import jdk.vm.ci.meta.ConstantPool; import jdk.vm.ci.meta.JavaConstant; @@ -288,7 +288,7 @@ public class HostedUniverse implements Universe { protected final Map types = new HashMap<>(); protected final Map fields = new HashMap<>(); protected final Map methods = new HashMap<>(); - protected final Map signatures = new HashMap<>(); + protected final Map, ResolvedSignature> signatures = new HashMap<>(); protected final Map constantPools = new HashMap<>(); protected EnumMap kindToType = new EnumMap<>(JavaKind.class); @@ -425,7 +425,7 @@ public HostedMethod[] lookup(JavaMethod[] inputs) { } @Override - public WrappedSignature lookup(Signature signature, ResolvedJavaType defaultAccessingClass) { + public ResolvedSignature lookup(Signature signature, ResolvedJavaType defaultAccessingClass) { assert signatures.containsKey(signature) : signature; return signatures.get(signature); } 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 91dff3d66c12..f93ea1d32ff0 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 @@ -52,8 +52,8 @@ import com.oracle.graal.pointsto.BigBang; import com.oracle.graal.pointsto.constraints.UnsupportedFeatures; +import com.oracle.graal.pointsto.infrastructure.ResolvedSignature; import com.oracle.graal.pointsto.infrastructure.WrappedConstantPool; -import com.oracle.graal.pointsto.infrastructure.WrappedSignature; import com.oracle.graal.pointsto.meta.AnalysisField; import com.oracle.graal.pointsto.meta.AnalysisMetaAccess; import com.oracle.graal.pointsto.meta.AnalysisMethod; @@ -108,7 +108,6 @@ import jdk.vm.ci.meta.ExceptionHandler; import jdk.vm.ci.meta.JavaKind; import jdk.vm.ci.meta.JavaType; -import jdk.vm.ci.meta.Signature; import jdk.vm.ci.meta.UnresolvedJavaType; public class UniverseBuilder { @@ -294,7 +293,8 @@ private static boolean sameObject(Object x, Object y) { private HostedMethod makeMethod(AnalysisMethod aMethod) { AnalysisType aDeclaringClass = aMethod.getDeclaringClass(); HostedType hDeclaringClass = lookupType(aDeclaringClass); - Signature signature = makeSignature(aMethod.getSignature(), aDeclaringClass); + @SuppressWarnings("unchecked") + var signature = makeSignature((ResolvedSignature) aMethod.getSignature()); ConstantPool constantPool = makeConstantPool(aMethod.getConstantPool(), aDeclaringClass); ExceptionHandler[] aHandlers = aMethod.getExceptionHandlers(); @@ -332,16 +332,17 @@ private HostedMethod makeMethod(AnalysisMethod aMethod) { return hMethod; } - private Signature makeSignature(Signature aSignature, AnalysisType aDefaultAccessingClass) { - WrappedSignature hSignature = hUniverse.signatures.get(aSignature); + private ResolvedSignature makeSignature(ResolvedSignature aSignature) { + ResolvedSignature hSignature = hUniverse.signatures.get(aSignature); if (hSignature == null) { - hSignature = new WrappedSignature(hUniverse, aSignature, aDefaultAccessingClass); - hUniverse.signatures.put(aSignature, hSignature); - - for (int i = 0; i < aSignature.getParameterCount(false); i++) { - lookupType((AnalysisType) aSignature.getParameterType(i, null)); + HostedType[] paramTypes = new HostedType[aSignature.getParameterCount(false)]; + for (int i = 0; i < paramTypes.length; i++) { + paramTypes[i] = lookupType(aSignature.getParameterType(i)); } - lookupType((AnalysisType) aSignature.getReturnType(null)); + HostedType returnType = lookupType(aSignature.getReturnType()); + + hSignature = ResolvedSignature.fromArray(paramTypes, returnType); + hUniverse.signatures.put(aSignature, hSignature); } return hSignature; }