private void insertClinit(DependencyInfo dependency, String className, MethodReference method, Instruction insn) { if (className.equals(method.getClassName())) { return; } ClassReader cls = dependency.getClassSource().get(className); if (cls == null || cls.getMethod(clinitDescriptor) != null) { InitClassInstruction initInsn = new InitClassInstruction(); initInsn.setClassName(className); initInsn.setLocation(insn.getLocation()); insn.insertPrevious(initInsn); } } }
private void devirtualize(Program program, MethodReference method, DependencyInfo dependencyInfo) { ClassInference inference = new ClassInference(dependencyInfo, hierarchy); inference.infer(program, method); for (BasicBlock block : program.getBasicBlocks()) { for (Instruction instruction : block) { if (!(instruction instanceof InvokeInstruction)) { continue; } InvokeInstruction invoke = (InvokeInstruction) instruction; if (invoke.getType() != InvocationType.VIRTUAL) { continue; } Set<MethodReference> implementations = new HashSet<>(); for (String className : inference.classesOf(invoke.getInstance().getIndex())) { MethodReference rawMethod = new MethodReference(className, invoke.getMethod().getDescriptor()); MethodReader resolvedMethod = dependencyInfo.getClassSource().resolveImplementation(rawMethod); if (resolvedMethod != null) { implementations.add(resolvedMethod.getReference()); } } if (implementations.size() == 1) { invoke.setType(InvocationType.SPECIAL); invoke.setMethod(implementations.iterator().next()); } } } }
private void propagateAlongVirtualCalls(Program program) { ClassReaderSource classSource = dependencyInfo.getClassSource();
private void devirtualize(Program program, MethodReference method, DependencyInfo dependencyInfo) { ClassInference inference = new ClassInference(dependencyInfo); inference.infer(program, method); for (BasicBlock block : program.getBasicBlocks()) { for (Instruction instruction : block) { if (!(instruction instanceof InvokeInstruction)) { continue; } InvokeInstruction invoke = (InvokeInstruction) instruction; if (invoke.getType() != InvocationType.VIRTUAL) { continue; } Set<MethodReference> implementations = new HashSet<>(); for (String className : inference.classesOf(invoke.getInstance().getIndex())) { MethodReference rawMethod = new MethodReference(className, invoke.getMethod().getDescriptor()); MethodReader resolvedMethod = dependencyInfo.getClassSource().resolve(rawMethod); if (resolvedMethod != null) { implementations.add(resolvedMethod.getReference()); } } if (implementations.size() == 1) { invoke.setType(InvocationType.SPECIAL); invoke.setMethod(implementations.iterator().next()); } } } }
private void propagate(Program program) { ClassReaderSource classSource = dependencyInfo.getClassSource();
@SuppressWarnings("WeakerAccess") public ListableClassHolderSource link(DependencyInfo dependency) { reportPhase(TeaVMPhase.LINKING, dependency.getReachableClasses().size()); Linker linker = new Linker(); MutableClassHolderSource cutClasses = new MutableClassHolderSource(); MissingItemsProcessor missingItemsProcessor = new MissingItemsProcessor(dependency, diagnostics); if (wasCancelled()) { return cutClasses; } int index = 0; for (String className : dependency.getReachableClasses()) { ClassReader clsReader = dependency.getClassSource().get(className); if (clsReader == null) { continue; } ClassHolder cls = ModelUtils.copyClass(clsReader); cutClasses.putClassHolder(cls); missingItemsProcessor.processClass(cls); linker.link(dependency, cls); progressListener.progressReached(++index); } return cutClasses; }