Skip to content

Commit

Permalink
Use EconomicSet for JNIAccessibleMember.hidingSubclasses.
Browse files Browse the repository at this point in the history
  • Loading branch information
peter-hofer committed Jul 18, 2022
1 parent e6a0296 commit 8361841
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@
package com.oracle.svm.core.jni.access;

import java.lang.reflect.Modifier;
import java.util.Map;

import org.graalvm.collections.EconomicSet;
import org.graalvm.nativeimage.Platform.HOSTED_ONLY;
import org.graalvm.nativeimage.Platforms;
import org.graalvm.word.UnsignedWord;
Expand Down Expand Up @@ -99,7 +99,7 @@ public boolean isStatic() {
}

@Platforms(HOSTED_ONLY.class)
public void finishBeforeCompilation(int offset, Map<Class<?>, Void> hidingSubclasses) {
public void finishBeforeCompilation(int offset, EconomicSet<Class<?>> hidingSubclasses) {
assert id.equal(0);
assert ID_OFFSET_MASK.and(offset).equal(offset) : "Offset is too large to be encoded in the JNIAccessibleField ID";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,17 @@
*/
package com.oracle.svm.core.jni.access;

import java.util.IdentityHashMap;
import java.util.Map;
import org.graalvm.collections.EconomicSet;
import org.graalvm.nativeimage.Platform;
import org.graalvm.nativeimage.Platforms;

import com.oracle.svm.core.annotate.UnknownObjectField;

abstract class JNIAccessibleMember {
private final JNIAccessibleClass declaringClass;

@UnknownObjectField(types = IdentityHashMap.class, canBeNull = true) //
private Map<Class<?>, Void> hidingSubclasses;
@UnknownObjectField(fullyQualifiedTypes = "org.graalvm.collections.EconomicMapImpl", canBeNull = true) //
private EconomicSet<Class<?>> hidingSubclasses;

JNIAccessibleMember(JNIAccessibleClass declaringClass) {
this.declaringClass = declaringClass;
Expand All @@ -47,7 +48,7 @@ boolean isDiscoverableIn(Class<?> clazz) {
Class<?> declaring = declaringClass.getClassObject();
assert clazz != null && declaring.isAssignableFrom(clazz);
if (hidingSubclasses != null && !clazz.equals(declaring)) {
if (hidingSubclasses.containsKey(clazz)) {
if (hidingSubclasses.contains(clazz)) {
return false;
}
if (declaring.isInterface()) {
Expand All @@ -65,7 +66,8 @@ boolean isDiscoverableIn(Class<?> clazz) {
return true;
}

protected void setHidingSubclasses(Map<Class<?>, Void> hidingSubclasses) {
@Platforms(Platform.HOSTED_ONLY.class)
protected void setHidingSubclasses(EconomicSet<Class<?>> hidingSubclasses) {
assert this.hidingSubclasses == null;
this.hidingSubclasses = hidingSubclasses;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@
package com.oracle.svm.core.jni.access;

import java.lang.reflect.Modifier;
import java.util.Map;

import org.graalvm.collections.EconomicSet;
import org.graalvm.compiler.nodes.NamedLocationIdentity;
import org.graalvm.compiler.word.BarrieredAccess;
import org.graalvm.nativeimage.Platform.HOSTED_ONLY;
Expand Down Expand Up @@ -122,13 +122,13 @@ boolean isStatic() {
}

@Platforms(HOSTED_ONLY.class)
public void finishBeforeCompilation(Map<Class<?>, Void> hidingSubclasses, int vtableEntryOffset, CodePointer nonvirtualTargetEntry, PointerBase newObjectTargetEntry, CodePointer callWrapperEntry,
public void finishBeforeCompilation(EconomicSet<Class<?>> hidingSubclasses, int vtableEntryOffset, CodePointer nonvirtualEntry, PointerBase newObjectEntry, CodePointer callWrapperEntry,
CodePointer varargs, CodePointer array, CodePointer valist, CodePointer varargsNonvirtual, CodePointer arrayNonvirtual, CodePointer valistNonvirtual) {
assert this.vtableOffset == VTABLE_OFFSET_NOT_YET_COMPUTED && (vtableEntryOffset == STATICALLY_BOUND_METHOD || vtableEntryOffset >= 0);

this.vtableOffset = vtableEntryOffset;
this.nonvirtualTarget = nonvirtualTargetEntry;
this.newObjectTarget = newObjectTargetEntry;
this.nonvirtualTarget = nonvirtualEntry;
this.newObjectTarget = newObjectEntry;
this.callWrapper = callWrapperEntry;
this.varargsWrapper = varargs;
this.arrayWrapper = array;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,15 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Predicate;
import java.util.stream.Stream;

import org.graalvm.collections.EconomicSet;
import org.graalvm.collections.Equivalence;
import org.graalvm.collections.UnmodifiableMapCursor;
import org.graalvm.compiler.api.replacements.Fold;
import org.graalvm.compiler.options.Option;
Expand Down Expand Up @@ -508,7 +509,7 @@ private static void finishMethodBeforeCompilation(JNICallableJavaMethod method,
arrayNonvirtual = new MethodPointer(hUniverse.lookup(aUniverse.lookup(method.nonvirtualVariantWrappers.array)));
valistNonvirtual = new MethodPointer(hUniverse.lookup(aUniverse.lookup(method.nonvirtualVariantWrappers.valist)));
}
Map<Class<?>, Void> hidingSubclasses = findHidingSubclasses(hTarget.getDeclaringClass(), sub -> anyMethodMatchesIgnoreReturnType(sub, method.descriptor), null);
EconomicSet<Class<?>> hidingSubclasses = findHidingSubclasses(hTarget.getDeclaringClass(), sub -> anyMethodMatchesIgnoreReturnType(sub, method.descriptor), null);
method.jniMethod.finishBeforeCompilation(hidingSubclasses, vtableOffset, nonvirtualTarget, newObjectTarget, callWrapper,
varargs, array, valist, varargsNonvirtual, arrayNonvirtual, valistNonvirtual);
}
Expand Down Expand Up @@ -538,8 +539,8 @@ private static boolean anyMethodMatchesIgnoreReturnType(ResolvedJavaType sub, JN
* Determines which subclasses of a member's declaring class contain a declaration that cause
* this member to be hidden in that subclass and all of its subclasses.
*/
private static Map<Class<?>, Void> findHidingSubclasses(HostedType type, Predicate<ResolvedJavaType> predicate, Map<Class<?>, Void> existing) {
Map<Class<?>, Void> map = existing;
private static EconomicSet<Class<?>> findHidingSubclasses(HostedType type, Predicate<ResolvedJavaType> predicate, EconomicSet<Class<?>> existing) {
EconomicSet<Class<?>> map = existing;
/*
* HostedType.getSubTypes() only gives us subtypes that are part of our analyzed closed
* world, but this is fine because JNI lookups can only be done on those.
Expand All @@ -557,9 +558,9 @@ private static Map<Class<?>, Void> findHidingSubclasses(HostedType type, Predica
assert !(originalType instanceof WrappedJavaType) : "need fully unwrapped type for member lookups";
if (predicate.test(originalType)) {
if (map == null) {
map = new IdentityHashMap<>();
map = EconomicSet.create(Equivalence.IDENTITY);
}
map.put(subType.getJavaClass(), null);
map.add(subType.getJavaClass());
// no need to explore further subclasses
} else {
map = findHidingSubclasses(subType, predicate, map);
Expand Down Expand Up @@ -587,7 +588,7 @@ private static void finishFieldBeforeCompilation(String name, JNIAccessibleField
assert hField.hasLocation();
offset = hField.getLocation();
}
Map<Class<?>, Void> hidingSubclasses = findHidingSubclasses(hField.getDeclaringClass(), sub -> anyFieldMatches(sub, name), null);
EconomicSet<Class<?>> hidingSubclasses = findHidingSubclasses(hField.getDeclaringClass(), sub -> anyFieldMatches(sub, name), null);

field.finishBeforeCompilation(offset, hidingSubclasses);

Expand Down

0 comments on commit 8361841

Please sign in to comment.