Fixes small bugs. Introduces a new class source that does a slight

optimization before providing classes.
This commit is contained in:
konsoletyper 2014-09-04 17:18:22 +04:00
parent 89d6a453ec
commit f740782881
3 changed files with 63 additions and 35 deletions

View File

@ -16,9 +16,9 @@
package org.teavm.dependency;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.Set;
import org.teavm.model.*;
import org.teavm.model.instructions.*;
import org.teavm.model.util.ListingBuilder;
@ -124,7 +124,7 @@ class DependencyGraphBuilder {
private final DependencyNode[] parameters;
private final DependencyNode result;
private final DependencyStack stack;
private final ConcurrentMap<MethodReference, MethodReference> knownMethods = new ConcurrentHashMap<>();
private final Set<MethodReference> knownMethods = new HashSet<>();
private ExceptionConsumer exceptionConsumer;
public VirtualCallConsumer(DependencyNode node, ClassReader filterClass,
@ -155,13 +155,13 @@ class DependencyGraphBuilder {
}
MethodReference methodRef = new MethodReference(className, methodDesc);
MethodDependency methodDep = checker.linkMethod(methodRef, stack);
if (!methodDep.isMissing() && knownMethods.putIfAbsent(methodRef, methodRef) == null) {
if (!methodDep.isMissing() && knownMethods.add(methodRef)) {
methodDep.use();
DependencyNode[] targetParams = methodDep.getVariables();
for (int i = 0; i < parameters.length; ++i) {
parameters[i].connect(targetParams[i]);
}
if (methodDep.getResult() != null) {
if (result != null && methodDep.getResult() != null) {
methodDep.getResult().connect(result);
}
methodDep.getThrown().addConsumer(exceptionConsumer);

View File

@ -16,10 +16,6 @@
package org.teavm.dependency;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicReference;
/**
*
@ -29,10 +25,9 @@ public class DependencyNode implements ValueDependencyInfo {
private DependencyChecker dependencyChecker;
private Set<DependencyConsumer> followers = new HashSet<>();
private BitSet types = new BitSet();
private ConcurrentMap<DependencyNode, DependencyNodeToNodeTransition> transitions = new ConcurrentHashMap<>();
private Map<DependencyNode, DependencyNodeToNodeTransition> transitions = new HashMap<>();
private volatile String tag;
private final AtomicReference<DependencyNode> arrayItemNode = new AtomicReference<>();
private volatile CountDownLatch arrayItemNodeLatch = new CountDownLatch(1);
private DependencyNode arrayItemNode;
private int degree;
DependencyNode(DependencyChecker dependencyChecker) {
@ -105,7 +100,8 @@ public class DependencyNode implements ValueDependencyInfo {
public void connect(DependencyNode node, DependencyTypeFilter filter) {
DependencyNodeToNodeTransition transition = new DependencyNodeToNodeTransition(this, node, filter);
if (transitions.putIfAbsent(node, transition) == null) {
if (!transitions.containsKey(node)) {
transitions.put(node, transition);
if (DependencyChecker.shouldLog) {
System.out.println("Connecting " + tag + " to " + node.tag);
}
@ -119,34 +115,18 @@ public class DependencyNode implements ValueDependencyInfo {
@Override
public DependencyNode getArrayItem() {
DependencyNode result = arrayItemNode.get();
if (result == null) {
result = new DependencyNode(dependencyChecker, degree + 1);
if (arrayItemNode.compareAndSet(null, result)) {
if (DependencyChecker.shouldLog) {
arrayItemNode.get().tag = tag + "[";
}
arrayItemNodeLatch.countDown();
arrayItemNodeLatch = null;
} else {
result = arrayItemNode.get();
if (arrayItemNode == null) {
arrayItemNode = new DependencyNode(dependencyChecker, degree + 1);
if (DependencyChecker.shouldLog) {
arrayItemNode.tag = tag + "[";
}
}
CountDownLatch latch = arrayItemNodeLatch;
if (latch != null) {
try {
latch.await();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return result;
}
}
return result;
return arrayItemNode;
}
@Override
public boolean hasArrayType() {
return arrayItemNode.get() != null && !arrayItemNode.get().types.isEmpty();
return arrayItemNode != null && arrayItemNode.types.isEmpty();
}
public boolean hasType(DependencyAgentType type) {

View File

@ -0,0 +1,48 @@
/*
* Copyright 2014 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.model;
import java.util.HashMap;
import java.util.Map;
import org.teavm.optimization.GlobalValueNumbering;
import org.teavm.optimization.UnusedVariableElimination;
/**
*
* @author Alexey Andreev
*/
public class PreOptimizingClassHolderSource implements ClassHolderSource {
private ClassHolderSource innerClassSource;
private Map<String, ClassHolder> cache = new HashMap<>();
public PreOptimizingClassHolderSource(ClassHolderSource innerClassSource) {
this.innerClassSource = innerClassSource;
}
@Override
public ClassHolder get(String name) {
ClassHolder cls = cache.get(name);
if (cls == null) {
cls = innerClassSource.get(name);
for (MethodHolder method : cls.getMethods()) {
new GlobalValueNumbering().optimize(method, method.getProgram());
new UnusedVariableElimination().optimize(method, method.getProgram());
}
cache.put(name, cls);
}
return cls;
}
}