src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/EscapeAnalysisTest.java
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File
*** old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/EscapeAnalysisTest.java Mon Mar 20 17:37:40 2017
--- new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/EscapeAnalysisTest.java Mon Mar 20 17:37:40 2017
*** 1,7 ****
--- 1,7 ----
/*
! * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
! * Copyright (c) 2011, 2017, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*** 20,44 ****
--- 20,49 ----
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.graalvm.compiler.core.test.ea;
! import jdk.vm.ci.meta.JavaConstant;
import org.junit.Assert;
import org.junit.Test;
! import java.util.List;
import org.graalvm.compiler.graph.Node;
import org.graalvm.compiler.loop.DefaultLoopPolicies;
import org.graalvm.compiler.loop.phases.LoopFullUnrollPhase;
import org.graalvm.compiler.loop.phases.LoopPeelingPhase;
+ import org.graalvm.compiler.nodes.ConstantNode;
+ import org.graalvm.compiler.nodes.ReturnNode;
+ import org.graalvm.compiler.nodes.extended.BoxNode;
import org.graalvm.compiler.nodes.extended.ValueAnchorNode;
+ import org.graalvm.compiler.nodes.java.LoadFieldNode;
import org.graalvm.compiler.nodes.virtual.AllocatedObjectNode;
import org.graalvm.compiler.nodes.virtual.CommitAllocationNode;
import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.graalvm.compiler.phases.schedule.SchedulePhase;
import org.graalvm.compiler.virtual.phases.ea.PartialEscapePhase;
+ import org.junit.Assert;
+ import org.junit.Test;
+
+ import jdk.vm.ci.meta.JavaConstant;
/**
* The PartialEscapeAnalysisPhase is expected to remove all allocations and return the correct
* values.
*/
*** 178,187 ****
--- 183,236 ----
}
return obj.x <= 3 ? 1 : 0;
}
@Test
+ public void testMergeAllocationsInt2() {
+ testEscapeAnalysis("testMergeAllocationsInt2Snippet", JavaConstant.forInt(1), true);
+ }
+
+ public int testMergeAllocationsInt2Snippet(int a) {
+ /*
+ * The initial object in obj exists until the end of the function, but it can still be
+ * merged with the one allocated in the else block because noone can observe the identity.
+ */
+ TestClassInt obj = new TestClassInt(1, 2);
+ if (a < 0) {
+ notInlineable();
+ } else {
+ obj = new TestClassInt(1, 2);
+ notInlineable();
+ }
+ return obj.x <= 3 ? 1 : 0;
+ }
+
+ @Test
+ public void testMergeAllocationsInt3() {
+ // ensure that the result is not constant:
+ assertTrue(testMergeAllocationsInt3Snippet(true));
+ assertFalse(testMergeAllocationsInt3Snippet(false));
+
+ prepareGraph("testMergeAllocationsInt3Snippet", true);
+ assertFalse(graph.getNodes().filter(ReturnNode.class).first().result().isConstant());
+ }
+
+ public boolean testMergeAllocationsInt3Snippet(boolean a) {
+ TestClassInt phi1;
+ TestClassInt phi2;
+ if (a) {
+ field = new TestClassObject();
+ field = new TestClassObject();
+ phi1 = phi2 = new TestClassInt(1, 2);
+ } else {
+ phi1 = new TestClassInt(2, 3);
+ phi2 = new TestClassInt(3, 4);
+ }
+ return phi1 == phi2;
+ }
+
+ @Test
public void testMergeAllocationsObj() {
testEscapeAnalysis("testMergeAllocationsObjSnippet", JavaConstant.forInt(1), false);
}
public int testMergeAllocationsObjSnippet(int a) {
*** 257,269 ****
--- 306,382 ----
notInlineable();
}
return obj.value <= 3 ? 1 : 0;
}
+ /**
+ * Tests that a graph with allocations that does not make progress during PEA will not be
+ * changed.
+ */
+ @Test
+ public void testChangeHandling() {
+ prepareGraph("testChangeHandlingSnippet", false);
+ Assert.assertEquals(2, graph.getNodes().filter(CommitAllocationNode.class).count());
+ Assert.assertEquals(1, graph.getNodes().filter(BoxNode.class).count());
+ List<Node> nodes = graph.getNodes().snapshot();
+ // verify that an additional run doesn't add or remove nodes
+ new PartialEscapePhase(false, false, new CanonicalizerPhase(), null, graph.getOptions()).apply(graph, context);
+ Assert.assertEquals(nodes.size(), graph.getNodeCount());
+ for (Node node : nodes) {
+ Assert.assertTrue(node.isAlive());
+ }
+ }
+
+ public volatile Object field;
+
+ public int testChangeHandlingSnippet(int a) {
+ Object obj;
+ Integer one = 1;
+ obj = new MyException(one);
+ if (a < 0) {
+ notInlineable();
+ } else {
+ obj = new Integer(1);
+ notInlineable();
+ }
+ field = obj;
+ return 1;
+ }
+
+ /**
+ * Test the case where allocations before and during a loop that have no usages other than their
+ * phi need to be recognized as an important change. This needs a loop so that the allocation is
+ * not trivially removed by dead code elimination.
+ */
+ @Test
+ public void testRemovalSpecialCase() {
+ prepareGraph("testRemovalSpecialCaseSnippet", false);
+ Assert.assertEquals(2, graph.getNodes().filter(CommitAllocationNode.class).count());
+ // create the situation by removing the if
+ graph.replaceFixedWithFloating(graph.getNodes().filter(LoadFieldNode.class).first(), graph.unique(ConstantNode.forInt(0)));
+ new CanonicalizerPhase().apply(graph, context);
+ // verify that an additional run removes all allocations
+ new PartialEscapePhase(false, false, new CanonicalizerPhase(), null, graph.getOptions()).apply(graph, context);
+ Assert.assertEquals(0, graph.getNodes().filter(CommitAllocationNode.class).count());
+ }
+
+ public volatile int field2;
+
+ public int testRemovalSpecialCaseSnippet(int a) {
+ Object phi = new Object();
+ for (int i = 0; i < a; i++) {
+ field = null;
+ if (field2 == 1) {
+ phi = new Object();
+ }
+ }
+ return phi == null ? 1 : 0;
+ }
+
@Test
public void testCheckCast() {
! testEscapeAnalysis("testCheckCastSnippet", getSnippetReflection().forObject(TestClassObject.class), false);
! testEscapeAnalysis("testCheckCastSnippet", getSnippetReflection().forObject(TestClassObject.class), true);
}
public Object testCheckCastSnippet() {
TestClassObject obj = new TestClassObject(TestClassObject.class);
TestClassObject obj2 = new TestClassObject(obj);
*** 312,322 ****
--- 425,435 ----
@Test
public void testFullyUnrolledLoop() {
prepareGraph("testFullyUnrolledLoopSnippet", false);
new LoopFullUnrollPhase(new CanonicalizerPhase(), new DefaultLoopPolicies()).apply(graph, context);
! new PartialEscapePhase(false, new CanonicalizerPhase(), graph.getOptions()).apply(graph, context);
Assert.assertEquals(1, returnNodes.size());
Assert.assertTrue(returnNodes.get(0).result() instanceof AllocatedObjectNode);
CommitAllocationNode commit = ((AllocatedObjectNode) returnNodes.get(0).result()).getCommit();
Assert.assertEquals(2, commit.getValues().size());
Assert.assertEquals(1, commit.getVirtualObjects().size());
*** 343,353 ****
--- 456,466 ----
@Test
public void testPeeledLoop() {
prepareGraph("testPeeledLoopSnippet", false);
new LoopPeelingPhase(new DefaultLoopPolicies()).apply(graph, getDefaultHighTierContext());
! new SchedulePhase(graph.getOptions()).apply(graph);
}
public static void testDeoptMonitorSnippetInner(Object o2, Object t, int i) {
staticField = null;
if (i == 0) {
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/EscapeAnalysisTest.java
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File