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

View File

@ -55,7 +55,7 @@ public class Devirtualization {
}
ValueDependencyInfo var = methodDep.getVariable(invoke.getInstance().getIndex());
Set<MethodReference> implementations = getImplementations(var.getTypes(),
invoke.getMethod().getDescriptor());
invoke.getMethod());
if (implementations.size() == 1) {
invoke.setType(InvocationType.SPECIAL);
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<>();
for (String className : classNames) {
ClassReader cls = classSource.get(className);
if (cls != null && cls.getMethod(desc) != null) {
methods.add(new MethodReference(className, desc));
if (cls == null || !isAssignable(ref.getClassName(), cls)) {
break;
}
MethodDependencyInfo methodDep = dependency.getMethod(new MethodReference(className, ref.getDescriptor()));
if (methodDep != null) {
methods.add(methodDep.getReference());
}
}
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>
<phase>process-test-classes</phase>
<configuration>
<minifying>true</minifying>
<minifying>false</minifying>
<numThreads>1</numThreads>
<scanDependencies>true</scanDependencies>
<outputDir>${project.build.directory}/javascript-tck</outputDir>