1 /* 2 * Copyright (c) 2015, 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 24 package jdk.test.lib.jittester.factories; 25 26 import jdk.test.lib.jittester.IRNode; 27 import jdk.test.lib.jittester.Initialization; 28 import jdk.test.lib.jittester.Literal; 29 import jdk.test.lib.jittester.LocalVariable; 30 import jdk.test.lib.jittester.Nothing; 31 import jdk.test.lib.jittester.ProductionFailedException; 32 import jdk.test.lib.jittester.SymbolTable; 33 import jdk.test.lib.jittester.Type; 34 import jdk.test.lib.jittester.loops.DoWhile; 35 import jdk.test.lib.jittester.loops.Loop; 36 import jdk.test.lib.jittester.types.TypeKlass; 37 import jdk.test.lib.jittester.types.TypeInt; 38 import jdk.test.lib.jittester.utils.PseudoRandom; 39 40 class DoWhileFactory extends SafeFactory { 41 private final Loop loop; 42 private final long complexityLimit; 43 private final int statementLimit; 44 private final int operatorLimit; 45 private boolean canHaveReturn = false; 46 private final TypeKlass ownerClass; 47 private final int level; 48 private final Type returnType; 49 private long thisLoopIterLimit; 50 51 DoWhileFactory(TypeKlass ownerClass, Type returnType, long complexityLimit, int statementLimit, 52 int operatorLimit, int level, boolean canHaveReturn) { 53 loop = new Loop(); 54 this.ownerClass = ownerClass; 55 this.returnType = returnType; 56 this.complexityLimit = complexityLimit; 57 this.statementLimit = statementLimit; 58 this.operatorLimit = operatorLimit; 59 this.level = level; 60 this.canHaveReturn = canHaveReturn; 61 thisLoopIterLimit = 0; 62 } 63 64 @Override 65 protected IRNode sproduce() throws ProductionFailedException { 66 if (statementLimit > 0 && complexityLimit > 0) { 67 long complexity = complexityLimit; 68 // Loop header parameters 69 long headerComplLimit = (long) (0.005 * complexity * PseudoRandom.random()); 70 complexity -= headerComplLimit; 71 int headerStatementLimit = PseudoRandom.randomNotZero((int) (statementLimit / 3.0)); 72 // Loop body parameters 73 thisLoopIterLimit = (long) (0.0001 * complexity * PseudoRandom.random()); 74 if (thisLoopIterLimit > Integer.MAX_VALUE || thisLoopIterLimit == 0) { 75 throw new ProductionFailedException(); 76 } 77 complexity = thisLoopIterLimit > 0 ? complexity / thisLoopIterLimit : 0; 78 long condComplLimit = (long) (complexity * PseudoRandom.random()); 79 complexity -= condComplLimit; 80 long body1ComplLimit = (long) (complexity * PseudoRandom.random()); 81 complexity -= body1ComplLimit; 82 int body1StatementLimit = PseudoRandom.randomNotZero((int) (statementLimit / 3.0)); 83 long body2ComplLimit = (long) (complexity * PseudoRandom.random()); 84 complexity -= body2ComplLimit; 85 int body2StatementLimit = PseudoRandom.randomNotZero((int) (statementLimit / 3.0)); 86 // Production 87 IRNodeBuilder builder = new IRNodeBuilder() 88 .setOwnerKlass(ownerClass) 89 .setResultType(returnType) 90 .setOperatorLimit(operatorLimit); 91 loop.initialization = builder.getCounterInitializerFactory(0).produce(); 92 IRNode header; 93 try { 94 header = builder.setComplexityLimit(headerComplLimit) 95 .setStatementLimit(headerStatementLimit) 96 .setLevel(level - 1) 97 .setSubBlock(true) 98 .setCanHaveBreaks(false) 99 .setCanHaveContinues(false) 100 .setCanHaveReturn(false) 101 .getBlockFactory() 102 .produce(); 103 } catch (ProductionFailedException e) { 104 header = new Nothing(); 105 } 106 // getChildren().set(DoWhile.DoWhilePart.HEADER.ordinal(), header); 107 LocalVariable counter = new LocalVariable(((Initialization) loop.initialization).get()); 108 Literal limiter = new Literal(Integer.valueOf((int) thisLoopIterLimit), new TypeInt()); 109 loop.condition = builder.setComplexityLimit(condComplLimit) 110 .setLocalVariable(counter) 111 .getLoopingConditionFactory(limiter) 112 .produce(); 113 SymbolTable.push(); 114 IRNode body1; 115 try { 116 body1 = builder.setComplexityLimit(body1ComplLimit) 117 .setStatementLimit(body1StatementLimit) 118 .setLevel(level) 119 .setSubBlock(true) 120 .setCanHaveBreaks(true) 121 .setCanHaveContinues(false) 122 .setCanHaveReturn(false) 123 .getBlockFactory() 124 .produce(); 125 } catch (ProductionFailedException e) { 126 body1 = new Nothing(); 127 } 128 // getChildren().set(DoWhile.DoWhilePart.BODY1.ordinal(), body1); 129 loop.manipulator = builder.setLocalVariable(counter).getCounterManipulatorFactory().produce(); 130 IRNode body2; 131 try { 132 body2 = builder.setComplexityLimit(body2ComplLimit) 133 .setStatementLimit(body2StatementLimit) 134 .setLevel(level) 135 .setSubBlock(true) 136 .setCanHaveBreaks(true) 137 .setCanHaveContinues(false) 138 .setCanHaveReturn(canHaveReturn) 139 .getBlockFactory() 140 .produce(); 141 } catch (ProductionFailedException e) { 142 body2 = new Nothing(); 143 } 144 // getChildren().set(DoWhile.DoWhilePart.BODY2.ordinal(), body2); 145 SymbolTable.pop(); 146 return new DoWhile(level, loop, thisLoopIterLimit, header, body1, body2); 147 } 148 throw new ProductionFailedException(); 149 } 150 }