1 /* 2 * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 package org.graalvm.compiler.core.test; 24 25 import org.graalvm.compiler.core.phases.HighTier; 26 import org.graalvm.compiler.core.phases.MidTier; 27 import org.graalvm.compiler.nodes.InvokeNode; 28 import org.graalvm.compiler.nodes.InvokeWithExceptionNode; 29 import org.graalvm.compiler.nodes.StructuredGraph; 30 import org.graalvm.compiler.nodes.extended.LoadHubNode; 31 import org.graalvm.compiler.nodes.extended.LoadMethodNode; 32 import org.graalvm.compiler.options.OptionValues; 33 import org.graalvm.compiler.phases.OptimisticOptimizations; 34 import org.graalvm.compiler.phases.tiers.MidTierContext; 35 import org.junit.Assert; 36 import org.junit.Test; 37 38 public class HashCodeTest extends GraalCompilerTest { 39 40 static class OverrideHashCode { 41 @Override 42 public int hashCode() { 43 return 42; 44 } 45 } 46 47 static final class DontOverrideHashCode { 48 } 49 50 public static final Object NonOverridingConstant = new Object(); 51 public static final Object OverridingConstant = new OverrideHashCode(); 52 53 private static void initialize(Class<?> c) { 54 try { 55 Class.forName(c.getName(), true, c.getClassLoader()); 56 } catch (ClassNotFoundException e) { 57 throw new AssertionError(e); 58 } 59 } 60 61 public static final int hashCodeSnippet01(Object o) { 62 return o.hashCode(); 63 } 64 65 public static final int systemIdentityHashCodeSnippet01(Object o) { 66 return System.identityHashCode(o); 67 } 68 69 public static final int hashCodeFoldSnippet01() { 70 return NonOverridingConstant.hashCode(); 71 } 72 73 public static final int identityHashCodeFoldSnippet01() { 74 return System.identityHashCode(NonOverridingConstant); 75 } 76 77 public static final int hashCodeNoFoldOverridingSnippet01(Object o) { 78 return o.hashCode(); 79 } 80 81 public static final int identityHashCodeFoldOverridingSnippet01() { 82 return System.identityHashCode(OverridingConstant); 83 } 84 85 public static final int dontOverrideHashCodeFinalClass(DontOverrideHashCode o) { 86 return o.hashCode(); 87 } 88 89 @Test 90 public void test01() { 91 test("hashCodeSnippet01", new Object()); 92 } 93 94 @Test 95 public void test02() { 96 test("systemIdentityHashCodeSnippet01", new Object()); 97 } 98 99 @Test 100 public void test03() { 101 StructuredGraph g = buildGraphAfterMidTier("hashCodeFoldSnippet01"); 102 Assert.assertEquals(0, g.getNodes().filter(InvokeNode.class).count()); 103 } 104 105 @Test 106 public void test04() { 107 StructuredGraph g = buildGraphAfterMidTier("identityHashCodeFoldSnippet01"); 108 Assert.assertEquals(0, g.getNodes().filter(InvokeNode.class).count()); 109 } 110 111 @Test 112 public void test05() { 113 checkForGuardedIntrinsicPattern("hashCodeNoFoldOverridingSnippet01"); 114 115 Object nullObject = null; 116 test("hashCodeNoFoldOverridingSnippet01", nullObject); 117 test("hashCodeNoFoldOverridingSnippet01", new Object()); 118 test("hashCodeNoFoldOverridingSnippet01", new DontOverrideHashCode()); 119 } 120 121 @Test 122 public void test06() { 123 StructuredGraph g = buildGraphAfterMidTier("identityHashCodeFoldOverridingSnippet01"); 124 Assert.assertEquals(0, g.getNodes().filter(InvokeNode.class).count()); 125 } 126 127 @Test 128 public void test07() { 129 initialize(DontOverrideHashCode.class); 130 StructuredGraph g = buildGraphAfterMidTier("dontOverrideHashCodeFinalClass"); 131 Assert.assertEquals(0, g.getNodes().filter(InvokeNode.class).count()); 132 } 133 134 public static final int hashCodeInterface(Appendable o) { 135 return o.hashCode(); 136 } 137 138 @Test 139 public void test08() { 140 initialize(Appendable.class); 141 checkForGuardedIntrinsicPattern("hashCodeInterface"); 142 checkForGuardedIntrinsicPattern("hashCodeSnippet01"); 143 } 144 145 private void checkForGuardedIntrinsicPattern(String name) { 146 StructuredGraph g = parseForCompile(getResolvedJavaMethod(name)); 147 int invokeNodeCount = g.getNodes().filter(InvokeNode.class).count(); 148 int invokeWithExceptionNodeCount = g.getNodes().filter(InvokeWithExceptionNode.class).count(); 149 Assert.assertEquals(1, invokeNodeCount + invokeWithExceptionNodeCount); 150 Assert.assertEquals(1, g.getNodes().filter(LoadHubNode.class).count()); 151 Assert.assertEquals(1, g.getNodes().filter(LoadMethodNode.class).count()); 152 } 153 154 @SuppressWarnings("try") 155 private StructuredGraph buildGraphAfterMidTier(String name) { 156 StructuredGraph g = parseForCompile(getResolvedJavaMethod(name)); 157 OptionValues options = getInitialOptions(); 158 new HighTier(options).apply(g, getDefaultHighTierContext()); 159 new MidTier(options).apply(g, new MidTierContext(getProviders(), getTargetProvider(), OptimisticOptimizations.ALL, g.getProfilingInfo())); 160 return g; 161 } 162 163 }