Skip to content

Commit c460f60

Browse files
committed
[GR-65058] Avoid direct intrinsification of Array#newInstance.
PullRequest: graal/20836
2 parents c8d83d3 + 8347f55 commit c460f60

File tree

7 files changed

+38
-10
lines changed

7 files changed

+38
-10
lines changed

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@
8686
import jdk.graal.compiler.core.common.memory.BarrierType;
8787
import jdk.graal.compiler.core.common.memory.MemoryOrderMode;
8888
import jdk.graal.compiler.core.common.spi.ForeignCallDescriptor;
89+
import jdk.graal.compiler.core.common.type.AbstractPointerStamp;
8990
import jdk.graal.compiler.core.common.type.ObjectStamp;
9091
import jdk.graal.compiler.core.common.type.StampFactory;
9192
import jdk.graal.compiler.core.common.type.TypeReference;
@@ -141,6 +142,7 @@
141142
import jdk.graal.compiler.nodes.calc.XorNode;
142143
import jdk.graal.compiler.nodes.extended.BranchProbabilityNode;
143144
import jdk.graal.compiler.nodes.extended.ForeignCallNode;
145+
import jdk.graal.compiler.nodes.extended.GuardingNode;
144146
import jdk.graal.compiler.nodes.extended.JavaReadNode;
145147
import jdk.graal.compiler.nodes.extended.JavaWriteNode;
146148
import jdk.graal.compiler.nodes.extended.LoadHubNode;
@@ -557,19 +559,20 @@ private static void registerArrayPlugins(InvocationPlugins plugins, Replacements
557559
@Override
558560
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode componentType, ValueNode length) {
559561
try (HotSpotInvocationPluginHelper helper = new HotSpotInvocationPluginHelper(b, targetMethod, config)) {
560-
// If (componentType == null) then deopt
561-
ValueNode nonNullComponentType = b.nullCheckedValue(componentType);
562+
// If (componentType == null) then take the fallback path
563+
GuardingNode guard = helper.doFallbackIf(IsNullNode.create(componentType), GraalDirectives.UNLIKELY_PROBABILITY);
564+
ValueNode nonNullComponentType = helper.piCast(componentType, guard, ((AbstractPointerStamp) componentType.stamp(NodeView.DEFAULT)).asNonNull());
562565
// Read Class.array_klass
563566
ValueNode arrayClass = helper.loadArrayKlass(nonNullComponentType);
564-
// Take the fallback path is the array klass is null
567+
// Take the fallback path if the array klass is null
565568
helper.doFallbackIf(IsNullNode.create(arrayClass), GraalDirectives.UNLIKELY_PROBABILITY);
566569
// Otherwise perform the array allocation
567-
helper.emitFinalReturn(JavaKind.Object, new DynamicNewArrayNode(nonNullComponentType, length,
568-
true));
570+
helper.emitFinalReturn(JavaKind.Object, new DynamicNewArrayNode(nonNullComponentType, length, true));
569571
}
570572
return true;
571573
}
572574
});
575+
r.register(StandardGraphBuilderPlugins.newArrayPlugin("newInstance"));
573576
}
574577

