Skip to content

Commit 32078dc

Browse files
committed
Use tempTargetAllowList instead of substitutions for Vector API
1 parent 3b0939a commit 32078dc

File tree

2 files changed

+75
-470
lines changed

2 files changed

+75
-470
lines changed

substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/TruffleFeature.java

Lines changed: 75 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@
118118
import com.oracle.svm.core.graal.meta.SubstrateForeignCallsProvider;
119119
import com.oracle.svm.core.graal.snippets.NodeLoweringProvider;
120120
import com.oracle.svm.core.heap.Heap;
121+
import com.oracle.svm.core.jdk.VectorAPIEnabled;
121122
import com.oracle.svm.core.option.HostedOptionKey;
122123
import com.oracle.svm.core.option.HostedOptionValues;
123124
import com.oracle.svm.core.option.SubstrateOptionsParser;
@@ -695,6 +696,59 @@ private void initializeMethodBlocklist(MetaAccessProvider metaAccess, FeatureAcc
695696

696697
tempTargetAllowlistMethod(metaAccess, Object.class, "equals", Object.class);
697698
tempTargetAllowlistMethod(metaAccess, Object.class, "hashCode");
699+
700+
if (VectorAPIEnabled.getValue()) {
701+
Class<?> abstractMaskClass = ReflectionUtil.lookupClass("jdk.incubator.vector.AbstractMask");
702+
Class<?> abstractSpeciesClass = ReflectionUtil.lookupClass("jdk.incubator.vector.AbstractSpecies");
703+
Class<?> abstractVectorClass = ReflectionUtil.lookupClass("jdk.incubator.vector.AbstractVector");
704+
Class<?> laneTypeClass = ReflectionUtil.lookupClass("jdk.incubator.vector.LaneType");
705+
Class<?> binaryClass = ReflectionUtil.lookupClass("jdk.incubator.vector.VectorOperators$Binary");
706+
Class<?> operatorImplClass = ReflectionUtil.lookupClass("jdk.incubator.vector.VectorOperators$OperatorImpl");
707+
Class<?> unaryClass = ReflectionUtil.lookupClass("jdk.incubator.vector.VectorOperators$Unary");
708+
Class<?> vectorClass = ReflectionUtil.lookupClass("jdk.incubator.vector.Vector");
709+
Class<?> vectorIntrinsicsClass = ReflectionUtil.lookupClass("jdk.incubator.vector.VectorIntrinsics");
710+
Class<?> vectorShapeClass = ReflectionUtil.lookupClass("jdk.incubator.vector.VectorShape");
711+
Class<?> vectorSpeciesClass = ReflectionUtil.lookupClass("jdk.incubator.vector.VectorSpecies");
712+
Class<?> vectorSupportClass = ReflectionUtil.lookupClass("jdk.internal.vm.vector.VectorSupport");
713+
714+
/*
715+
* The methods of the VectorSupport class have intrinsics in VectorAPIIntrinsics. On
716+
* fast paths, those should be used instead of the Java fallback implementation. Since
717+
* we do not rely on these methods on fast paths, we can omit them from PE to reduce the
718+
* number of methods needed for runtime compilation and to avoid blocklist violations.
719+
*/
720+
blocklistAllMethods(metaAccess, vectorSupportClass);
721+
tempTargetAllowlistAllMethods(metaAccess, vectorSupportClass);
722+
723+
/*
724+
* VectorMathLibrary is an extension to VectorSupport that has two more intrinsic
725+
* candidates.
726+
*/
727+
Class<?> vectorMathLibraryClass = ReflectionUtil.lookupClass(true, "jdk.incubator.vector.VectorMathLibrary");
728+
if (vectorMathLibraryClass != null) {
729+
markTruffleBoundary(metaAccess, vectorMathLibraryClass, "unaryMathOp", unaryClass, int.class, vectorSpeciesClass, IntFunction.class, vectorClass);
730+
markTruffleBoundary(metaAccess, vectorMathLibraryClass, "binaryMathOp", binaryClass, int.class, vectorSpeciesClass, IntFunction.class, vectorClass, vectorClass);
731+
}
732+
733+
/* Utils.isNonCapturingLambda is removed by VectorAPIIntrinsics */
734+
Class<?> utilsClass = ReflectionUtil.lookupClass(true, "jdk.internal.vm.vector.Utils");
735+
if (utilsClass != null) {
736+
markTruffleBoundary(metaAccess, utilsClass, "isNonCapturingLambda", Object.class);
737+
}
738+
739+
/* Vector API slow-path methods */
740+
markTruffleBoundary(metaAccess, abstractMaskClass, "checkIndexFailed", long.class, int.class, long.class, int.class);
741+
markTruffleBoundary(metaAccess, abstractSpeciesClass, "badArrayBits", Object.class, boolean.class, long.class);
742+
markTruffleBoundary(metaAccess, abstractSpeciesClass, "badElementBits", long.class, Object.class);
743+
markTruffleBoundary(metaAccess, abstractSpeciesClass, "checkFailed", Object.class, Object.class);
744+
markTruffleBoundary(metaAccess, abstractVectorClass, "wrongPart", abstractSpeciesClass, abstractSpeciesClass, boolean.class, int.class);
745+
markTruffleBoundary(metaAccess, laneTypeClass, "badElementType", Class.class, Object.class);
746+
markTruffleBoundary(metaAccess, operatorImplClass, "illegalOperation", int.class, int.class);
747+
markTruffleBoundary(metaAccess, vectorIntrinsicsClass, "requireLengthFailed", int.class, int.class);
748+
749+
/* Made obsolete by VectorAPIFeature's precomputation of the species */
750+
markTruffleBoundary(metaAccess, abstractSpeciesClass, "computeSpecies", laneTypeClass, vectorShapeClass);
751+
}
698752
}
699753

