Fixes devirtualization optimization

This commit is contained in:
konsoletyper 2014-03-01 16:58:38 +04:00
parent 723ad74f2e
commit f4fd2d884f
3 changed files with 30 additions and 8 deletions

View File

@ -158,8 +158,8 @@ public class JavascriptBuilder implements JavascriptBuilderHost {
Linker linker = new Linker(dependencyChecker); Linker linker = new Linker(dependencyChecker);
ListableClassHolderSource classSet = linker.link(classSource); ListableClassHolderSource classSet = linker.link(classSource);
Decompiler decompiler = new Decompiler(classSet, classLoader, executor); Decompiler decompiler = new Decompiler(classSet, classLoader, executor);
/*devirtualize(classSet, dependencyChecker); devirtualize(classSet, dependencyChecker);
executor.complete();*/ executor.complete();
ClassSetOptimizer optimizer = new ClassSetOptimizer(executor); ClassSetOptimizer optimizer = new ClassSetOptimizer(executor);
optimizer.optimizeAll(classSet); optimizer.optimizeAll(classSet);
executor.complete(); executor.complete();
@ -199,7 +199,6 @@ public class JavascriptBuilder implements JavascriptBuilderHost {
} }
// TODO: repair devirtualization // TODO: repair devirtualization
@SuppressWarnings("unused")
private void devirtualize(ListableClassHolderSource classes, DependencyInfo dependency) { private void devirtualize(ListableClassHolderSource classes, DependencyInfo dependency) {
final Devirtualization devirtualization = new Devirtualization(dependency, classes); final Devirtualization devirtualization = new Devirtualization(dependency, classes);
for (String className : classes.getClassNames()) { for (String className : classes.getClassNames()) {

View File

@ -55,7 +55,7 @@ public class Devirtualization {
} }
ValueDependencyInfo var = methodDep.getVariable(invoke.getInstance().getIndex()); ValueDependencyInfo var = methodDep.getVariable(invoke.getInstance().getIndex());
Set<MethodReference> implementations = getImplementations(var.getTypes(), Set<MethodReference> implementations = getImplementations(var.getTypes(),
invoke.getMethod().getDescriptor()); invoke.getMethod());
if (implementations.size() == 1) { if (implementations.size() == 1) {
invoke.setType(InvocationType.SPECIAL); invoke.setType(InvocationType.SPECIAL);
invoke.setMethod(implementations.iterator().next()); invoke.setMethod(implementations.iterator().next());
@ -64,14 +64,37 @@ public class Devirtualization {
} }
} }
private Set<MethodReference> getImplementations(String[] classNames, MethodDescriptor desc) { private Set<MethodReference> getImplementations(String[] classNames, MethodReference ref) {
Set<MethodReference> methods = new HashSet<>(); Set<MethodReference> methods = new HashSet<>();
for (String className : classNames) { for (String className : classNames) {
ClassReader cls = classSource.get(className); ClassReader cls = classSource.get(className);
if (cls != null && cls.getMethod(desc) != null) { if (cls == null || !isAssignable(ref.getClassName(), cls)) {
methods.add(new MethodReference(className, desc)); break;
}
MethodDependencyInfo methodDep = dependency.getMethod(new MethodReference(className, ref.getDescriptor()));
if (methodDep != null) {
methods.add(methodDep.getReference());
} }
} }
return methods; return methods;
} }
private boolean isAssignable(String target, ClassReader cls) {
if (cls.getName().equals(target)) {
return true;
}
if (cls.getParent() != null) {
ClassReader parent = classSource.get(cls.getParent());
if (parent != null && isAssignable(target, parent)) {
return true;
}
}
for (String ifaceName : cls.getInterfaces()) {
ClassReader iface = classSource.get(ifaceName);
if (iface != null && isAssignable(target, iface)) {
return true;
}
}
return false;
}
} }

View File

@ -85,7 +85,7 @@
</goals> </goals>
<phase>process-test-classes</phase> <phase>process-test-classes</phase>
<configuration> <configuration>
<minifying>true</minifying> <minifying>false</minifying>
<numThreads>1</numThreads> <numThreads>1</numThreads>
<scanDependencies>true</scanDependencies> <scanDependencies>true</scanDependencies>
<outputDir>${project.build.directory}/javascript-tck</outputDir> <outputDir>${project.build.directory}/javascript-tck</outputDir>