void initClass(ClassDependency cls, CallLocation callLocation) { ClassReader reader = cls.getClassReader(); MethodReader method = reader.getMethod(new MethodDescriptor("<clinit>", void.class)); if (method != null) { tasks.add(() -> linkMethod(method.getReference(), callLocation).use()); } }
public MethodDependency linkMethod(MethodReference methodRef, CallLocation callLocation) { if (methodRef == null) { throw new IllegalArgumentException(); } MethodReader methodReader = methodReaderCache.map(methodRef); if (methodReader != null) { methodRef = methodReader.getReference(); } if (completing && getMethod(methodRef) == null) { throw new IllegalStateException("Can't submit class during completion phase"); } callGraph.getNode(methodRef); boolean added = true; if (callLocation != null && callLocation.getMethod() != null) { added = callGraph .getNode(callLocation.getMethod()) .addCallSite(methodRef, callLocation.getSourceLocation()); } else { added = methodsAddedByRoot.add(methodRef); } MethodDependency graph = methodCache.map(methodRef); if (!graph.isMissing() && added) { for (DependencyListener listener : listeners) { listener.methodReached(agent, graph, callLocation); } activateDependencyPlugin(graph, callLocation); } return graph; }
@Override public void generate(GeneratorContext context, SourceWriter writer, MethodReference methodRef) throws IOException { ClassReader cls = context.getClassSource().get(methodRef.getClassName()); MethodReader method = cls.getMethod(methodRef.getDescriptor()); AnnotationReader providerAnnot = method.getAnnotations().get(MetadataProvider.class.getName()); AnnotationReader refAnnot = method.getAnnotations().get(MetadataProviderRef.class.getName()); methodRef = MethodReference.parse(refAnnot.getValue("value").getString()); // Find and instantiate metadata generator ValueType generatorType = providerAnnot.getValue("value").getJavaClass(); String generatorClassName = ((ValueType.Object) generatorType).getClassName(); Class<?> generatorClass; try { generatorClass = Class.forName(generatorClassName, true, context.getClassLoader()); } catch (ClassNotFoundException e) { context .getDiagnostics() .error( new CallLocation(methodRef), "Can't find metadata provider class {{c0}}", generatorClassName); return; } Constructor<?> cons; try { cons = generatorClass.getConstructor(); } catch (NoSuchMethodException e) { context .getDiagnostics() .error( new CallLocation(methodRef), "Metadata generator {{c0}} does not have " + "a public no-arg constructor", generatorClassName); return; } MetadataGenerator generator; try { generator = (MetadataGenerator) cons.newInstance(); } catch (IllegalAccessException | InstantiationException | InvocationTargetException e) { context .getDiagnostics() .error( new CallLocation(methodRef), "Error instantiating metadata " + "generator {{c0}}", generatorClassName); return; } DefaultMetadataGeneratorContext metadataContext = new DefaultMetadataGeneratorContext( context.getClassSource(), context.getClassLoader(), context.getProperties(), context); // Generate resource loader Resource resource = generator.generateMetadata(metadataContext, methodRef); writer.append("return "); ResourceWriterHelper.write(writer, resource); writer.append(';').softNewLine(); }
public void allocateRegisters(MethodReader method, Program program) { insertJointArgumentsCopies(program); insertPhiArgumentsCopies(program); InterferenceGraphBuilder interferenceBuilder = new InterferenceGraphBuilder(); LivenessAnalyzer liveness = new LivenessAnalyzer(); liveness.analyze(program); List<MutableGraphNode> interferenceGraph = interferenceBuilder.build(program, method.parameterCount(), liveness); DisjointSet congruenceClasses = buildPhiCongruenceClasses(program); joinClassNodes(interferenceGraph, congruenceClasses); removeRedundantCopies(program, interferenceGraph, congruenceClasses); int[] classArray = congruenceClasses.pack(program.variableCount()); renameVariables(program, classArray); int[] colors = new int[program.variableCount()]; Arrays.fill(colors, -1); for (int i = 0; i <= method.parameterCount(); ++i) { colors[i] = i; } renameInterferenceGraph(interferenceGraph, congruenceClasses, classArray); GraphColorer colorer = new GraphColorer(); int maxClass = 0; for (int cls : classArray) { maxClass = Math.max(maxClass, cls + 1); } int[] categories = getVariableCategories(program, method.getReference()); int[] classCategories = new int[maxClass]; for (int i = 0; i < categories.length; ++i) { classCategories[classArray[i]] = categories[i]; } colorer.colorize(interferenceGraph, colors, classCategories); for (int i = 0; i < colors.length; ++i) { program.variableAt(i).setRegister(colors[i]); } for (int i = 0; i < program.basicBlockCount(); ++i) { program.basicBlockAt(i).getPhis().clear(); program.basicBlockAt(i).getTryCatchJoints().clear(); } }
@Override public boolean acceptMethod(MethodReader method) { return method.getAnnotations().get(KOTest.class.getName()) != null; }
@Override public MethodDependency getMethodImplementation(MethodReference methodRef) { MethodReader method = methodReaderCache.map(methodRef); return method != null ? methodCache.getKnown(method.getReference()) : null; }