diff --git a/teavm-core/src/main/java/org/teavm/common/CachedMapper.java b/teavm-core/src/main/java/org/teavm/common/CachedMapper.java index 9ca551c3f..addf3a64e 100644 --- a/teavm-core/src/main/java/org/teavm/common/CachedMapper.java +++ b/teavm-core/src/main/java/org/teavm/common/CachedMapper.java @@ -48,6 +48,9 @@ public class CachedMapper implements Mapper { cache.put(preimage, wrapper); wrapper.value = innerMapper.map(preimage); wrapper.computed = true; + for (KeyListener listener : keyListeners) { + listener.keyAdded(preimage); + } } if (!wrapper.computed) { throw new IllegalStateException("Recursive calls are not allowed"); diff --git a/teavm-core/src/main/java/org/teavm/dependency/DependencyChecker.java b/teavm-core/src/main/java/org/teavm/dependency/DependencyChecker.java index 574a83e01..51821a750 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/DependencyChecker.java +++ b/teavm-core/src/main/java/org/teavm/dependency/DependencyChecker.java @@ -153,7 +153,7 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent { public void addEntryPoint(MethodReference methodRef, String... argumentTypes) { ValueType[] parameters = methodRef.getDescriptor().getParameterTypes(); - if (parameters.length != argumentTypes.length) { + if (parameters.length + 1 != argumentTypes.length) { throw new IllegalArgumentException("argumentTypes length does not match the number of method's arguments"); } MethodDependency method = linkMethod(methodRef, DependencyStack.ROOT); @@ -173,6 +173,16 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent { }); } + void schedulePropagation(final DependencyConsumer consumer, final DependencyType[] types) { + tasks.add(new Runnable() { + @Override public void run() { + for (DependencyType type : types) { + consumer.consume(type); + } + } + }); + } + boolean achieveClass(String className, DependencyStack stack) { classStacks.put(className, stack); if (!achievableClasses.add(className)) { diff --git a/teavm-core/src/main/java/org/teavm/dependency/DependencyGraphCreator.java b/teavm-core/src/main/java/org/teavm/dependency/DependencyGraphCreator.java index 0afc043d9..7bfe8459d 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/DependencyGraphCreator.java +++ b/teavm-core/src/main/java/org/teavm/dependency/DependencyGraphCreator.java @@ -20,5 +20,5 @@ package org.teavm.dependency; * @author Alexey Andreev */ public interface DependencyGraphCreator { - DependencyGraphCreatorProduct createDependency(DependencyChecker checker, DependencyStack stack); + void createDependency(MethodDependency method); } diff --git a/teavm-core/src/main/java/org/teavm/dependency/DependencyNode.java b/teavm-core/src/main/java/org/teavm/dependency/DependencyNode.java index d1daa9299..dabd324cf 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/DependencyNode.java +++ b/teavm-core/src/main/java/org/teavm/dependency/DependencyNode.java @@ -20,7 +20,6 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicReference; -import org.teavm.common.IntegerArray; /** * @@ -67,15 +66,40 @@ public class DependencyNode implements ValueDependencyInfo { } } + public void propagate(DependencyAgentType[] agentTypes) { + DependencyType[] types = new DependencyType[agentTypes.length]; + int j = 0; + for (int i = 0; i < agentTypes.length; ++i) { + DependencyAgentType agentType = agentTypes[i]; + if (!(agentType instanceof DependencyType)) { + throw new IllegalArgumentException("The given type does not belong to the same dependency checker"); + } + DependencyType type = (DependencyType)agentType; + if (type.getDependencyChecker() != dependencyChecker) { + throw new IllegalArgumentException("The given type does not belong to the same dependency checker"); + } + if (!this.types.get(type.index)) { + types[j++] = type; + } + } + for (int i = 0; i < j; ++i) { + this.types.set(types[i].index); + if (DependencyChecker.shouldLog) { + System.out.println(tag + " -> " + types[i].getName()); + } + } + for (DependencyConsumer consumer : followers.toArray(new DependencyConsumer[followers.size()])) { + dependencyChecker.schedulePropagation(consumer, Arrays.copyOf(types, j)); + } + } + public void addConsumer(DependencyConsumer consumer) { if (followers.add(consumer)) { - IntegerArray indexes = new IntegerArray(8); - for (int index = types.nextSetBit(0); index >= 0; index = types.nextSetBit(index + 1)) { - indexes.add(index); - } - for (int index : indexes.getAll()) { - dependencyChecker.schedulePropagation(consumer, dependencyChecker.types.get(index)); + List types = new ArrayList<>(); + for (int index = this.types.nextSetBit(0); index >= 0; index = this.types.nextSetBit(index + 1)) { + types.add(dependencyChecker.types.get(index)); } + dependencyChecker.schedulePropagation(consumer, types.toArray(new DependencyType[types.size()])); } } diff --git a/teavm-core/src/main/java/org/teavm/dependency/MethodDependency.java b/teavm-core/src/main/java/org/teavm/dependency/MethodDependency.java index af1b684a5..09955e1bb 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/MethodDependency.java +++ b/teavm-core/src/main/java/org/teavm/dependency/MethodDependency.java @@ -16,7 +16,6 @@ package org.teavm.dependency; import java.util.Arrays; -import java.util.concurrent.atomic.AtomicBoolean; import org.teavm.model.MethodReader; import org.teavm.model.MethodReference; @@ -33,8 +32,8 @@ public class MethodDependency implements MethodDependencyInfo { private DependencyStack stack; private MethodReader method; private MethodReference reference; - private AtomicBoolean used = new AtomicBoolean(); - private volatile Runnable useRunner; + private boolean used; + private Runnable useRunner; MethodDependency(DependencyChecker dependencyChecker, DependencyNode[] variableNodes, int parameterCount, DependencyNode resultNode, DependencyNode thrown, DependencyStack stack, MethodReader method, @@ -102,11 +101,12 @@ public class MethodDependency implements MethodDependencyInfo { @Override public boolean isUsed() { - return used.get(); + return used; } public void use() { - if (used.compareAndSet(false, true)) { + if (!used) { + used = true; if (useRunner != null) { useRunner.run(); useRunner = null; @@ -119,9 +119,6 @@ public class MethodDependency implements MethodDependencyInfo { runner.run(); } else { useRunner = runner; - if (isUsed()) { - runner.run(); - } } } } diff --git a/teavm-core/src/main/java/org/teavm/dependency/ProgrammableDependencyGraphCreator.java b/teavm-core/src/main/java/org/teavm/dependency/ProgrammableDependencyGraphCreator.java deleted file mode 100644 index ff7049e97..000000000 --- a/teavm-core/src/main/java/org/teavm/dependency/ProgrammableDependencyGraphCreator.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * 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.dependency; - -import org.teavm.model.ClassReader; -import org.teavm.model.ClassReaderSource; - -/** - * - * @author Alexey Andreev - */ -class ProgrammableDependencyGraphCreator implements DependencyGraphCreator { - int nodeCount; - Connection[] connections; - TypeRestrictedConnection[] typeRestrictedConnections; - TypePropagation[] typePropagations; - String[] initializedClasses; - int[] variableMap; - int resultIndex; - - ProgrammableDependencyGraphCreator() { - } - - @Override - public DependencyGraphCreatorProduct createDependency(DependencyChecker checker, DependencyStack stack) { - DependencyNode[] nodes = new DependencyNode[nodeCount]; - for (int i = 0; i < nodes.length; ++i) { - nodes[i] = checker.createNode(); - } - for (Connection conn : connections) { - nodes[conn.from].connect(nodes[conn.to]); - } - for (TypeRestrictedConnection conn : typeRestrictedConnections) { - nodes[conn.from].connect(nodes[conn.to], new DependencySupertypeFilter(checker.getClassSource(), - checker.getClassSource().get(conn.superclass))); - } - for (TypePropagation propagation : typePropagations) { - nodes[propagation.var].propagate(checker.getType(propagation.type)); - } - for (String className : initializedClasses) { - checker.initClass(className, stack); - } - return null; - } - - static class Connection { - int from; - int to; - } - - static class TypeRestrictedConnection { - int from; - int to; - String superclass; - } - - static class TypePropagation { - int var; - String type; - } - - static class DependencySupertypeFilter implements DependencyTypeFilter { - private ClassReaderSource classSource; - private ClassReader superClass; - public DependencySupertypeFilter(ClassReaderSource classSource, ClassReader superClass) { - this.classSource = classSource; - this.superClass = superClass; - } - @Override public boolean match(DependencyAgentType type) { - if (superClass.getName().equals("java.lang.Object")) { - return true; - } - return isAssignableFrom(classSource, superClass, type.getName()); - } - } - - private static boolean isAssignableFrom(ClassReaderSource classSource, ClassReader supertype, - String subtypeName) { - if (supertype.getName().equals(subtypeName)) { - return true; - } - ClassReader subtype = classSource.get(subtypeName); - if (subtype == null) { - return false; - } - if (subtype.getParent() != null && isAssignableFrom(classSource, supertype, subtype.getParent())) { - return true; - } - for (String iface : subtype.getInterfaces()) { - if (isAssignableFrom(classSource, supertype, iface)) { - return true; - } - } - return false; - } -} diff --git a/teavm-core/src/main/java/org/teavm/dependency/ProgrammableDependencyGraphCreatorBuilder.java b/teavm-core/src/main/java/org/teavm/dependency/ProgrammableDependencyGraphCreatorBuilder.java deleted file mode 100644 index 6a1d791aa..000000000 --- a/teavm-core/src/main/java/org/teavm/dependency/ProgrammableDependencyGraphCreatorBuilder.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * 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.dependency; - -/** - * - * @author Alexey Andreev - */ -public class ProgrammableDependencyGraphCreatorBuilder { - -}