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 24package jdk.test.lib.jittester.utils; 25 26import java.util.Arrays; 27import java.util.ArrayList; 28import java.util.LinkedList; 29import java.util.List; 30 31import jdk.test.lib.jittester.BinaryOperator; 32import jdk.test.lib.jittester.Block; 33import jdk.test.lib.jittester.CatchBlock; 34import jdk.test.lib.jittester.IRNode; 35import jdk.test.lib.jittester.Literal; 36import jdk.test.lib.jittester.LocalVariable; 37import jdk.test.lib.jittester.NonStaticMemberVariable; 38import jdk.test.lib.jittester.Nothing; 39import jdk.test.lib.jittester.Operator; 40import jdk.test.lib.jittester.OperatorKind; 41import jdk.test.lib.jittester.PrintVariables; 42import jdk.test.lib.jittester.Statement; 43import jdk.test.lib.jittester.StaticMemberVariable; 44import jdk.test.lib.jittester.Symbol; 45import jdk.test.lib.jittester.TryCatchBlock; 46import jdk.test.lib.jittester.Type; 47import jdk.test.lib.jittester.TypeList; 48import jdk.test.lib.jittester.VariableInfo; 49import jdk.test.lib.jittester.VariableInitialization; 50import jdk.test.lib.jittester.functions.ArgumentDeclaration; 51import jdk.test.lib.jittester.functions.Function; 52import jdk.test.lib.jittester.functions.FunctionDefinition; 53import jdk.test.lib.jittester.functions.FunctionInfo; 54import jdk.test.lib.jittester.functions.Return; 55import jdk.test.lib.jittester.jtreg.Printer; 56import jdk.test.lib.jittester.loops.CounterInitializer; 57import jdk.test.lib.jittester.loops.CounterManipulator; 58import jdk.test.lib.jittester.loops.For; 59import jdk.test.lib.jittester.loops.Loop; 60import jdk.test.lib.jittester.loops.LoopingCondition; 61import jdk.test.lib.jittester.types.TypeArray; 62import jdk.test.lib.jittester.types.TypeKlass; 63 64public class FixedTrees { 65 private static final Literal EOL = new Literal("\n", TypeList.STRING); 66 67 public static FunctionDefinition printVariablesAsFunction(PrintVariables node) { 68 TypeKlass owner = node.getOwner(); 69 70 ArrayList<IRNode> nodes = new ArrayList<>(); 71 72 VariableInfo resultInfo = new VariableInfo("result", node.getOwner(), TypeList.STRING, VariableInfo.LOCAL); 73 nodes.add(new Statement(new VariableInitialization(resultInfo, new Literal("[", TypeList.STRING)), true)); 74 LocalVariable resultVar = new LocalVariable(resultInfo); 75 76 List<Symbol> vars = node.getVars(); 77 78 TypeKlass printerKlass = new TypeKlass(Printer.class.getName()); 79 VariableInfo thisInfo = new VariableInfo("this", node.getOwner(), 80 node.getOwner(), VariableInfo.LOCAL | VariableInfo.INITIALIZED); 81 82 LocalVariable thisVar = new LocalVariable(thisInfo); 83 84 for (int i = 0; i < vars.size(); i++) { 85 Symbol v = vars.get(i); 86 nodes.add(new Statement(new BinaryOperator(OperatorKind.COMPOUND_ADD, TypeList.STRING, resultVar, 87 new Literal(v.owner.getName() + "." + v.name + " = ", TypeList.STRING)), true)); 88 VariableInfo argInfo = new VariableInfo("arg", printerKlass, 89 v.type instanceof TypeKlass ? TypeList.OBJECT : v.type, 90 VariableInfo.LOCAL | VariableInfo.INITIALIZED); 91 FunctionInfo printInfo = new FunctionInfo("print", printerKlass, 92 TypeList.STRING, 0, FunctionInfo.PUBLIC | FunctionInfo.STATIC, argInfo); 93 Function call = new Function(owner, printInfo, null); 94 VariableInfo varInfo = new VariableInfo(v.name, v.owner, v.type, v.flags); 95 if (v.isStatic()) { 96 call.addChild(new StaticMemberVariable(v.owner, varInfo)); 97 } else { 98 call.addChild(new NonStaticMemberVariable(thisVar, varInfo)); 99 } 100 nodes.add(new Statement(new BinaryOperator(OperatorKind.COMPOUND_ADD, TypeList.STRING, resultVar, 101 call), true)); 102 if (i < vars.size() - 1) { 103 nodes.add(new Statement(new BinaryOperator(OperatorKind.COMPOUND_ADD, TypeList.STRING, resultVar, 104 EOL), true)); 105 } 106 } 107 nodes.add(new Statement( 108 new BinaryOperator(OperatorKind.COMPOUND_ADD, TypeList.STRING, resultVar, new Literal("]\n", TypeList.STRING)), 109 true)); 110 111 Block block = new Block(node.getOwner(), TypeList.STRING, nodes, 1); 112 FunctionInfo toStringInfo = new FunctionInfo("toString", owner, TypeList.STRING, 0L, FunctionInfo.PUBLIC, thisInfo); 113 return new FunctionDefinition(toStringInfo, new ArrayList<>(), block, new Return(resultVar)); 114 } 115 116 public static FunctionDefinition generateMainOrExecuteMethod(TypeKlass owner, boolean isMain) { 117 Nothing nothing = new Nothing(); 118 ArrayList<IRNode> testCallNodeContent = new ArrayList<>(); 119 VariableInfo tInfo = new VariableInfo("t", owner, owner, VariableInfo.LOCAL); 120 LocalVariable tVar = new LocalVariable(tInfo); 121 Function testCallNode = new Function(owner, new FunctionInfo("test", owner, TypeList.VOID, 122 0L, FunctionInfo.PRIVATE, tInfo), null); 123 testCallNode.addChild(tVar); 124 testCallNodeContent.add(new Statement(testCallNode, true)); 125 // { t.test(); } 126 Block testCallNodeBlock = new Block(owner, TypeList.VOID, testCallNodeContent, 4); 127 128 IRNode tryNode = testCallNodeBlock; 129 if (isMain) { 130 VariableInfo iInfo = new VariableInfo("i", owner, TypeList.INT, VariableInfo.LOCAL); 131 LocalVariable iVar = new LocalVariable(iInfo); 132 Operator increaseCounter = new BinaryOperator(OperatorKind.ASSIGN, TypeList.INT, 133 iVar, 134 new BinaryOperator(OperatorKind.ADD, TypeList.INT, 135 iVar, new Literal(1, TypeList.INT))); 136 Loop loop = new Loop(); 137 Block emptyBlock = new Block(owner, TypeList.VOID, new LinkedList<>(), 3); 138 loop.initialization = new CounterInitializer(iInfo, new Literal(0, TypeList.INT)); 139 loop.manipulator = new CounterManipulator(new Statement(increaseCounter, false)); 140 loop.condition = new LoopingCondition(new BinaryOperator(OperatorKind.LT, TypeList.BOOLEAN, iVar, 141 new Literal(150000, TypeList.INT))); 142 For forNode = new For(4, loop, 150000, emptyBlock, new Statement(nothing, false), 143 new Statement(nothing, false), testCallNodeBlock, emptyBlock, emptyBlock); 144 tryNode = forNode; 145 } 146 147 FunctionInfo constrInfo = new FunctionInfo(owner.getName(), owner, owner, 0, FunctionInfo.PUBLIC); 148 Function testConstructor = new Function(owner, constrInfo, null); 149 // Test t = new Test() 150 VariableInitialization testInit = new VariableInitialization(tInfo, testConstructor); 151 152 TypeKlass throwableKlass = new TypeKlass("java.lang.Throwable"); 153 List<Type> throwables = new ArrayList<>(); 154 throwables.add(throwableKlass); 155 156 TypeKlass printStreamKlass = new TypeKlass("java.io.PrintStream"); 157 FunctionInfo printInfo = new FunctionInfo("print", printStreamKlass, 158 TypeList.VOID, 0, FunctionInfo.PUBLIC, 159 new VariableInfo("this", owner, printStreamKlass, VariableInfo.LOCAL | VariableInfo.INITIALIZED), 160 new VariableInfo("t", owner, TypeList.OBJECT, 161 VariableInfo.LOCAL | VariableInfo.INITIALIZED)); 162 TypeKlass systemKlass = new TypeKlass("java.lang.System"); 163 StaticMemberVariable systemErrVar = new StaticMemberVariable(owner, 164 new VariableInfo("err", systemKlass, printStreamKlass, VariableInfo.STATIC | VariableInfo.PUBLIC)); 165 166 LocalVariable exVar = new LocalVariable( 167 new VariableInfo("ex", owner, throwableKlass, VariableInfo.LOCAL | VariableInfo.INITIALIZED)); 168 TypeKlass classKlass = new TypeKlass("java.lang.Class"); 169 FunctionInfo getClassInfo = new FunctionInfo("getClass", TypeList.OBJECT, 170 classKlass, 0, FunctionInfo.PUBLIC, 171 new VariableInfo("this", owner, TypeList.OBJECT, VariableInfo.LOCAL | VariableInfo.INITIALIZED)); 172 Function getClass = new Function(TypeList.OBJECT, getClassInfo, Arrays.asList(exVar)); 173 FunctionInfo getNameInfo = new FunctionInfo("getName", classKlass, 174 TypeList.STRING, 0, FunctionInfo.PUBLIC, 175 new VariableInfo("this", owner, TypeList.OBJECT, VariableInfo.LOCAL | VariableInfo.INITIALIZED)); 176 Function getName = new Function(classKlass, getNameInfo, Arrays.asList(getClass)); 177 ArrayList<IRNode> printExceptionBlockContent = new ArrayList<>(); 178 // { System.err.print(ex.getClass().getName()); System.err.print("\n"); } 179 printExceptionBlockContent.add(new Statement( 180 new Function(printStreamKlass, printInfo, Arrays.asList(systemErrVar, getName)), true)); 181 printExceptionBlockContent.add(new Statement( 182 new Function(printStreamKlass, printInfo, Arrays.asList(systemErrVar, EOL)), true)); 183 184 Block printExceptionBlock = new Block(owner, TypeList.VOID, printExceptionBlockContent, 3); 185 List<CatchBlock> catchBlocks1 = new ArrayList<>(); 186 catchBlocks1.add(new CatchBlock(printExceptionBlock, throwables, 3)); 187 List<CatchBlock> catchBlocks2 = new ArrayList<>(); 188 catchBlocks2.add(new CatchBlock(printExceptionBlock, throwables, 3)); 189 List<CatchBlock> catchBlocks3 = new ArrayList<>(); 190 catchBlocks3.add(new CatchBlock(printExceptionBlock, throwables, 2)); 191 192 TryCatchBlock tryCatch1 = new TryCatchBlock(tryNode, nothing, catchBlocks1, 3); 193 List<IRNode> printArgs = new ArrayList<>(); 194 VariableInfo systemOutInfo = new VariableInfo("out", systemKlass, printStreamKlass, 195 VariableInfo.STATIC | VariableInfo.PUBLIC); 196 StaticMemberVariable systemOutVar = new StaticMemberVariable(owner, systemOutInfo); 197 printArgs.add(systemOutVar); 198 printArgs.add(tVar); 199 Function print = new Function(printStreamKlass, printInfo, printArgs); 200 ArrayList<IRNode> printBlockContent = new ArrayList<>(); 201 printBlockContent.add(new Statement(print, true)); 202 Block printBlock = new Block(owner, TypeList.VOID, printBlockContent, 3); 203 TryCatchBlock tryCatch2 = new TryCatchBlock(printBlock, nothing, catchBlocks2, 3); 204 205 List<IRNode> mainTryCatchBlockContent = new ArrayList<>(); 206 mainTryCatchBlockContent.add(new Statement(testInit, true)); 207 mainTryCatchBlockContent.add(tryCatch1); 208 mainTryCatchBlockContent.add(tryCatch2); 209 Block mainTryCatchBlock = new Block(owner, TypeList.VOID, mainTryCatchBlockContent, 2); 210 TryCatchBlock mainTryCatch = new TryCatchBlock(mainTryCatchBlock, nothing, catchBlocks3, 2); 211 ArrayList<IRNode> bodyContent = new ArrayList<>(); 212 bodyContent.add(mainTryCatch); 213 Block funcBody = new Block(owner, TypeList.VOID, bodyContent, 1); 214 215 // static main(String[] args)V or static execute()V 216 VariableInfo mainArgs = new VariableInfo("args", owner, 217 new TypeArray(TypeList.STRING, 1), VariableInfo.LOCAL); 218 FunctionInfo fInfo = isMain 219 ? new FunctionInfo("main", owner, TypeList.VOID, 0, FunctionInfo.PUBLIC | FunctionInfo.STATIC, mainArgs) 220 : new FunctionInfo("execute", owner, TypeList.VOID, 0, FunctionInfo.PUBLIC | FunctionInfo.STATIC); 221 ArrayList<ArgumentDeclaration> argDecl = new ArrayList<>(); 222 if (isMain) { 223 argDecl.add(new ArgumentDeclaration(mainArgs)); 224 } 225 return new FunctionDefinition(fInfo, argDecl, funcBody, new Return(nothing)); 226 } 227} 228