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