001/* 002 * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved. 003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 004 * 005 * This code is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU General Public License version 2 only, as 007 * published by the Free Software Foundation. 008 * 009 * This code is distributed in the hope that it will be useful, but WITHOUT 010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 011 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 012 * version 2 for more details (a copy is included in the LICENSE file that 013 * accompanied this code). 014 * 015 * You should have received a copy of the GNU General Public License version 016 * 2 along with this work; if not, write to the Free Software Foundation, 017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 018 * 019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 020 * or visit www.oracle.com if you need additional information or have any 021 * questions. 022 */ 023package com.oracle.graal.compiler.test.tutorial; 024 025import java.lang.reflect.*; 026import java.util.*; 027 028import jdk.internal.jvmci.meta.*; 029 030import org.junit.*; 031 032import com.oracle.graal.api.runtime.*; 033import com.oracle.graal.compiler.target.*; 034import com.oracle.graal.compiler.test.tutorial.StaticAnalysis.MethodState; 035import com.oracle.graal.compiler.test.tutorial.StaticAnalysis.TypeFlow; 036import com.oracle.graal.nodes.spi.*; 037import com.oracle.graal.phases.util.*; 038import com.oracle.graal.runtime.*; 039 040public class StaticAnalysisTests { 041 042 static class A { 043 Object foo(Object arg) { 044 return arg; 045 } 046 } 047 048 static class B extends A { 049 @Override 050 Object foo(Object arg) { 051 if (arg instanceof Data) { 052 return ((Data) arg).f; 053 } else { 054 return super.foo(arg); 055 } 056 } 057 } 058 059 static class Data { 060 Object f; 061 } 062 063 private final MetaAccessProvider metaAccess; 064 private final StampProvider stampProvider; 065 066 public StaticAnalysisTests() { 067 Backend backend = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend(); 068 Providers providers = backend.getProviders(); 069 this.metaAccess = providers.getMetaAccess(); 070 this.stampProvider = providers.getStampProvider(); 071 } 072 073 static void test01Entry() { 074 A a = new A(); 075 a.foo(null); 076 } 077 078 @Test 079 public void test01() { 080 StaticAnalysis sa = new StaticAnalysis(metaAccess, stampProvider); 081 sa.addMethod(findMethod(StaticAnalysisTests.class, "test01Entry")); 082 sa.finish(); 083 084 assertEquals(sa.getResults().getAllInstantiatedTypes(), t(A.class)); 085 assertEquals(f(sa, Data.class, "f")); 086 assertEquals(m(sa, A.class, "foo").getFormalParameters()[0], t(A.class)); 087 assertEquals(m(sa, A.class, "foo").getFormalParameters()[1]); 088 assertEquals(m(sa, A.class, "foo").getFormalReturn()); 089 } 090 091 static void test02Entry() { 092 A a = new A(); 093 a.foo(new Data()); 094 095 B b = new B(); 096 b.foo(null); 097 } 098 099 @Test 100 public void test02() { 101 StaticAnalysis sa = new StaticAnalysis(metaAccess, stampProvider); 102 sa.addMethod(findMethod(StaticAnalysisTests.class, "test02Entry")); 103 sa.finish(); 104 105 assertEquals(sa.getResults().getAllInstantiatedTypes(), t(A.class), t(B.class), t(Data.class)); 106 assertEquals(f(sa, Data.class, "f")); 107 assertEquals(m(sa, A.class, "foo").getFormalParameters()[0], t(A.class), t(B.class)); 108 assertEquals(m(sa, A.class, "foo").getFormalParameters()[1], t(Data.class)); 109 assertEquals(m(sa, A.class, "foo").getFormalReturn(), t(Data.class)); 110 assertEquals(m(sa, B.class, "foo").getFormalParameters()[0], t(B.class)); 111 assertEquals(m(sa, B.class, "foo").getFormalParameters()[1]); 112 assertEquals(m(sa, B.class, "foo").getFormalReturn(), t(Data.class)); 113 } 114 115 static void test03Entry() { 116 Data data = new Data(); 117 data.f = new Integer(42); 118 119 A a = new A(); 120 a.foo(new Data()); 121 122 B b = new B(); 123 b.foo(null); 124 } 125 126 @Test 127 public void test03() { 128 StaticAnalysis sa = new StaticAnalysis(metaAccess, stampProvider); 129 sa.addMethod(findMethod(StaticAnalysisTests.class, "test03Entry")); 130 sa.finish(); 131 132 assertEquals(sa.getResults().getAllInstantiatedTypes(), t(A.class), t(B.class), t(Data.class), t(Integer.class)); 133 assertEquals(f(sa, Data.class, "f"), t(Integer.class)); 134 assertEquals(m(sa, A.class, "foo").getFormalParameters()[0], t(A.class), t(B.class)); 135 assertEquals(m(sa, A.class, "foo").getFormalParameters()[1], t(Data.class)); 136 assertEquals(m(sa, A.class, "foo").getFormalReturn(), t(Data.class)); 137 assertEquals(m(sa, B.class, "foo").getFormalParameters()[0], t(B.class)); 138 assertEquals(m(sa, B.class, "foo").getFormalParameters()[1]); 139 assertEquals(m(sa, B.class, "foo").getFormalReturn(), t(Data.class), t(Integer.class)); 140 } 141 142 static void test04Entry() { 143 Data data = null; 144 for (int i = 0; i < 2; i++) { 145 if (i == 0) { 146 data = new Data(); 147 } else if (i == 1) { 148 data.f = new Integer(42); 149 } 150 } 151 152 A a = new A(); 153 a.foo(data); 154 } 155 156 @Test 157 public void test04() { 158 StaticAnalysis sa = new StaticAnalysis(metaAccess, stampProvider); 159 sa.addMethod(findMethod(StaticAnalysisTests.class, "test04Entry")); 160 sa.finish(); 161 162 assertEquals(sa.getResults().getAllInstantiatedTypes(), t(A.class), t(Data.class), t(Integer.class)); 163 assertEquals(f(sa, Data.class, "f"), t(Integer.class)); 164 assertEquals(m(sa, A.class, "foo").getFormalParameters()[0], t(A.class)); 165 assertEquals(m(sa, A.class, "foo").getFormalParameters()[1], t(Data.class)); 166 assertEquals(m(sa, A.class, "foo").getFormalReturn(), t(Data.class)); 167 } 168 169 private MethodState m(StaticAnalysis sa, Class<?> declaringClass, String name) { 170 return sa.getResults().lookupMethod(findMethod(declaringClass, name)); 171 } 172 173 private TypeFlow f(StaticAnalysis sa, Class<?> declaringClass, String name) { 174 return sa.getResults().lookupField(findField(declaringClass, name)); 175 } 176 177 private static void assertEquals(TypeFlow actual, Object... expected) { 178 Collection<?> actualTypes = actual.getTypes(); 179 if (actualTypes.size() != expected.length || !actualTypes.containsAll(Arrays.asList(expected))) { 180 Assert.fail(actualTypes + " != " + Arrays.asList(expected)); 181 } 182 } 183 184 private ResolvedJavaType t(Class<?> clazz) { 185 return metaAccess.lookupJavaType(clazz); 186 } 187 188 private ResolvedJavaMethod findMethod(Class<?> declaringClass, String name) { 189 Method reflectionMethod = null; 190 for (Method m : declaringClass.getDeclaredMethods()) { 191 if (m.getName().equals(name)) { 192 assert reflectionMethod == null : "More than one method with name " + name + " in class " + declaringClass.getName(); 193 reflectionMethod = m; 194 } 195 } 196 assert reflectionMethod != null : "No method with name " + name + " in class " + declaringClass.getName(); 197 return metaAccess.lookupJavaMethod(reflectionMethod); 198 } 199 200 private ResolvedJavaField findField(Class<?> declaringClass, String name) { 201 Field reflectionField; 202 try { 203 reflectionField = declaringClass.getDeclaredField(name); 204 } catch (NoSuchFieldException | SecurityException ex) { 205 throw new AssertionError(ex); 206 } 207 return metaAccess.lookupJavaField(reflectionField); 208 } 209}