src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ArrayEqualsNode.java
changeset 54204 55c262f4f5a1
parent 52910 583fd71c47d6
child 54328 37648a9c4a6a
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ArrayEqualsNode.java	Wed Mar 20 17:28:29 2019 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ArrayEqualsNode.java	Wed Mar 20 22:53:44 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, 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
@@ -26,11 +26,14 @@
 
 import static org.graalvm.compiler.nodeinfo.InputType.Memory;
 
+import org.graalvm.compiler.api.replacements.Snippet;
+import org.graalvm.compiler.core.common.spi.ForeignCallLinkage;
 import org.graalvm.compiler.core.common.type.StampFactory;
 import org.graalvm.compiler.graph.Node;
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.graph.spi.Canonicalizable;
 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
+import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
 import org.graalvm.compiler.nodeinfo.NodeCycles;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodeinfo.NodeSize;
@@ -48,11 +51,14 @@
 import org.graalvm.compiler.nodes.spi.VirtualizerTool;
 import org.graalvm.compiler.nodes.util.GraphUtil;
 import org.graalvm.compiler.nodes.virtual.VirtualObjectNode;
+import org.graalvm.compiler.options.Option;
+import org.graalvm.compiler.options.OptionKey;
 import jdk.internal.vm.compiler.word.LocationIdentity;
 
 import jdk.vm.ci.meta.ConstantReflectionProvider;
 import jdk.vm.ci.meta.JavaConstant;
 import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
 import jdk.vm.ci.meta.Value;
 
 // JaCoCo Exclude
@@ -63,6 +69,13 @@
 @NodeInfo(cycles = NodeCycles.CYCLES_UNKNOWN, size = NodeSize.SIZE_128)
 public final class ArrayEqualsNode extends FixedWithNextNode implements LIRLowerable, Canonicalizable, Virtualizable, MemoryAccess {
 
+    public static class Options {
+        // @formatter:off
+        @Option(help = "Use Array equals stubs instead of embedding all the emitted code.")
+        public static final OptionKey<Boolean> ArrayEqualsStubs = new OptionKey<>(true);
+        // @formatter:on
+    }
+
     public static final NodeClass<ArrayEqualsNode> TYPE = NodeClass.create(ArrayEqualsNode.class);
     /** {@link JavaKind} of the arrays to compare. */
     protected final JavaKind kind;
@@ -178,7 +191,7 @@
     }
 
     @NodeIntrinsic
-    static native boolean equals(Object array1, Object array2, int length, @ConstantNodeParameter JavaKind kind);
+    public static native boolean equals(Object array1, Object array2, int length, @ConstantNodeParameter JavaKind kind);
 
     public static boolean equals(boolean[] array1, boolean[] array2, int length) {
         return equals(array1, array2, length, JavaKind.Boolean);
@@ -214,11 +227,25 @@
 
     @Override
     public void generate(NodeLIRBuilderTool gen) {
+        LIRGeneratorTool tool = gen.getLIRGeneratorTool();
         int constantLength = -1;
         if (length.isConstant()) {
             constantLength = length.asJavaConstant().asInt();
         }
-        Value result = gen.getLIRGeneratorTool().emitArrayEquals(kind, gen.operand(array1), gen.operand(array2), gen.operand(length), constantLength, false);
+
+        if (Options.ArrayEqualsStubs.getValue(graph().getOptions())) {
+            ResolvedJavaMethod method = graph().method();
+            if (method != null && method.getAnnotation(Snippet.class) == null) {
+                ForeignCallLinkage linkage = tool.lookupArrayEqualsStub(kind, constantLength);
+                if (linkage != null) {
+                    Value result = tool.emitForeignCall(linkage, null, gen.operand(array1), gen.operand(array2), gen.operand(length));
+                    gen.setResult(this, result);
+                    return;
+                }
+            }
+        }
+
+        Value result = tool.emitArrayEquals(kind, gen.operand(array1), gen.operand(array2), gen.operand(length), constantLength, false);
         gen.setResult(this, result);
     }