Skip to content
Merged
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 @@ -304,21 +304,24 @@ public final class DynamicHub implements AnnotatedElement, java.lang.reflect.Typ
* time will throw an error.
*/
private static final int IS_LINKED_BIT = 10;
/**
* Indicates whether the class is a proxy class according to
* {@link java.lang.reflect.Proxy#isProxyClass}.
*/
private static final int IS_PROXY_CLASS_BIT = 11;

/**
* Similar to {@link #flags}, but non-final because {@link #setSharedData} sets the value.
*/
@UnknownPrimitiveField(availability = AfterHostedUniverse.class)//
private byte additionalFlags;

/** Has the type been discovered as instantiated by the static analysis? */
/** Indicates whether the type has been discovered as instantiated by the static analysis. */
private static final int IS_INSTANTIATED_BIT = 0;
/** Can this class be instantiated as an instance. */
private static final int CAN_INSTANTIATE_AS_INSTANCE_BIT = 1;
/** Is the class a proxy class according to {@link java.lang.reflect.Proxy#isProxyClass}? */
private static final int IS_PROXY_CLASS_BIT = 2;

private static final int IS_REGISTERED_FOR_SERIALIZATION = 3;
private static final int IS_REGISTERED_FOR_SERIALIZATION = 2;

/**
* The {@link Modifier modifiers} of this class.
Expand Down Expand Up @@ -439,7 +442,7 @@ public final class DynamicHub implements AnnotatedElement, java.lang.reflect.Typ
@Platforms(Platform.HOSTED_ONLY.class)
public DynamicHub(Class<?> hostedJavaClass, String name, int hubType, ReferenceType referenceType, DynamicHub superType, DynamicHub componentHub, String sourceFileName, int modifiers,
ClassLoader classLoader, boolean isHidden, boolean isRecord, Class<?> nestHost, boolean assertionStatus, boolean hasDefaultMethods, boolean declaresDefaultMethods,
boolean isSealed, boolean isVMInternal, boolean isLambdaFormHidden, boolean isLinked, String simpleBinaryName, Object declaringClass, String signature) {
boolean isSealed, boolean isVMInternal, boolean isLambdaFormHidden, boolean isLinked, String simpleBinaryName, Object declaringClass, String signature, boolean isProxyClass) {
this.hostedJavaClass = hostedJavaClass;
this.module = hostedJavaClass.getModule();
this.name = name;
Expand All @@ -464,7 +467,8 @@ public DynamicHub(Class<?> hostedJavaClass, String name, int hubType, ReferenceT
makeFlag(IS_SEALED_FLAG_BIT, isSealed) |
makeFlag(IS_VM_INTERNAL_FLAG_BIT, isVMInternal) |
makeFlag(IS_LAMBDA_FORM_HIDDEN_BIT, isLambdaFormHidden) |
makeFlag(IS_LINKED_BIT, isLinked));
makeFlag(IS_LINKED_BIT, isLinked) |
makeFlag(IS_PROXY_CLASS_BIT, isProxyClass));

this.companion = new DynamicHubCompanion(hostedJavaClass, classLoader);
}
Expand Down Expand Up @@ -494,7 +498,7 @@ public void setClassInitializationInfo(ClassInitializationInfo classInitializati

@Platforms(Platform.HOSTED_ONLY.class)
public void setSharedData(int layoutEncoding, int monitorOffset, int identityHashOffset,
long referenceMapIndex, boolean isInstantiated, boolean canInstantiateAsInstance, boolean isProxyClass,
long referenceMapIndex, boolean isInstantiated, boolean canInstantiateAsInstance,
boolean isRegisteredForSerialization) {
assert !(!isInstantiated && canInstantiateAsInstance);
VMError.guarantee(monitorOffset == (char) monitorOffset, "Class %s has an invalid monitor field offset. Most likely, its objects are larger than supported.", name);
Expand All @@ -510,7 +514,6 @@ public void setSharedData(int layoutEncoding, int monitorOffset, int identityHas
this.referenceMapIndex = (int) referenceMapIndex;
this.additionalFlags = NumUtil.safeToUByte(makeFlag(IS_INSTANTIATED_BIT, isInstantiated) |
makeFlag(CAN_INSTANTIATE_AS_INSTANCE_BIT, canInstantiateAsInstance) |
makeFlag(IS_PROXY_CLASS_BIT, isProxyClass) |
makeFlag(IS_REGISTERED_FOR_SERIALIZATION, isRegisteredForSerialization));
}

Expand Down Expand Up @@ -758,7 +761,7 @@ public boolean canInstantiateAsInstance() {
}

public boolean isProxyClass() {
return isFlagSet(additionalFlags, IS_PROXY_CLASS_BIT);
return isFlagSet(flags, IS_PROXY_CLASS_BIT);
}

@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,6 @@ public interface DynamicProxyRegistry extends RuntimeProxyCreationSupport {

Class<?> getProxyClass(ClassLoader loader, Class<?>... interfaces);

boolean isProxyClass(Class<?> clazz);

@Platforms(Platform.HOSTED_ONLY.class)
Class<?> createProxyClassForSerialization(Class<?>... interfaces);
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

import org.graalvm.nativeimage.ImageSingletons;

import com.oracle.svm.core.annotate.Delete;
import com.oracle.svm.core.annotate.Substitute;
import com.oracle.svm.core.annotate.TargetClass;
import com.oracle.svm.core.hub.DynamicHub;

@TargetClass(java.lang.reflect.Proxy.class)
final class Target_java_lang_reflect_Proxy {
Expand All @@ -56,7 +56,7 @@ private static Constructor<?> getProxyConstructor(Class<?> caller, ClassLoader l

@Substitute
public static boolean isProxyClass(Class<?> cl) {
return Proxy.class.isAssignableFrom(cl) && ImageSingletons.lookup(DynamicProxyRegistry.class).isProxyClass(cl);
return DynamicHub.fromClass(cl).isProxyClass();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,16 @@
package com.oracle.svm.core.reflect.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.regex.Pattern;

import org.graalvm.collections.EconomicMap;
import org.graalvm.collections.EconomicSet;
import org.graalvm.collections.Equivalence;
import org.graalvm.nativeimage.Platform;
import org.graalvm.nativeimage.Platforms;
import org.graalvm.nativeimage.hosted.RuntimeClassInitialization;
import org.graalvm.nativeimage.hosted.RuntimeReflection;

import com.oracle.svm.core.SubstrateUtil;
import com.oracle.svm.core.hub.DynamicHub;
import com.oracle.svm.core.hub.PredefinedClassesSupport;
import com.oracle.svm.core.jdk.proxy.DynamicProxyRegistry;
Expand Down Expand Up @@ -80,7 +78,6 @@ public String toString() {
}
}

private final EconomicSet<Class<?>> hostedProxyClasses = EconomicSet.create(Equivalence.IDENTITY);
private final EconomicMap<ProxyCacheKey, Object> proxyCache = ImageHeapMap.create();

@Platforms(Platform.HOSTED_ONLY.class)
Expand All @@ -103,7 +100,7 @@ public synchronized void addProxyClass(Class<?>... interfaces) {
}

@Platforms(Platform.HOSTED_ONLY.class)
private Object createProxyClass(Class<?>[] interfaces) {
private static Object createProxyClass(Class<?>[] interfaces) {
try {
Class<?> clazz = createProxyClassFromImplementedInterfaces(interfaces);

Expand Down Expand Up @@ -135,8 +132,6 @@ private Object createProxyClass(Class<?>[] interfaces) {
for (Class<?> intf : interfaces) {
RuntimeReflection.register(intf.getMethods());
}

hostedProxyClasses.add(clazz);
return clazz;
} catch (Throwable t) {
LogUtils.warning("Could not create a proxy class from list of interfaces: %s. Reason: %s", Arrays.toString(interfaces), t.getMessage());
Expand All @@ -152,8 +147,9 @@ public Class<?> createProxyClassForSerialization(Class<?>... interfaces) {
}

@Platforms(Platform.HOSTED_ONLY.class)
@SuppressWarnings("deprecation")
private static Class<?> createProxyClassFromImplementedInterfaces(Class<?>[] interfaces) {
return getJdkProxyClass(getCommonClassLoaderOrFail(null, interfaces), interfaces);
return Proxy.getProxyClass(getCommonClassLoaderOrFail(null, interfaces), interfaces);
}

private static ClassLoader getCommonClassLoaderOrFail(ClassLoader loader, Class<?>... intfs) {
Expand Down Expand Up @@ -226,23 +222,4 @@ private static void describeLoaderChain(StringBuilder b, ClassLoader loader) {
l = l.getParent();
}
}

@Override
public boolean isProxyClass(Class<?> clazz) {
if (SubstrateUtil.HOSTED) {
return isHostedProxyClass(clazz);
}
return DynamicHub.fromClass(clazz).isProxyClass();
}

@Platforms(Platform.HOSTED_ONLY.class)
private synchronized boolean isHostedProxyClass(Class<?> clazz) {
return hostedProxyClasses.contains(clazz);
}

@SuppressWarnings("deprecation")
@Platforms(Platform.HOSTED_ONLY.class)
public static Class<?> getJdkProxyClass(ClassLoader loader, Class<?>... interfaces) {
return java.lang.reflect.Proxy.getProxyClass(loader, interfaces);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;
import java.util.Collections;
import java.util.Comparator;
import java.util.EnumSet;
Expand Down Expand Up @@ -418,9 +419,15 @@ private DynamicHub createHub(AnalysisType type) {

nestHost = PredefinedClassesSupport.maybeAdjustLambdaNestHost(className, javaClass, classLoader, nestHost);

/*
* All proxy classes, even the ones that we create artificially via DynamicProxySupport, are
* proper proxy classes in the host VM.
*/
boolean isProxyClass = Proxy.isProxyClass(javaClass);