575578
private static void registerStringPlugins(InvocationPlugins plugins, Replacements replacements, WordTypes wordTypes, ArrayCopyForeignCalls foreignCalls, GraalHotSpotVMConfig vmConfig) {

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/replacements/StandardGraphBuilderPlugins.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -548,9 +548,8 @@ private static void registerArraysPlugins(InvocationPlugins plugins, Replacement
548548
r.registerConditional(ArrayFillNode.isSupported(arch), new ArrayFillInvocationPlugin(JavaKind.Double, double[].class, double.class));
549549
}
550550

551-
private static void registerArrayPlugins(InvocationPlugins plugins, Replacements replacements) {
552-
Registration r = new Registration(plugins, Array.class, replacements);
553-
r.register(new InvocationPlugin("newInstance", Class.class, int.class) {
551+
public static InvocationPlugin newArrayPlugin(final String methodName) {
552+
return new InvocationPlugin(methodName, Class.class, int.class) {
554553
@Override
555554
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver unused, ValueNode componentType, ValueNode length) {
556555
ValueNode componentTypeNonNull = b.nullCheckedValue(componentType);
@@ -562,7 +561,11 @@ public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Rec
562561
}
563562
return true;
564563
}
565-
});
564+
};
565+
}
566+
567+
private static void registerArrayPlugins(InvocationPlugins plugins, Replacements replacements) {
568+
Registration r = new Registration(plugins, Array.class, replacements);
566569
r.register(new InvocationPlugin("getLength", Object.class) {
567570
@Override
568571
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver unused, ValueNode object) {

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/plugins/PointstoGraphBuilderPlugins.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
*/
2525
package com.oracle.graal.pointsto.plugins;
2626

27+
import java.lang.reflect.Array;
28+
2729
import com.oracle.graal.pointsto.nodes.AnalysisObjectCloneNode;
2830

2931
import jdk.graal.compiler.nodes.ValueNode;
@@ -32,13 +34,19 @@
3234
import jdk.graal.compiler.nodes.graphbuilderconf.InvocationPlugin.RequiredInvocationPlugin;
3335
import jdk.graal.compiler.nodes.graphbuilderconf.InvocationPlugins;
3436
import jdk.graal.compiler.nodes.graphbuilderconf.InvocationPlugins.Registration;
37+
import jdk.graal.compiler.replacements.StandardGraphBuilderPlugins;
3538
import jdk.graal.compiler.replacements.arraycopy.ArrayCopySnippets;
3639
import jdk.graal.compiler.replacements.nodes.MacroNode.MacroParams;
3740
import jdk.vm.ci.meta.JavaKind;
3841
import jdk.vm.ci.meta.ResolvedJavaMethod;
3942

4043
public class PointstoGraphBuilderPlugins {
4144

45+
public static void registerArrayPlugins(InvocationPlugins plugins) {
46+
Registration r = new Registration(plugins, Array.class);
47+
r.register(StandardGraphBuilderPlugins.newArrayPlugin("newInstance"));
48+
}
49+
4250
public static void registerSystemPlugins(InvocationPlugins plugins) {
4351
Registration r = new Registration(plugins, System.class).setAllowOverwrite(true);
4452
ArrayCopySnippets.registerSystemArraycopyPlugin(r);

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/graal/jdk/SubstrateObjectCloneSnippets.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ private static Object doClone(Object original) throws CloneNotSupportedException
112112
if (isArrayLike) {
113113
if (BranchProbabilityNode.probability(FAST_PATH_PROBABILITY, LayoutEncoding.isArray(layoutEncoding))) {
114114
int length = ArrayLengthNode.arrayLength(original);
115-
Object newArray = java.lang.reflect.Array.newInstance(DynamicHub.toClass(hub.getComponentHub()), length);
115+
Object newArray = KnownIntrinsics.unvalidatedNewArray(DynamicHub.toClass(hub.getComponentHub()), length);
116116
if (LayoutEncoding.isObjectArray(layoutEncoding)) {
117117
JavaMemoryUtil.copyObjectArrayForward(original, 0, newArray, 0, length, layoutEncoding);
118118
} else {

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JavaLangReflectSubstitutions.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import com.oracle.svm.core.hub.DynamicHub;
3939
import com.oracle.svm.core.hub.LayoutEncoding;
4040
import com.oracle.svm.core.reflect.MissingReflectionRegistrationUtils;
41+
import com.oracle.svm.core.snippets.KnownIntrinsics;
4142

4243
import jdk.graal.compiler.word.BarrieredAccess;
4344

@@ -382,6 +383,12 @@ private static void set(Object a, int index, Object value) {
382383
throw new IllegalArgumentException();
383384
}
384385

386+
@Substitute
387+
private static Object newArray(Class<?> componentType, int length)
388+
throws NegativeArraySizeException {
389+
return KnownIntrinsics.unvalidatedNewArray(componentType, length);
390+
}
391+
385392
@Substitute
386393
private static Object multiNewArray(Class<?> componentType, int[] dimensions) {
387394
if (componentType == null) {

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/snippets/KnownIntrinsics.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,4 +123,10 @@ public class KnownIntrinsics {
123123
* the static analysis, and without the check that the class is already initialized.
124124
*/
125125
public static native Object unvalidatedAllocateInstance(Class<?> hub);
126+
127+
/**
128+
* Like {@link java.lang.reflect.Array#newInstance(Class, int)} but without the checks that the
129+
* array of the desired class is registered for reflection.
130+
*/
131+
public static native Object unvalidatedNewArray(Class<?> componentType, int length) throws NegativeArraySizeException;
126132
}

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/snippets/SubstrateGraphBuilderPlugins.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1019,6 +1019,7 @@ public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Rec
10191019
return true;
10201020
}
10211021
});
1022+
r.register(StandardGraphBuilderPlugins.newArrayPlugin("unvalidatedNewArray"));
10221023

10231024
registerCastExact(r);
10241025
}

0 commit comments

Comments
 (0)