Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
import com.oracle.svm.core.annotate.RecomputeFieldValue;
import com.oracle.svm.core.annotate.RecomputeFieldValue.Kind;
import com.oracle.svm.core.annotate.TargetClass;
import com.oracle.svm.core.util.HostedSubstrateUtil;
import com.oracle.svm.core.util.VMError;
import com.oracle.svm.util.ReflectionUtil;
import com.oracle.svm.util.StringUtil;
Expand Down Expand Up @@ -376,12 +377,14 @@ public static String defaultUniqueShortName(Member m) {
* @return A unique identifier for the classloader or the empty string when the loader is one of
* the special set whose method names do not need qualification.
*/
public static String classLoaderNameAndId(ClassLoader loader) {
if (loader == null) {
public static String runtimeClassLoaderNameAndId(ClassLoader loader) {
ClassLoader runtimeClassLoader = SubstrateUtil.HOSTED ? HostedSubstrateUtil.getRuntimeClassLoader(loader) : loader;

if (runtimeClassLoader == null) {
return "";
}
try {
return (String) classLoaderNameAndId.get(loader);
return (String) classLoaderNameAndId.get(runtimeClassLoader);
} catch (IllegalAccessException e) {
throw VMError.shouldNotReachHere("Cannot reflectively access ClassLoader.nameAndId");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
public class UniqueShortNameProviderDefaultImpl implements UniqueShortNameProvider {
@Override
public String uniqueShortName(ClassLoader loader, ResolvedJavaType declaringClass, String methodName, Signature methodSignature, boolean isConstructor) {
return SubstrateUtil.defaultUniqueShortName(SubstrateUtil.classLoaderNameAndId(loader), declaringClass, methodName, methodSignature, isConstructor);
return SubstrateUtil.defaultUniqueShortName(SubstrateUtil.runtimeClassLoaderNameAndId(loader), declaringClass, methodName, methodSignature, isConstructor);
}

@Override
Expand All @@ -52,7 +52,7 @@ public String uniqueShortName(Member m) {

@Override
public String uniqueShortLoaderName(ClassLoader classLoader) {
return SubstrateUtil.classLoaderNameAndId(classLoader);
return SubstrateUtil.runtimeClassLoaderNameAndId(classLoader);
}

public static class UseDefault implements BooleanSupplier {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright (c) 2024, 2024, 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.svm.core.util;

import org.graalvm.nativeimage.ImageSingletons;
import org.graalvm.nativeimage.Platform;
import org.graalvm.nativeimage.Platforms;

@Platforms(Platform.HOSTED_ONLY.class)
public interface HostedSubstrateUtil {

static ClassLoader getRuntimeClassLoader(ClassLoader loader) {
return ImageSingletons.lookup(HostedSubstrateUtil.class).doGetRuntimeClassLoader(loader);
}

ClassLoader doGetRuntimeClassLoader(ClassLoader loader);
}
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public String uniqueShortLoaderName(ClassLoader loader) {
if (isGraalImageLoader(loader)) {
return "";
}
String name = SubstrateUtil.classLoaderNameAndId(loader);
String name = SubstrateUtil.runtimeClassLoaderNameAndId(loader);
// name will look like "org.foo.bar.FooBarClassLoader @1234"
// trim it down to something more manageable
// escaping quotes in the classlaoder name does not work in GDB
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
import java.util.function.Function;

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

private static HostedMethod create0(AnalysisMethod wrapped, HostedType holder, ResolvedSignature<HostedType> signature,
ConstantPool constantPool, ExceptionHandler[] handlers, MultiMethodKey key, Map<MultiMethodKey, MultiMethod> multiMethodMap, LocalVariableTable localVariableTable) {
Function<Integer, HostedMethodNameFactory.MethodNameInfo> nameGenerator = (collisionCount) -> {
String name = wrapped.wrapped.getName(); // want name w/o any multimethodkey suffix
if (key != ORIGINAL_METHOD) {
name += StableMethodNameFormatter.MULTI_METHOD_KEY_SEPARATOR + key;
}
if (collisionCount > 0) {
name = name + METHOD_NAME_COLLISION_SEPARATOR + collisionCount;
var generator = new HostedMethodNameFactory.NameGenerator() {

@Override
public HostedMethodNameFactory.MethodNameInfo generateMethodNameInfo(int collisionCount) {
String name = wrapped.wrapped.getName(); // want name w/o any multimethodkey suffix
if (key != ORIGINAL_METHOD) {
name += StableMethodNameFormatter.MULTI_METHOD_KEY_SEPARATOR + key;
}
if (collisionCount > 0) {
name = name + METHOD_NAME_COLLISION_SEPARATOR + collisionCount;
}

String uniqueShortName = generateUniqueName(name);

return new HostedMethodNameFactory.MethodNameInfo(name, uniqueShortName);
}
String uniqueShortName = SubstrateUtil.uniqueShortName(holder.getJavaClass().getClassLoader(), holder, name, signature, wrapped.isConstructor());

return new HostedMethodNameFactory.MethodNameInfo(name, uniqueShortName);
@Override
public String generateUniqueName(String name) {
return SubstrateUtil.uniqueShortName(holder.getJavaClass().getClassLoader(), holder, name, signature, wrapped.isConstructor());
}
};

HostedMethodNameFactory.MethodNameInfo names = HostedMethodNameFactory.singleton().createNames(nameGenerator, wrapped);
HostedMethodNameFactory.MethodNameInfo names = HostedMethodNameFactory.singleton().createNames(generator, wrapped);

return new HostedMethod(wrapped, holder, signature, constantPool, handlers, names.name(), names.uniqueShortName(), localVariableTable, key, multiMethodMap);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,35 +27,56 @@
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;

import org.graalvm.nativeimage.ImageSingletons;

import com.oracle.graal.pointsto.meta.AnalysisMethod;
import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature;
import com.oracle.svm.core.feature.InternalFeature;
import com.oracle.svm.core.imagelayer.ImageLayerBuildingSupport;
import com.oracle.svm.core.option.HostedOptionKey;
import com.oracle.svm.core.util.VMError;
import com.oracle.svm.hosted.imagelayer.HostedDynamicLayerInfo;
import com.oracle.svm.util.LogUtils;

import jdk.graal.compiler.options.Option;

@AutomaticallyRegisteredFeature
public class HostedMethodNameFactory implements InternalFeature {
public static final class Options {
@Option(help = "Log unique names which do not match across layers. This is an experimental option which will be removed.") //
public static final HostedOptionKey<Boolean> LogUniqueNameInconsistencies = new HostedOptionKey<>(false);
}

private Map<String, Integer> methodNameCount = new ConcurrentHashMap<>();
private Set<String> uniqueShortNames = ConcurrentHashMap.newKeySet();
private final boolean buildingExtensionLayer = ImageLayerBuildingSupport.buildingExtensionLayer();
private Set<String> reservedUniqueShortNames = buildingExtensionLayer ? HostedDynamicLayerInfo.singleton().getReservedNames() : null;
private final boolean logUniqueNameInconsistencies = Options.LogUniqueNameInconsistencies.getValue();

public record MethodNameInfo(String name, String uniqueShortName) {
}

public interface NameGenerator {
MethodNameInfo generateMethodNameInfo(int collisionCount);

String generateUniqueName(String name);
}

public static HostedMethodNameFactory singleton() {
return ImageSingletons.lookup(HostedMethodNameFactory.class);
}

MethodNameInfo createNames(Function<Integer, MethodNameInfo> nameGenerator, AnalysisMethod aMethod) {
MethodNameInfo createNames(NameGenerator generator, AnalysisMethod aMethod) {
MethodNameInfo result = buildingExtensionLayer ? HostedDynamicLayerInfo.singleton().loadMethodNameInfo(aMethod) : null;
if (result != null) {
assert reservedUniqueShortNames.contains(result.uniqueShortName()) : result;
if (logUniqueNameInconsistencies) {
boolean consistentNames = generator.generateUniqueName(result.name()).equals(result.uniqueShortName);
if (!consistentNames) {
LogUtils.warning("Unique names are inconsistent for %s", aMethod.getQualifiedName());
}
}

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

MethodNameInfo initialName = nameGenerator.apply(0);
MethodNameInfo initialName = generator.generateMethodNameInfo(0);
result = initialName;

do {
int collisionCount = methodNameCount.merge(initialName.uniqueShortName(), 0, (oldValue, value) -> oldValue + 1);
if (collisionCount != 0) {
result = nameGenerator.apply(collisionCount);
result = generator.generateMethodNameInfo(collisionCount);
}
/*
* Redo if the short name is reserved.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -671,7 +671,7 @@ public int compare(HostedType o1, HostedType o2) {

ClassLoader l1 = Optional.ofNullable(o1.getJavaClass()).map(Class::getClassLoader).orElse(null);
ClassLoader l2 = Optional.ofNullable(o2.getJavaClass()).map(Class::getClassLoader).orElse(null);
result = SubstrateUtil.classLoaderNameAndId(l1).compareTo(SubstrateUtil.classLoaderNameAndId(l2));
result = SubstrateUtil.runtimeClassLoaderNameAndId(l1).compareTo(SubstrateUtil.runtimeClassLoaderNameAndId(l2));
VMError.guarantee(result != 0, "HostedType objects not distinguishable by name and classloader: %s, %s", o1, o2);
return result;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright (c) 2024, 2024, 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.svm.hosted.util;

import com.oracle.svm.core.feature.AutomaticallyRegisteredImageSingleton;
import com.oracle.svm.core.util.HostedSubstrateUtil;
import com.oracle.svm.hosted.ClassLoaderFeature;

@AutomaticallyRegisteredImageSingleton(value = HostedSubstrateUtil.class)
public class HostedSubstrateUtilDefaultImpl implements HostedSubstrateUtil {

@Override
public ClassLoader doGetRuntimeClassLoader(ClassLoader loader) {
return ClassLoaderFeature.getRuntimeClassLoader(loader);
}
}