25 26 import java.util.ArrayList; 27 import java.util.HashSet; 28 import java.util.Iterator; 29 import java.util.LinkedList; 30 import jdk.test.lib.jittester.IRNode; 31 import jdk.test.lib.jittester.ProductionFailedException; 32 import jdk.test.lib.jittester.ProductionParams; 33 import jdk.test.lib.jittester.Symbol; 34 import jdk.test.lib.jittester.SymbolTable; 35 import jdk.test.lib.jittester.Type; 36 import jdk.test.lib.jittester.TypeList; 37 import jdk.test.lib.jittester.VariableInfo; 38 import jdk.test.lib.jittester.classes.Klass; 39 import jdk.test.lib.jittester.functions.FunctionDeclarationBlock; 40 import jdk.test.lib.jittester.functions.FunctionDefinition; 41 import jdk.test.lib.jittester.functions.FunctionInfo; 42 import jdk.test.lib.jittester.types.TypeKlass; 43 import jdk.test.lib.jittester.utils.PseudoRandom; 44 45 class KlassFactory extends Factory { 46 private final String name; 47 private final String printerName; 48 private final long complexityLimit; 49 private final int statementsInFunctionLimit; 50 private final int operatorLimit; 51 private final int memberFunctionsArgLimit; 52 private final int level; 53 private final ArrayList<TypeKlass> interfaces; 54 private TypeKlass thisKlass; 55 private TypeKlass parent; 56 private int memberFunctionsLimit; 57 58 KlassFactory(String name, String printerName, long complexityLimit, 59 int memberFunctionsLimit, int memberFunctionsArgLimit, int statementsInFunctionLimit, 60 int operatorLimit, int level) { 61 this.name = name; 62 this.printerName = printerName; 63 this.complexityLimit = complexityLimit; 64 this.memberFunctionsLimit = memberFunctionsLimit; 65 this.memberFunctionsArgLimit = memberFunctionsArgLimit; 66 this.statementsInFunctionLimit = statementsInFunctionLimit; 67 this.operatorLimit = operatorLimit; 68 this.level = level; 69 interfaces = new ArrayList<>(); 70 } 71 72 @Override 73 public IRNode produce() throws ProductionFailedException { 74 HashSet<Symbol> abstractSet = new HashSet<>(); 75 HashSet<Symbol> overrideSet = new HashSet<>(); 76 thisKlass = new TypeKlass(name); 77 // Do we want to inherit something? 78 if (!ProductionParams.disableInheritance.value()) { 79 inheritClass(); 80 inheritInterfaces(); 81 // Now, we should carefully construct a set of all methods with are still abstract. 82 // In order to do that, we will make two sets of methods: abstract and non-abstract. 83 // Then by substracting non-abstract from abstract we'll get what we want. 84 HashSet<Symbol> nonAbstractSet = new HashSet<>(); 85 for (Symbol symbol : SymbolTable.getAllCombined(thisKlass, FunctionInfo.class)) { 86 FunctionInfo functionInfo = (FunctionInfo) symbol; 87 // There could be multiple definitions or declarations encountered, 88 // but all we interested in are signatures. 89 if ((functionInfo.flags & FunctionInfo.ABSTRACT) > 0) { 90 abstractSet.add(functionInfo); 91 } else { 92 nonAbstractSet.add(functionInfo); 93 } 118 break; 119 } 120 FunctionInfo functionInfo = (FunctionInfo) symbol; 121 if ((functionInfo.flags & FunctionInfo.FINAL) > 0) { 122 continue; 123 } 124 overrideSet.add(functionInfo); 125 } 126 } 127 } 128 memberFunctionsLimit -= abstractSet.size() + overrideSet.size(); 129 // Ok, remove the symbols from the table which are going to be overrided. 130 // Because the redefiner would probably modify them and put them back into table. 131 for (Symbol symbol : abstractSet) { 132 SymbolTable.remove(symbol); 133 } 134 for (Symbol symbol : overrideSet) { 135 SymbolTable.remove(symbol); 136 } 137 } else { 138 parent = (TypeKlass) TypeList.find("java.lang.Object"); 139 thisKlass.addParent(parent.getName()); 140 thisKlass.setParent(parent); 141 parent.addChild(name); 142 } 143 // Just don't print it. It's assumed that we at least are inherited from Object. 144 if (parent.getName().equals("java.lang.Object")) { 145 parent = null; 146 } 147 SymbolTable.add(new VariableInfo("this", thisKlass, thisKlass, 148 VariableInfo.FINAL | VariableInfo.LOCAL | VariableInfo.INITIALIZED)); 149 IRNode variableDeclarations = null; 150 IRNode constructorDefinitions = null; 151 IRNode functionDefinitions = null; 152 IRNode functionDeclarations = null; 153 IRNode abstractFunctionsRedefinitions = null; 154 IRNode overridenFunctionsRedefinitions = null; 155 IRNodeBuilder builder = new IRNodeBuilder().setPrinterName(printerName) 156 .setOwnerKlass(thisKlass) 157 .setExceptionSafe(true); 158 try { 159 builder.setLevel(level + 1) 160 .setOperatorLimit(operatorLimit) 161 .setStatementLimit(statementsInFunctionLimit) 162 .setMemberFunctionsArgLimit(memberFunctionsArgLimit); 163 variableDeclarations = builder.setComplexityLimit((long) (complexityLimit * 0.001 * PseudoRandom.random())) 164 .getVariableDeclarationBlockFactory().produce(); 165 if (!ProductionParams.disableFunctions.value()) { 166 // Try to implement all methods. 167 abstractFunctionsRedefinitions = builder.setComplexityLimit((long) (complexityLimit * 0.3 * PseudoRandom.random())) 168 .setLevel(level + 1) 169 .getFunctionRedefinitionBlockFactory(abstractSet) 170 .produce(); 171 overridenFunctionsRedefinitions = builder.setComplexityLimit((long) (complexityLimit * 0.3 * PseudoRandom.random())) 172 .getFunctionRedefinitionBlockFactory(overrideSet) 173 .produce(); 174 if (PseudoRandom.randomBoolean(0.2)) { // wanna be abstract ? 175 functionDeclarations = builder.setMemberFunctionsLimit((int) (memberFunctionsLimit * 0.2 176 * PseudoRandom.random())) 210 TypeList.add(thisKlass); 211 IRNode printVariables = builder.setLevel(2).getPrintVariablesFactory().produce(); 212 return new Klass(thisKlass, parent, interfaces, name, level, 213 variableDeclarations, constructorDefinitions, functionDefinitions, 214 abstractFunctionsRedefinitions, overridenFunctionsRedefinitions, 215 functionDeclarations, printVariables); 216 } 217 218 private void inheritClass() { 219 // Grab all Klasses from the TypeList and select one to be a parent 220 LinkedList<Type> probableParents = new LinkedList<>(TypeList.getAll()); 221 for (Iterator<Type> i = probableParents.iterator(); i.hasNext();) { 222 Type klass = i.next(); 223 if (!(klass instanceof TypeKlass) || ((TypeKlass) klass).isFinal() 224 || ((TypeKlass) klass).isInterface()) { 225 // we can not derive from finals and interfaces 226 i.remove(); 227 } 228 } 229 if (probableParents.isEmpty()) { 230 parent = (TypeKlass) TypeList.find("java.lang.Object"); 231 } else { 232 parent = (TypeKlass) PseudoRandom.randomElement(probableParents); 233 } 234 thisKlass.addParent(parent.getName()); 235 thisKlass.setParent(parent); 236 parent.addChild(name); 237 for (Symbol symbol : SymbolTable.getAllCombined(parent)) { 238 if ((symbol.flags & Symbol.PRIVATE) == 0) { 239 Symbol symbolCopy = symbol.deepCopy(); 240 if (symbolCopy instanceof FunctionInfo) { 241 FunctionInfo functionInfo = (FunctionInfo) symbolCopy; 242 if (functionInfo.isConstructor()) { 243 continue; 244 } 245 if ((functionInfo.flags & FunctionInfo.STATIC) == 0) { 246 functionInfo.argTypes.get(0).type = thisKlass; 247 } 248 } 249 symbolCopy.klass = thisKlass; 250 SymbolTable.add(symbolCopy); 251 } 252 } 253 } 254 255 private void inheritInterfaces() { 256 // Select interfaces that we'll implement. 257 LinkedList<Type> probableInterfaces = new LinkedList<>(TypeList.getAll()); 258 for (Iterator<Type> i = probableInterfaces.iterator(); i.hasNext();) { 259 Type klass = i.next(); 260 if (!(klass instanceof TypeKlass) || !((TypeKlass) klass).isInterface()) { 261 i.remove(); 262 } 263 } 264 PseudoRandom.shuffle(probableInterfaces); 265 int implLimit = (int) (ProductionParams.implementationLimit.value() * PseudoRandom.random()); 266 // Mulitiple inheritance compatibility check 267 compatibility_check: 268 for (Iterator<Type> i = probableInterfaces.iterator(); i.hasNext() && implLimit > 0; implLimit--) { 269 TypeKlass iface = (TypeKlass) i.next(); 270 ArrayList<Symbol> ifaceFuncSet = SymbolTable.getAllCombined(iface, FunctionInfo.class); 271 for (Symbol symbol : SymbolTable.getAllCombined(thisKlass, FunctionInfo.class)) { 272 if (FunctionDefinition.isInvalidOverride((FunctionInfo) symbol, ifaceFuncSet)) { 273 continue compatibility_check; 274 } 275 } 276 interfaces.add(iface); 277 iface.addChild(name); 278 thisKlass.addParent(iface.getName()); 279 thisKlass.setParent(iface); 280 for (Symbol symbol : SymbolTable.getAllCombined(iface, FunctionInfo.class)) { 281 FunctionInfo functionInfo = (FunctionInfo) symbol.deepCopy(); 282 functionInfo.klass = thisKlass; 283 functionInfo.argTypes.get(0).type = thisKlass; 284 SymbolTable.add(functionInfo); 285 } 286 } 287 } 288 } | 25 26 import java.util.ArrayList; 27 import java.util.HashSet; 28 import java.util.Iterator; 29 import java.util.LinkedList; 30 import jdk.test.lib.jittester.IRNode; 31 import jdk.test.lib.jittester.ProductionFailedException; 32 import jdk.test.lib.jittester.ProductionParams; 33 import jdk.test.lib.jittester.Symbol; 34 import jdk.test.lib.jittester.SymbolTable; 35 import jdk.test.lib.jittester.Type; 36 import jdk.test.lib.jittester.TypeList; 37 import jdk.test.lib.jittester.VariableInfo; 38 import jdk.test.lib.jittester.classes.Klass; 39 import jdk.test.lib.jittester.functions.FunctionDeclarationBlock; 40 import jdk.test.lib.jittester.functions.FunctionDefinition; 41 import jdk.test.lib.jittester.functions.FunctionInfo; 42 import jdk.test.lib.jittester.types.TypeKlass; 43 import jdk.test.lib.jittester.utils.PseudoRandom; 44 45 class KlassFactory extends Factory<Klass> { 46 private final String name; 47 private final long complexityLimit; 48 private final int statementsInFunctionLimit; 49 private final int operatorLimit; 50 private final int memberFunctionsArgLimit; 51 private final int level; 52 private final ArrayList<TypeKlass> interfaces; 53 private TypeKlass thisKlass; 54 private TypeKlass parent; 55 private int memberFunctionsLimit; 56 57 KlassFactory(String name, long complexityLimit, 58 int memberFunctionsLimit, int memberFunctionsArgLimit, int statementsInFunctionLimit, 59 int operatorLimit, int level) { 60 this.name = name; 61 this.complexityLimit = complexityLimit; 62 this.memberFunctionsLimit = memberFunctionsLimit; 63 this.memberFunctionsArgLimit = memberFunctionsArgLimit; 64 this.statementsInFunctionLimit = statementsInFunctionLimit; 65 this.operatorLimit = operatorLimit; 66 this.level = level; 67 interfaces = new ArrayList<>(); 68 } 69 70 @Override 71 public Klass produce() throws ProductionFailedException { 72 HashSet<Symbol> abstractSet = new HashSet<>(); 73 HashSet<Symbol> overrideSet = new HashSet<>(); 74 thisKlass = new TypeKlass(name); 75 // Do we want to inherit something? 76 if (!ProductionParams.disableInheritance.value()) { 77 inheritClass(); 78 inheritInterfaces(); 79 // Now, we should carefully construct a set of all methods with are still abstract. 80 // In order to do that, we will make two sets of methods: abstract and non-abstract. 81 // Then by substracting non-abstract from abstract we'll get what we want. 82 HashSet<Symbol> nonAbstractSet = new HashSet<>(); 83 for (Symbol symbol : SymbolTable.getAllCombined(thisKlass, FunctionInfo.class)) { 84 FunctionInfo functionInfo = (FunctionInfo) symbol; 85 // There could be multiple definitions or declarations encountered, 86 // but all we interested in are signatures. 87 if ((functionInfo.flags & FunctionInfo.ABSTRACT) > 0) { 88 abstractSet.add(functionInfo); 89 } else { 90 nonAbstractSet.add(functionInfo); 91 } 116 break; 117 } 118 FunctionInfo functionInfo = (FunctionInfo) symbol; 119 if ((functionInfo.flags & FunctionInfo.FINAL) > 0) { 120 continue; 121 } 122 overrideSet.add(functionInfo); 123 } 124 } 125 } 126 memberFunctionsLimit -= abstractSet.size() + overrideSet.size(); 127 // Ok, remove the symbols from the table which are going to be overrided. 128 // Because the redefiner would probably modify them and put them back into table. 129 for (Symbol symbol : abstractSet) { 130 SymbolTable.remove(symbol); 131 } 132 for (Symbol symbol : overrideSet) { 133 SymbolTable.remove(symbol); 134 } 135 } else { 136 parent = TypeList.OBJECT; 137 thisKlass.addParent(parent.getName()); 138 thisKlass.setParent(parent); 139 parent.addChild(name); 140 } 141 SymbolTable.add(new VariableInfo("this", thisKlass, thisKlass, 142 VariableInfo.FINAL | VariableInfo.LOCAL | VariableInfo.INITIALIZED)); 143 IRNode variableDeclarations = null; 144 IRNode constructorDefinitions = null; 145 IRNode functionDefinitions = null; 146 IRNode functionDeclarations = null; 147 IRNode abstractFunctionsRedefinitions = null; 148 IRNode overridenFunctionsRedefinitions = null; 149 IRNodeBuilder builder = new IRNodeBuilder().setOwnerKlass(thisKlass) 150 .setExceptionSafe(true); 151 try { 152 builder.setLevel(level + 1) 153 .setOperatorLimit(operatorLimit) 154 .setStatementLimit(statementsInFunctionLimit) 155 .setMemberFunctionsArgLimit(memberFunctionsArgLimit); 156 variableDeclarations = builder.setComplexityLimit((long) (complexityLimit * 0.001 * PseudoRandom.random())) 157 .getVariableDeclarationBlockFactory().produce(); 158 if (!ProductionParams.disableFunctions.value()) { 159 // Try to implement all methods. 160 abstractFunctionsRedefinitions = builder.setComplexityLimit((long) (complexityLimit * 0.3 * PseudoRandom.random())) 161 .setLevel(level + 1) 162 .getFunctionRedefinitionBlockFactory(abstractSet) 163 .produce(); 164 overridenFunctionsRedefinitions = builder.setComplexityLimit((long) (complexityLimit * 0.3 * PseudoRandom.random())) 165 .getFunctionRedefinitionBlockFactory(overrideSet) 166 .produce(); 167 if (PseudoRandom.randomBoolean(0.2)) { // wanna be abstract ? 168 functionDeclarations = builder.setMemberFunctionsLimit((int) (memberFunctionsLimit * 0.2 169 * PseudoRandom.random())) 203 TypeList.add(thisKlass); 204 IRNode printVariables = builder.setLevel(2).getPrintVariablesFactory().produce(); 205 return new Klass(thisKlass, parent, interfaces, name, level, 206 variableDeclarations, constructorDefinitions, functionDefinitions, 207 abstractFunctionsRedefinitions, overridenFunctionsRedefinitions, 208 functionDeclarations, printVariables); 209 } 210 211 private void inheritClass() { 212 // Grab all Klasses from the TypeList and select one to be a parent 213 LinkedList<Type> probableParents = new LinkedList<>(TypeList.getAll()); 214 for (Iterator<Type> i = probableParents.iterator(); i.hasNext();) { 215 Type klass = i.next(); 216 if (!(klass instanceof TypeKlass) || ((TypeKlass) klass).isFinal() 217 || ((TypeKlass) klass).isInterface()) { 218 // we can not derive from finals and interfaces 219 i.remove(); 220 } 221 } 222 if (probableParents.isEmpty()) { 223 parent = TypeList.OBJECT; 224 } else { 225 parent = (TypeKlass) PseudoRandom.randomElement(probableParents); 226 } 227 thisKlass.addParent(parent.getName()); 228 thisKlass.setParent(parent); 229 parent.addChild(name); 230 for (Symbol symbol : SymbolTable.getAllCombined(parent)) { 231 if ((symbol.flags & Symbol.PRIVATE) == 0) { 232 Symbol symbolCopy = symbol.deepCopy(); 233 if (symbolCopy instanceof FunctionInfo) { 234 FunctionInfo functionInfo = (FunctionInfo) symbolCopy; 235 if (functionInfo.isConstructor()) { 236 continue; 237 } 238 if ((functionInfo.flags & FunctionInfo.STATIC) == 0) { 239 functionInfo.argTypes.get(0).type = thisKlass; 240 } 241 } 242 symbolCopy.owner = thisKlass; 243 SymbolTable.add(symbolCopy); 244 } 245 } 246 } 247 248 private void inheritInterfaces() { 249 // Select interfaces that we'll implement. 250 LinkedList<Type> probableInterfaces = new LinkedList<>(TypeList.getAll()); 251 for (Iterator<Type> i = probableInterfaces.iterator(); i.hasNext();) { 252 Type klass = i.next(); 253 if (!(klass instanceof TypeKlass) || !((TypeKlass) klass).isInterface()) { 254 i.remove(); 255 } 256 } 257 PseudoRandom.shuffle(probableInterfaces); 258 int implLimit = (int) (ProductionParams.implementationLimit.value() * PseudoRandom.random()); 259 // Mulitiple inheritance compatibility check 260 compatibility_check: 261 for (Iterator<Type> i = probableInterfaces.iterator(); i.hasNext() && implLimit > 0; implLimit--) { 262 TypeKlass iface = (TypeKlass) i.next(); 263 ArrayList<Symbol> ifaceFuncSet = SymbolTable.getAllCombined(iface, FunctionInfo.class); 264 for (Symbol symbol : SymbolTable.getAllCombined(thisKlass, FunctionInfo.class)) { 265 if (FunctionDefinition.isInvalidOverride((FunctionInfo) symbol, ifaceFuncSet)) { 266 continue compatibility_check; 267 } 268 } 269 interfaces.add(iface); 270 iface.addChild(name); 271 thisKlass.addParent(iface.getName()); 272 for (Symbol symbol : SymbolTable.getAllCombined(iface, FunctionInfo.class)) { 273 FunctionInfo functionInfo = (FunctionInfo) symbol.deepCopy(); 274 functionInfo.owner = thisKlass; 275 functionInfo.argTypes.get(0).type = thisKlass; 276 SymbolTable.add(functionInfo); 277 } 278 } 279 } 280 } |