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 java.util.ArrayList; 27 import jdk.test.lib.jittester.IRNode; 28 import jdk.test.lib.jittester.ProductionFailedException; 29 import jdk.test.lib.jittester.SymbolTable; 30 import jdk.test.lib.jittester.VariableInfo; 31 import jdk.test.lib.jittester.functions.ArgumentDeclaration; 32 import jdk.test.lib.jittester.functions.FunctionDefinition; 33 import jdk.test.lib.jittester.functions.FunctionInfo; 34 import jdk.test.lib.jittester.types.TypeKlass; 35 import jdk.test.lib.jittester.types.TypeVoid; 36 import jdk.test.lib.jittester.utils.PseudoRandom; 37 38 class FunctionRedefinitionFactory extends Factory { 39 private final long complexityLimit; 40 private final int statementLimit; 41 private final int operatorLimit; 42 private final int level; 43 private final TypeKlass ownerClass; 44 private final FunctionInfo functionInfo; 45 46 FunctionRedefinitionFactory(FunctionInfo functionInfo, TypeKlass ownerClass, 47 long complexityLimit, int statementLimit, int operatorLimit, int level, int flags) { 48 this.ownerClass = ownerClass; 49 this.functionInfo = new FunctionInfo(functionInfo); // do deep coping 50 functionInfo.klass = ownerClass; // important! fix klass! 51 if ((functionInfo.flags & FunctionInfo.STATIC) == 0) { 52 functionInfo.argTypes.get(0).type = ownerClass; // redefine type of this 53 } 54 functionInfo.flags = flags; // apply new flags. 55 // fix the type of class where the args would be declared 56 for (VariableInfo varInfo : functionInfo.argTypes) { 57 varInfo.klass = ownerClass; 58 } 59 this.complexityLimit = complexityLimit; 60 this.statementLimit = statementLimit; 61 this.operatorLimit = operatorLimit; 62 this.level = level; 63 } 64 65 @Override 66 public IRNode produce() throws ProductionFailedException { 67 ArrayList<VariableInfo> argumentsInfo = functionInfo.argTypes; 68 SymbolTable.push(); 69 IRNode body; 70 IRNode returnNode; 71 ArrayList<ArgumentDeclaration> argumentsDeclaration; 72 try { 73 if ((functionInfo.flags & FunctionInfo.STATIC) > 0) { 74 argumentsDeclaration = new ArrayList<>(argumentsInfo.size()); 75 for (VariableInfo varInfo : argumentsInfo) { 76 argumentsDeclaration.add(new ArgumentDeclaration(varInfo)); 77 SymbolTable.add(varInfo); 78 } 79 } else { 80 argumentsDeclaration = new ArrayList<>(argumentsInfo.size() - 1); 81 SymbolTable.add(argumentsInfo.get(0)); 82 for (int i = 1; i < argumentsInfo.size(); i++) { 83 argumentsDeclaration.add(new ArgumentDeclaration(argumentsInfo.get(i))); 84 SymbolTable.add(argumentsInfo.get(i)); 85 } 86 } 87 long blockComplLimit = (long) (PseudoRandom.random() * complexityLimit); 88 IRNodeBuilder builder = new IRNodeBuilder() 89 .setOwnerKlass(ownerClass) 90 .setResultType(functionInfo.type) 91 .setStatementLimit(statementLimit) 92 .setOperatorLimit(operatorLimit); 93 body = builder.setComplexityLimit(blockComplLimit) 94 .setLevel(level) 95 .setSubBlock(true) 96 .setCanHaveBreaks(false) 97 .setCanHaveContinues(false) 98 .setCanHaveReturn(true) 99 .getBlockFactory() 100 .produce(); 101 if (!functionInfo.type.equals(new TypeVoid())) { 102 returnNode = builder.setComplexityLimit(complexityLimit - blockComplLimit) 103 .setExceptionSafe(false) 104 .getReturnFactory() 105 .produce(); 106 } else { 107 returnNode = null; 108 } 109 } catch (ProductionFailedException e) { 110 SymbolTable.pop(); 111 SymbolTable.add(functionInfo); 112 throw e; 113 } 114 SymbolTable.pop(); 115 if ((functionInfo.flags & FunctionInfo.STATIC) == 0) { 116 functionInfo.flags &= ~FunctionInfo.ABSTRACT; 117 } 118 // If it's all ok, add the function to the symbol table. 119 SymbolTable.add(functionInfo); 120 return new FunctionDefinition(functionInfo, argumentsDeclaration, body, returnNode); 121 } 122 123 }