Skip to content

Commit 6e1388b

Browse files
committed
[GR-60044] Use runtime ClassLoader for unique name support.
PullRequest: graal/19472
2 parents 9625aeb + 1dcc5eb commit 6e1388b

File tree

8 files changed

+132
-22
lines changed

8 files changed

+132
-22
lines changed

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

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
import com.oracle.svm.core.annotate.RecomputeFieldValue;
5252
import com.oracle.svm.core.annotate.RecomputeFieldValue.Kind;
5353
import com.oracle.svm.core.annotate.TargetClass;
54+
import com.oracle.svm.core.util.HostedSubstrateUtil;
5455
import com.oracle.svm.core.util.VMError;
5556
import com.oracle.svm.util.ReflectionUtil;
5657
import com.oracle.svm.util.StringUtil;
@@ -376,12 +377,14 @@ public static String defaultUniqueShortName(Member m) {
376377
* @return A unique identifier for the classloader or the empty string when the loader is one of
377378
* the special set whose method names do not need qualification.
378379
*/
379-
public static String classLoaderNameAndId(ClassLoader loader) {
380-
if (loader == null) {
380+
public static String runtimeClassLoaderNameAndId(ClassLoader loader) {
381+
ClassLoader runtimeClassLoader = SubstrateUtil.HOSTED ? HostedSubstrateUtil.getRuntimeClassLoader(loader) : loader;
382+
383+
if (runtimeClassLoader == null) {
381384
return "";
382385
}
383386
try {
384-
return (String) classLoaderNameAndId.get(loader);
387+
return (String) classLoaderNameAndId.get(runtimeClassLoader);
385388
} catch (IllegalAccessException e) {
386389
throw VMError.shouldNotReachHere("Cannot reflectively access ClassLoader.nameAndId");
387390
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
public class UniqueShortNameProviderDefaultImpl implements UniqueShortNameProvider {
4343
@Override
4444
public String uniqueShortName(ClassLoader loader, ResolvedJavaType declaringClass, String methodName, Signature methodSignature, boolean isConstructor) {
45-
return SubstrateUtil.defaultUniqueShortName(SubstrateUtil.classLoaderNameAndId(loader), declaringClass, methodName, methodSignature, isConstructor);
45+
return SubstrateUtil.defaultUniqueShortName(SubstrateUtil.runtimeClassLoaderNameAndId(loader), declaringClass, methodName, methodSignature, isConstructor);
4646
}
4747

4848
@Override
@@ -52,7 +52,7 @@ public String uniqueShortName(Member m) {
5252

5353
@Override
5454
public String uniqueShortLoaderName(ClassLoader classLoader) {
55-
return SubstrateUtil.classLoaderNameAndId(classLoader);
55+
return SubstrateUtil.runtimeClassLoaderNameAndId(classLoader);
5656
}
5757

5858
public static class UseDefault implements BooleanSupplier {
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Copyright (c) 2024, 2024, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
package com.oracle.svm.core.util;
26+
27+
import org.graalvm.nativeimage.ImageSingletons;
28+
import org.graalvm.nativeimage.Platform;
29+
import org.graalvm.nativeimage.Platforms;
30+
31+
@Platforms(Platform.HOSTED_ONLY.class)
32+
public interface HostedSubstrateUtil {
33+
34+
static ClassLoader getRuntimeClassLoader(ClassLoader loader) {
35+
return ImageSingletons.lookup(HostedSubstrateUtil.class).doGetRuntimeClassLoader(loader);
36+
}
37+
38+
ClassLoader doGetRuntimeClassLoader(ClassLoader loader);
39+
}

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageBFDNameProvider.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ public String uniqueShortLoaderName(ClassLoader loader) {
8787
if (isGraalImageLoader(loader)) {
8888
return "";
8989
}
90-
String name = SubstrateUtil.classLoaderNameAndId(loader);
90+
String name = SubstrateUtil.runtimeClassLoaderNameAndId(loader);
9191
// name will look like "org.foo.bar.FooBarClassLoader @1234"
9292
// trim it down to something more manageable
9393
// escaping quotes in the classlaoder name does not work in GDB

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/meta/HostedMethod.java

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434
import java.util.Map;
3535
import java.util.concurrent.ConcurrentHashMap;
3636
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
37-
import java.util.function.Function;
3837

3938
import com.oracle.graal.pointsto.constraints.UnsupportedFeatureException;
4039
import com.oracle.graal.pointsto.infrastructure.OriginalMethodProvider;
@@ -150,20 +149,30 @@ static HostedMethod create(HostedUniverse universe, AnalysisMethod wrapped, Host
150149

151150
private static HostedMethod create0(AnalysisMethod wrapped, HostedType holder, ResolvedSignature<HostedType> signature,
152151
ConstantPool constantPool, ExceptionHandler[] handlers, MultiMethodKey key, Map<MultiMethodKey, MultiMethod> multiMethodMap, LocalVariableTable localVariableTable) {
153-
Function<Integer, HostedMethodNameFactory.MethodNameInfo> nameGenerator = (collisionCount) -> {
154-
String name = wrapped.wrapped.getName(); // want name w/o any multimethodkey suffix
155-
if (key != ORIGINAL_METHOD) {
156-
name += StableMethodNameFormatter.MULTI_METHOD_KEY_SEPARATOR + key;
157-
}
158-
if (collisionCount > 0) {
159-
name = name + METHOD_NAME_COLLISION_SEPARATOR + collisionCount;
152+
var generator = new HostedMethodNameFactory.NameGenerator() {
153+
154+
@Override
155+
public HostedMethodNameFactory.MethodNameInfo generateMethodNameInfo(int collisionCount) {
156+
String name = wrapped.wrapped.getName(); // want name w/o any multimethodkey suffix
157+
if (key != ORIGINAL_METHOD) {
158+
name += StableMethodNameFormatter.MULTI_METHOD_KEY_SEPARATOR + key;
159+
}
160+
if (collisionCount > 0) {
161+
name = name + METHOD_NAME_COLLISION_SEPARATOR + collisionCount;
162+
}
163+
164+
String uniqueShortName = generateUniqueName(name);
165+
166+
return new HostedMethodNameFactory.MethodNameInfo(name, uniqueShortName);
160167
}
161-
String uniqueShortName = SubstrateUtil.uniqueShortName(holder.getJavaClass().getClassLoader(), holder, name, signature, wrapped.isConstructor());
162168

163-
return new HostedMethodNameFactory.MethodNameInfo(name, uniqueShortName);
169+
@Override
170+
public String generateUniqueName(String name) {
171+
return SubstrateUtil.uniqueShortName(holder.getJavaClass().getClassLoader(), holder, name, signature, wrapped.isConstructor());
172+
}
164173
};
165174

166-
HostedMethodNameFactory.MethodNameInfo names = HostedMethodNameFactory.singleton().createNames(nameGenerator, wrapped);
175+
HostedMethodNameFactory.MethodNameInfo names = HostedMethodNameFactory.singleton().createNames(generator, wrapped);
167176

168177
return new HostedMethod(wrapped, holder, signature, constantPool, handlers, names.name(), names.uniqueShortName(), localVariableTable, key, multiMethodMap);
169178
}

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/meta/HostedMethodNameFactory.java

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,35 +27,56 @@
2727
import java.util.Map;
2828
import java.util.Set;
2929
import java.util.concurrent.ConcurrentHashMap;
30-
import java.util.function.Function;
3130

3231
import org.graalvm.nativeimage.ImageSingletons;
3332

3433
import com.oracle.graal.pointsto.meta.AnalysisMethod;
3534
import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature;
3635
import com.oracle.svm.core.feature.InternalFeature;
3736
import com.oracle.svm.core.imagelayer.ImageLayerBuildingSupport;
37+
import com.oracle.svm.core.option.HostedOptionKey;
3838
import com.oracle.svm.core.util.VMError;
3939
import com.oracle.svm.hosted.imagelayer.HostedDynamicLayerInfo;
40+
import com.oracle.svm.util.LogUtils;
41+
42+
import jdk.graal.compiler.options.Option;
4043

4144
@AutomaticallyRegisteredFeature
4245
public class HostedMethodNameFactory implements InternalFeature {
46+
public static final class Options {
47+
@Option(help = "Log unique names which do not match across layers. This is an experimental option which will be removed.") //
48+
public static final HostedOptionKey<Boolean> LogUniqueNameInconsistencies = new HostedOptionKey<>(false);
49+
}
50+
4351
private Map<String, Integer> methodNameCount = new ConcurrentHashMap<>();
4452
private Set<String> uniqueShortNames = ConcurrentHashMap.newKeySet();
4553
private final boolean buildingExtensionLayer = ImageLayerBuildingSupport.buildingExtensionLayer();
4654
private Set<String> reservedUniqueShortNames = buildingExtensionLayer ? HostedDynamicLayerInfo.singleton().getReservedNames() : null;
55+
private final boolean logUniqueNameInconsistencies = Options.LogUniqueNameInconsistencies.getValue();
4756

4857
public record MethodNameInfo(String name, String uniqueShortName) {
4958
}
5059

60+
public interface NameGenerator {
61+
MethodNameInfo generateMethodNameInfo(int collisionCount);
62+
63+
String generateUniqueName(String name);
64+
}
65+
5166
public static HostedMethodNameFactory singleton() {
5267
return ImageSingletons.lookup(HostedMethodNameFactory.class);
5368
}
5469

55-
MethodNameInfo createNames(Function<Integer, MethodNameInfo> nameGenerator, AnalysisMethod aMethod) {
70+
MethodNameInfo createNames(NameGenerator generator, AnalysisMethod aMethod) {
5671
MethodNameInfo result = buildingExtensionLayer ? HostedDynamicLayerInfo.singleton().loadMethodNameInfo(aMethod) : null;
5772
if (result != null) {
5873
assert reservedUniqueShortNames.contains(result.uniqueShortName()) : result;
74+
if (logUniqueNameInconsistencies) {
75+
boolean consistentNames = generator.generateUniqueName(result.name()).equals(result.uniqueShortName);
76+
if (!consistentNames) {
77+
LogUtils.warning("Unique names are inconsistent for %s", aMethod.getQualifiedName());
78+
}
79+
}
5980

6081
boolean added = uniqueShortNames.add(result.uniqueShortName());
6182
if (added) {
@@ -67,13 +88,13 @@ MethodNameInfo createNames(Function<Integer, MethodNameInfo> nameGenerator, Anal
6788
}
6889
}
6990

70-
MethodNameInfo initialName = nameGenerator.apply(0);
91+
MethodNameInfo initialName = generator.generateMethodNameInfo(0);
7192
result = initialName;
7293

7394
do {
7495
int collisionCount = methodNameCount.merge(initialName.uniqueShortName(), 0, (oldValue, value) -> oldValue + 1);
7596
if (collisionCount != 0) {
76-
result = nameGenerator.apply(collisionCount);
97+
result = generator.generateMethodNameInfo(collisionCount);
7798
}
7899
/*
79100
* Redo if the short name is reserved.

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/meta/HostedUniverse.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -671,7 +671,7 @@ public int compare(HostedType o1, HostedType o2) {
671671

672672
ClassLoader l1 = Optional.ofNullable(o1.getJavaClass()).map(Class::getClassLoader).orElse(null);
673673
ClassLoader l2 = Optional.ofNullable(o2.getJavaClass()).map(Class::getClassLoader).orElse(null);
674-
result = SubstrateUtil.classLoaderNameAndId(l1).compareTo(SubstrateUtil.classLoaderNameAndId(l2));
674+
result = SubstrateUtil.runtimeClassLoaderNameAndId(l1).compareTo(SubstrateUtil.runtimeClassLoaderNameAndId(l2));
675675
VMError.guarantee(result != 0, "HostedType objects not distinguishable by name and classloader: %s, %s", o1, o2);
676676
return result;
677677
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright (c) 2024, 2024, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
package com.oracle.svm.hosted.util;
26+
27+
import com.oracle.svm.core.feature.AutomaticallyRegisteredImageSingleton;
28+
import com.oracle.svm.core.util.HostedSubstrateUtil;
29+
import com.oracle.svm.hosted.ClassLoaderFeature;
30+
31+
@AutomaticallyRegisteredImageSingleton(value = HostedSubstrateUtil.class)
32+
public class HostedSubstrateUtilDefaultImpl implements HostedSubstrateUtil {
33+
34+
@Override
35+
public ClassLoader doGetRuntimeClassLoader(ClassLoader loader) {
36+
return ClassLoaderFeature.getRuntimeClassLoader(loader);
37+
}
38+
}

0 commit comments

Comments
 (0)