return new DynamicHub(javaClass, className, computeHubType(type), computeReferenceType(type), superHub, componentHub, sourceFileName, modifiers, hubClassLoader,
isHidden, isRecord, nestHost, assertionStatus, type.hasDefaultMethods(), type.declaresDefaultMethods(), isSealed, isVMInternal, isLambdaFormHidden, isLinked, simpleBinaryName,
getDeclaringClass(javaClass), getSignature(javaClass));
getDeclaringClass(javaClass), getSignature(javaClass), isProxyClass);
}

private static final Method getSignature = ReflectionUtil.lookupMethod(Class.class, "getGenericSignature0");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@
import com.oracle.svm.core.hub.DynamicHub;
import com.oracle.svm.core.hub.DynamicHubSupport;
import com.oracle.svm.core.hub.LayoutEncoding;
import com.oracle.svm.core.jdk.proxy.DynamicProxyRegistry;
import com.oracle.svm.core.meta.MethodPointer;
import com.oracle.svm.core.reflect.SubstrateConstructorAccessor;
import com.oracle.svm.core.reflect.SubstrateMethodAccessor;
Expand Down Expand Up @@ -1163,12 +1162,10 @@ private void buildHubs() {
assert ((SubstrateReferenceMap) referenceMap).hasNoDerivedOffsets();
long referenceMapIndex = referenceMapEncoder.lookupEncoding(referenceMap);

boolean isProxyClass = ImageSingletons.lookup(DynamicProxyRegistry.class).isProxyClass(type.getJavaClass());

DynamicHub hub = type.getHub();
SerializationRegistry s = ImageSingletons.lookup(SerializationRegistry.class);
hub.setSharedData(layoutHelper, monitorOffset, identityHashOffset,
referenceMapIndex, type.isInstantiated(), canInstantiateAsInstance, isProxyClass,
referenceMapIndex, type.isInstantiated(), canInstantiateAsInstance,
s.isRegisteredForSerialization(type.getJavaClass()));
if (SubstrateOptions.closedTypeWorld()) {
hub.setClosedWorldData(vtable, type.getTypeID(), type.getTypeCheckStart(), type.getTypeCheckRange(),
Expand Down