700754
private void blocklistAllMethods(MetaAccessProvider metaAccess, Class<?> clazz) {
@@ -714,6 +768,15 @@ private void blocklistMethod(MetaAccessProvider metaAccess, Class<?> clazz, Stri
714768
}
715769
}
716770

771+
private void tempTargetAllowlistAllMethods(MetaAccessProvider metaAccess, Class<?> clazz) {
772+
for (Executable m : clazz.getMethods()) {
773+
tempTargetAllowlistMethods.add(metaAccess.lookupJavaMethod(m));
774+
}
775+
for (Executable m : clazz.getConstructors()) {
776+
tempTargetAllowlistMethods.add(metaAccess.lookupJavaMethod(m));
777+
}
778+
}
779+
717780
private void tempTargetAllowlistMethod(MetaAccessProvider metaAccess, Class<?> clazz, String name, Class<?>... parameterTypes) {
718781
try {
719782
tempTargetAllowlistMethods.add(metaAccess.lookupJavaMethod(clazz.getDeclaredMethod(name, parameterTypes)));
@@ -722,6 +785,15 @@ private void tempTargetAllowlistMethod(MetaAccessProvider metaAccess, Class<?> c
722785
}
723786
}
724787

788+
/**
789+
* Effectively puts a {@link TruffleBoundary} on an existing method by {@link #blocklistMethod
790+
* blocklisting} it and {@link #tempTargetAllowlistMethod allowlisting} it.
791+
*/
792+
private void markTruffleBoundary(MetaAccessProvider metaAccess, Class<?> clazz, String name, Class<?>... parameterTypes) {
793+
blocklistMethod(metaAccess, clazz, name, parameterTypes);
794+
tempTargetAllowlistMethod(metaAccess, clazz, name, parameterTypes);
795+
}
796+
725797
/**
726798
* Removes a previously blocklisted method from the blocklist.
727799
*/
@@ -777,14 +849,9 @@ private void checkBlockList(CallTreeInfo treeInfo) {
777849

778850
// Determine blocklist violations
779851
if (!runtimeCompilationForbidden(candidate.getImplementationMethod())) {
780-
if (isBlocklisted(candidate.getImplementationMethod())) {
781-
boolean tempAllow = !candidate.getTargetMethod().equals(candidate.getImplementationMethod()) &&
782-
tempTargetAllowlistMethods.contains(candidate.getTargetMethod()) &&
783-
!isBlocklisted(candidate.getImplementationMethod());
784-
if (!tempAllow) {
785-
BlocklistViolationInfo violation = new BlocklistViolationInfo(candidate, runtimeCompilation.getCallTrace(treeInfo, candidate));
786-
blocklistViolations.add(violation);
787-
}
852+
if (isBlocklisted(candidate.getImplementationMethod()) && !tempTargetAllowlistMethods.contains(candidate.getTargetMethod())) {
853+
BlocklistViolationInfo violation = new BlocklistViolationInfo(candidate, runtimeCompilation.getCallTrace(treeInfo, candidate));
854+
blocklistViolations.add(violation);
788855
}
789856
}
790857
}

0 commit comments

Comments
 (0)