mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 16:14:10 -08:00
Fixes bugs. Adds JCL implementation
This commit is contained in:
parent
59e6095fef
commit
31b9525309
|
@ -54,6 +54,9 @@
|
||||||
<configuration>
|
<configuration>
|
||||||
<minifying>false</minifying>
|
<minifying>false</minifying>
|
||||||
<numThreads>1</numThreads>
|
<numThreads>1</numThreads>
|
||||||
|
<wildcards>
|
||||||
|
<param>**.ArraysTest</param>
|
||||||
|
</wildcards>
|
||||||
</configuration>
|
</configuration>
|
||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
|
|
|
@ -128,10 +128,10 @@ public class TArrayList<E> extends TAbstractList<E> implements TCloneable, TSeri
|
||||||
}
|
}
|
||||||
ensureCapacity(size + c.size());
|
ensureCapacity(size + c.size());
|
||||||
int gap = c.size();
|
int gap = c.size();
|
||||||
size += gap;
|
for (int i = size - 1; i >= index; --i) {
|
||||||
for (int i = gap - 1; i > index; --i) {
|
array[i + gap] = array[i];
|
||||||
array[i] = array[i - gap];
|
|
||||||
}
|
}
|
||||||
|
size += gap;
|
||||||
TIterator<? extends E> iter = c.iterator();
|
TIterator<? extends E> iter = c.iterator();
|
||||||
for (int i = 0; i < gap; ++i) {
|
for (int i = 0; i < gap; ++i) {
|
||||||
array[index++] = iter.next();
|
array[index++] = iter.next();
|
||||||
|
|
|
@ -182,4 +182,99 @@ public class TArrays extends TObject {
|
||||||
public static void fill(TObject[] a, TObject val) {
|
public static void fill(TObject[] a, TObject val) {
|
||||||
fill(a, 0, a.length, val);
|
fill(a, 0, a.length, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void sort(Object[] a) {
|
||||||
|
sort(a, new NaturalOrder());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sort(Object[] a, int fromIndex, int toIndex) {
|
||||||
|
sort(a, fromIndex, toIndex, new NaturalOrder());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class NaturalOrder implements TComparator<Object> {
|
||||||
|
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||||
|
@Override public int compare(Object o1, Object o2) {
|
||||||
|
if (o1 != null) {
|
||||||
|
return ((TComparable)o1).compareTo((TComparable)o2);
|
||||||
|
} else if (o2 != null) {
|
||||||
|
return ((TComparable)o2).compareTo((TComparable)o1);
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> void sort(T[] a, int fromIndex, int toIndex, TComparator<? super T> c) {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
T[] subarray = (T[])new Object[toIndex - fromIndex];
|
||||||
|
for (int i = fromIndex; i < toIndex; ++i) {
|
||||||
|
subarray[i - fromIndex] = a[i];
|
||||||
|
}
|
||||||
|
sort(subarray, c);
|
||||||
|
for (int i = fromIndex; i < toIndex; ++i) {
|
||||||
|
a[i] = subarray[i - fromIndex];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static <T> void sort(T[] a, TComparator<? super T> c) {
|
||||||
|
Object[] first = a;
|
||||||
|
Object[] second = new Object[a.length];
|
||||||
|
int chunkSize = 1;
|
||||||
|
while (chunkSize < a.length) {
|
||||||
|
for (int i = 0; i < first.length; i += chunkSize * 2) {
|
||||||
|
merge(first, second, i, Math.min(first.length, i + chunkSize),
|
||||||
|
Math.min(first.length, i + 2 * chunkSize), (TComparator<Object>)c);
|
||||||
|
}
|
||||||
|
Object[] tmp = first;
|
||||||
|
first = second;
|
||||||
|
second = tmp;
|
||||||
|
chunkSize *= 2;
|
||||||
|
}
|
||||||
|
if (first != a) {
|
||||||
|
for (int i = 0; i < first.length; ++i) {
|
||||||
|
second[i] = first[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void merge(Object[] a, Object[] b, int from, int split, int to, TComparator<Object> comp) {
|
||||||
|
int index = from;
|
||||||
|
int from2 = split;
|
||||||
|
while (true) {
|
||||||
|
if (from == split) {
|
||||||
|
while (from2 < to) {
|
||||||
|
b[index++] = a[from2++];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
} else if (from2 == to) {
|
||||||
|
while (from < split) {
|
||||||
|
b[index++] = a[from++];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Object p = a[from];
|
||||||
|
Object q = a[from2];
|
||||||
|
if (comp.compare(p, q) <= 0) {
|
||||||
|
b[index++] = p;
|
||||||
|
++from;
|
||||||
|
} else {
|
||||||
|
b[index++] = q;
|
||||||
|
++from2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SafeVarargs
|
||||||
|
public static <T> TList<T> asList(final T... a) {
|
||||||
|
return new TAbstractList<T>() {
|
||||||
|
@Override public T get(int index) {
|
||||||
|
return a[index];
|
||||||
|
}
|
||||||
|
@Override public int size() {
|
||||||
|
return a.length;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,135 @@
|
||||||
|
/*
|
||||||
|
* 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.classlib.java.util;
|
||||||
|
|
||||||
|
import org.teavm.classlib.java.lang.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Alexey Andreev
|
||||||
|
*/
|
||||||
|
public class TCollections extends TObject {
|
||||||
|
public static <T> TIterator<T> emptyIterator() {
|
||||||
|
return new TIterator<T>() {
|
||||||
|
@Override public boolean hasNext() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
@Override public T next() {
|
||||||
|
throw new TNoSuchElementException();
|
||||||
|
}
|
||||||
|
@Override public void remove() {
|
||||||
|
throw new TIllegalStateException();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> TListIterator<T> emptyListIterator() {
|
||||||
|
return new TListIterator<T>() {
|
||||||
|
@Override public boolean hasNext() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
@Override public T next() {
|
||||||
|
throw new TNoSuchElementException();
|
||||||
|
}
|
||||||
|
@Override public void remove() {
|
||||||
|
throw new TIllegalStateException();
|
||||||
|
}
|
||||||
|
@Override public boolean hasPrevious() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
@Override public T previous() {
|
||||||
|
throw new TNoSuchElementException();
|
||||||
|
}
|
||||||
|
@Override public int nextIndex() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@Override public int previousIndex() {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
@Override public void set(T e) {
|
||||||
|
throw new TUnsupportedOperationException();
|
||||||
|
}
|
||||||
|
@Override public void add(T e) {
|
||||||
|
throw new TUnsupportedOperationException();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final <T> TList<T> emptyList() {
|
||||||
|
return new TAbstractList<T>() {
|
||||||
|
@Override public T get(int index) {
|
||||||
|
throw new TIndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
@Override public int size() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> TList<T> singletonList(final T o) {
|
||||||
|
return new TAbstractList<T>() {
|
||||||
|
@Override public T get(int index) {
|
||||||
|
if (index != 0) {
|
||||||
|
throw new TIndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
@Override public int size() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> TList<T> nCopies(final int n, final T o) {
|
||||||
|
return new TAbstractList<T>() {
|
||||||
|
@Override public T get(int index) {
|
||||||
|
if (index < 0 || index >= n) {
|
||||||
|
throw new TIndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
@Override public int size() {
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void swap(TList<?> list, int i, int j) {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
TList<Object> objList = (TList<Object>)list;
|
||||||
|
Object tmp = objList.get(i);
|
||||||
|
objList.set(i, objList.get(j));
|
||||||
|
objList.set(j, tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> void sort(TList<T> list, TComparator<? super T> c) {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
T[] array = (T[])new Object[list.size()];
|
||||||
|
list.toArray(array);
|
||||||
|
TArrays.sort(array, c);
|
||||||
|
for (int i = 0; i < array.length; ++i) {
|
||||||
|
list.set(i, array[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T extends TComparable<? super T>> void sort(TList<T> list) {
|
||||||
|
sort(list, new TComparator<T>() {
|
||||||
|
@Override public int compare(T o1, T o2) {
|
||||||
|
return o1 != null ? o1.compareTo(o2) : -o2.compareTo(o1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,14 +15,10 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.classlib.java.util;
|
package org.teavm.classlib.java.util;
|
||||||
|
|
||||||
import org.teavm.classlib.java.lang.TObject;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Alexey Andreev <konsoletyper@gmail.com>
|
* @author Alexey Andreev <konsoletyper@gmail.com>
|
||||||
*/
|
*/
|
||||||
public interface TComparator<T extends TObject> {
|
public interface TComparator<T> {
|
||||||
int compare(T o1, T o2);
|
int compare(T o1, T o2);
|
||||||
|
|
||||||
boolean equals(TObject obj);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,6 +78,35 @@ public class ArrayListTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void manyElementsAdded() {
|
||||||
|
List<Integer> list = fillFromZeroToNine();
|
||||||
|
list.addAll(3, fillFromZeroToNine());
|
||||||
|
assertEquals(20, list.size());
|
||||||
|
assertEquals(Integer.valueOf(2), list.get(2));
|
||||||
|
assertEquals(Integer.valueOf(0), list.get(3));
|
||||||
|
assertEquals(Integer.valueOf(9), list.get(12));
|
||||||
|
assertEquals(Integer.valueOf(3), list.get(13));
|
||||||
|
assertEquals(Integer.valueOf(9), list.get(19));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void manyElementsRemoved() {
|
||||||
|
List<Integer> list = fillFromZeroToNine();
|
||||||
|
list.subList(2, 4).clear();
|
||||||
|
assertEquals(8, list.size());
|
||||||
|
assertEquals(Integer.valueOf(1), list.get(1));
|
||||||
|
assertEquals(Integer.valueOf(4), list.get(2));
|
||||||
|
assertEquals(Integer.valueOf(9), list.get(7));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void elementIndexFound() {
|
||||||
|
List<Integer> list = fillFromZeroToNine();
|
||||||
|
assertEquals(3, list.indexOf(3));
|
||||||
|
assertEquals(-1, list.indexOf(100));
|
||||||
|
}
|
||||||
|
|
||||||
private List<Integer> fillFromZeroToNine() {
|
private List<Integer> fillFromZeroToNine() {
|
||||||
List<Integer> list = new ArrayList<>();
|
List<Integer> list = new ArrayList<>();
|
||||||
for (int i = 0; i < 10; ++i) {
|
for (int i = 0; i < 10; ++i) {
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
* 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.classlib.java.lang.util;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Alexey Andreev
|
||||||
|
*/
|
||||||
|
public class ArraysTest {
|
||||||
|
@Test
|
||||||
|
public void arraySorted() {
|
||||||
|
Integer[] array = { 2, 5, 7, 3, 5, 6 };
|
||||||
|
Arrays.sort(array);
|
||||||
|
assertEquals(Integer.valueOf(2), array[0]);
|
||||||
|
assertEquals(Integer.valueOf(3), array[1]);
|
||||||
|
assertEquals(Integer.valueOf(5), array[2]);
|
||||||
|
assertEquals(Integer.valueOf(5), array[3]);
|
||||||
|
assertEquals(Integer.valueOf(6), array[4]);
|
||||||
|
assertEquals(Integer.valueOf(7), array[5]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void arrayExposedAsList() {
|
||||||
|
Integer[] array = { 2, 3, 4 };
|
||||||
|
List<Integer> list = Arrays.asList(array);
|
||||||
|
assertEquals(3, list.size());
|
||||||
|
assertEquals(Integer.valueOf(4), list.get(2));
|
||||||
|
}
|
||||||
|
}
|
|
@ -43,8 +43,8 @@ public class GraphBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addEdge(int from, int to) {
|
public void addEdge(int from, int to) {
|
||||||
if (to < 0) {
|
if (to < 0 || from < 0) {
|
||||||
throw new IllegalArgumentException("To is negative: " + to);
|
throw new IllegalArgumentException();
|
||||||
}
|
}
|
||||||
sz = Math.max(sz, Math.max(from, to) + 1);
|
sz = Math.max(sz, Math.max(from, to) + 1);
|
||||||
builtGraph = null;
|
builtGraph = null;
|
||||||
|
|
|
@ -141,7 +141,6 @@ public class DependencyChecker implements DependencyInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void schedulePropagation(final DependencyConsumer consumer, final String type) {
|
public void schedulePropagation(final DependencyConsumer consumer, final String type) {
|
||||||
System.out.print("");
|
|
||||||
executor.executeFast(new Runnable() {
|
executor.executeFast(new Runnable() {
|
||||||
@Override public void run() {
|
@Override public void run() {
|
||||||
consumer.consume(type);
|
consumer.consume(type);
|
||||||
|
|
|
@ -41,8 +41,8 @@ class DependencyNodeToNodeTransition implements DependencyConsumer {
|
||||||
}
|
}
|
||||||
if (!destination.hasType(type)) {
|
if (!destination.hasType(type)) {
|
||||||
destination.propagate(type);
|
destination.propagate(type);
|
||||||
source.getArrayItem().connect(destination.getArrayItem());
|
|
||||||
destination.getArrayItem().connect(source.getArrayItem());
|
|
||||||
}
|
}
|
||||||
|
source.getArrayItem().connect(destination.getArrayItem());
|
||||||
|
destination.getArrayItem().connect(source.getArrayItem());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,226 @@
|
||||||
|
/*
|
||||||
|
* 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.util;
|
||||||
|
|
||||||
|
import org.teavm.model.Variable;
|
||||||
|
import org.teavm.model.instructions.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Alexey Andreev
|
||||||
|
*/
|
||||||
|
public abstract class InstructionVariableMapper implements InstructionVisitor {
|
||||||
|
protected abstract Variable map(Variable var);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(EmptyInstruction insn) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(ClassConstantInstruction insn) {
|
||||||
|
insn.setReceiver(map(insn.getReceiver()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(NullConstantInstruction insn) {
|
||||||
|
insn.setReceiver(map(insn.getReceiver()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(IntegerConstantInstruction insn) {
|
||||||
|
insn.setReceiver(map(insn.getReceiver()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(LongConstantInstruction insn) {
|
||||||
|
insn.setReceiver(map(insn.getReceiver()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(FloatConstantInstruction insn) {
|
||||||
|
insn.setReceiver(map(insn.getReceiver()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(DoubleConstantInstruction insn) {
|
||||||
|
insn.setReceiver(map(insn.getReceiver()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(StringConstantInstruction insn) {
|
||||||
|
insn.setReceiver(map(insn.getReceiver()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(BinaryInstruction insn) {
|
||||||
|
insn.setReceiver(map(insn.getReceiver()));
|
||||||
|
insn.setFirstOperand(map(insn.getFirstOperand()));
|
||||||
|
insn.setSecondOperand(map(insn.getSecondOperand()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(NegateInstruction insn) {
|
||||||
|
insn.setReceiver(map(insn.getReceiver()));
|
||||||
|
insn.setOperand(map(insn.getOperand()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(AssignInstruction insn) {
|
||||||
|
insn.setReceiver(map(insn.getReceiver()));
|
||||||
|
insn.setAssignee(map(insn.getAssignee()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(CastInstruction insn) {
|
||||||
|
insn.setReceiver(map(insn.getReceiver()));
|
||||||
|
insn.setValue(map(insn.getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(CastNumberInstruction insn) {
|
||||||
|
insn.setReceiver(map(insn.getReceiver()));
|
||||||
|
insn.setValue(map(insn.getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(CastIntegerInstruction insn) {
|
||||||
|
insn.setReceiver(map(insn.getReceiver()));
|
||||||
|
insn.setValue(map(insn.getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(BranchingInstruction insn) {
|
||||||
|
insn.setOperand(map(insn.getOperand()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(BinaryBranchingInstruction insn) {
|
||||||
|
insn.setFirstOperand(map(insn.getFirstOperand()));
|
||||||
|
insn.setSecondOperand(map(insn.getSecondOperand()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(JumpInstruction insn) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(SwitchInstruction insn) {
|
||||||
|
insn.setCondition(insn.getCondition());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(ExitInstruction insn) {
|
||||||
|
if (insn.getValueToReturn() != null) {
|
||||||
|
insn.setValueToReturn(map(insn.getValueToReturn()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(RaiseInstruction insn) {
|
||||||
|
insn.setException(map(insn.getException()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(ConstructArrayInstruction insn) {
|
||||||
|
insn.setReceiver(map(insn.getReceiver()));
|
||||||
|
insn.setSize(map(insn.getSize()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(ConstructInstruction insn) {
|
||||||
|
insn.setReceiver(map(insn.getReceiver()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(ConstructMultiArrayInstruction insn) {
|
||||||
|
insn.setReceiver(map(insn.getReceiver()));
|
||||||
|
for (int i = 0; i < insn.getDimensions().size(); ++i) {
|
||||||
|
insn.getDimensions().set(i, map(insn.getDimensions().get(i)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(GetFieldInstruction insn) {
|
||||||
|
if (insn.getInstance() != null) {
|
||||||
|
insn.setInstance(map(insn.getInstance()));
|
||||||
|
}
|
||||||
|
insn.setReceiver(map(insn.getReceiver()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(PutFieldInstruction insn) {
|
||||||
|
if (insn.getInstance() != null) {
|
||||||
|
insn.setInstance(map(insn.getInstance()));
|
||||||
|
}
|
||||||
|
insn.setValue(map(insn.getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(ArrayLengthInstruction insn) {
|
||||||
|
insn.setReceiver(map(insn.getReceiver()));
|
||||||
|
insn.setArray(map(insn.getArray()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(CloneArrayInstruction insn) {
|
||||||
|
insn.setReceiver(map(insn.getReceiver()));
|
||||||
|
insn.setArray(map(insn.getArray()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(UnwrapArrayInstruction insn) {
|
||||||
|
insn.setReceiver(map(insn.getReceiver()));
|
||||||
|
insn.setArray(map(insn.getArray()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(GetElementInstruction insn) {
|
||||||
|
insn.setReceiver(map(insn.getReceiver()));
|
||||||
|
insn.setArray(map(insn.getArray()));
|
||||||
|
insn.setIndex(map(insn.getIndex()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(PutElementInstruction insn) {
|
||||||
|
insn.setValue(map(insn.getValue()));
|
||||||
|
insn.setArray(map(insn.getArray()));
|
||||||
|
insn.setIndex(map(insn.getIndex()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(InvokeInstruction insn) {
|
||||||
|
if (insn.getReceiver() != null) {
|
||||||
|
insn.setReceiver(map(insn.getReceiver()));
|
||||||
|
}
|
||||||
|
if (insn.getInstance() != null) {
|
||||||
|
insn.setInstance(map(insn.getInstance()));
|
||||||
|
}
|
||||||
|
for (int i = 0; i < insn.getArguments().size(); ++i) {
|
||||||
|
insn.getArguments().set(i, map(insn.getArguments().get(i)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(IsInstanceInstruction insn) {
|
||||||
|
insn.setReceiver(map(insn.getReceiver()));
|
||||||
|
insn.setValue(map(insn.getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(InitClassInstruction insn) {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -150,11 +150,15 @@ public class RegisterAllocator {
|
||||||
copy.incoming.setValue(program.variableAt(copy.original));
|
copy.incoming.setValue(program.variableAt(copy.original));
|
||||||
for (MutableGraphEdge edge : interferenceGraph.get(varClass).getEdges()
|
for (MutableGraphEdge edge : interferenceGraph.get(varClass).getEdges()
|
||||||
.toArray(new MutableGraphEdge[0])) {
|
.toArray(new MutableGraphEdge[0])) {
|
||||||
edge.setFirst(interferenceGraph.get(newClass));
|
if (edge.getFirst() != null) {
|
||||||
|
edge.setFirst(interferenceGraph.get(newClass));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (MutableGraphEdge edge : interferenceGraph.get(origClass).getEdges()
|
for (MutableGraphEdge edge : interferenceGraph.get(origClass).getEdges()
|
||||||
.toArray(new MutableGraphEdge[0])) {
|
.toArray(new MutableGraphEdge[0])) {
|
||||||
edge.setFirst(interferenceGraph.get(newClass));
|
if (edge.getFirst() != null) {
|
||||||
|
edge.setFirst(interferenceGraph.get(newClass));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,7 @@ public class ClassSetOptimizer {
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<MethodOptimization> getOptimizations() {
|
private List<MethodOptimization> getOptimizations() {
|
||||||
return Arrays.<MethodOptimization>asList(new CommonSubexpressionElimination(), new UnusedVariableElimination());
|
return Arrays.<MethodOptimization>asList(new UnusedVariableElimination());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void optimizeAll(ListableClassHolderSource classSource) {
|
public void optimizeAll(ListableClassHolderSource classSource) {
|
||||||
|
|
|
@ -15,7 +15,9 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.optimization;
|
package org.teavm.optimization;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import org.teavm.common.DominatorTree;
|
import org.teavm.common.DominatorTree;
|
||||||
import org.teavm.common.Graph;
|
import org.teavm.common.Graph;
|
||||||
|
@ -52,6 +54,7 @@ public class CommonSubexpressionElimination implements MethodOptimization {
|
||||||
for (int i = 0; i < map.length; ++i) {
|
for (int i = 0; i < map.length; ++i) {
|
||||||
map[i] = i;
|
map[i] = i;
|
||||||
}
|
}
|
||||||
|
List<List<Incoming>> outgoings = findOutgoings(program);
|
||||||
|
|
||||||
int[] stack = new int[cfg.size() * 2];
|
int[] stack = new int[cfg.size() * 2];
|
||||||
int top = 0;
|
int top = 0;
|
||||||
|
@ -64,7 +67,7 @@ public class CommonSubexpressionElimination implements MethodOptimization {
|
||||||
int v = stack[--top];
|
int v = stack[--top];
|
||||||
currentBlockIndex = v;
|
currentBlockIndex = v;
|
||||||
BasicBlock block = program.basicBlockAt(v);
|
BasicBlock block = program.basicBlockAt(v);
|
||||||
for (int i = 0; i < block.getPhis().size(); ++i) {
|
/*for (int i = 0; i < block.getPhis().size(); ++i) {
|
||||||
Phi phi = block.getPhis().get(i);
|
Phi phi = block.getPhis().get(i);
|
||||||
int sharedValue = -2;
|
int sharedValue = -2;
|
||||||
for (Incoming incoming : phi.getIncomings()) {
|
for (Incoming incoming : phi.getIncomings()) {
|
||||||
|
@ -77,32 +80,31 @@ public class CommonSubexpressionElimination implements MethodOptimization {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sharedValue != -1) {
|
if (sharedValue != -1) {
|
||||||
map[phi.getReceiver().getIndex()] = sharedValue;
|
if (sharedValue != -2) {
|
||||||
|
AssignInstruction assignInsn = new AssignInstruction();
|
||||||
|
assignInsn.setReceiver(phi.getReceiver());
|
||||||
|
assignInsn.setAssignee(program.variableAt(sharedValue));
|
||||||
|
block.getInstructions().add(0, assignInsn);
|
||||||
|
}
|
||||||
block.getPhis().remove(i--);
|
block.getPhis().remove(i--);
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
for (int i = 0; i < block.getInstructions().size(); ++i) {
|
for (int i = 0; i < block.getInstructions().size(); ++i) {
|
||||||
Instruction currentInsn = block.getInstructions().get(i);
|
Instruction currentInsn = block.getInstructions().get(i);
|
||||||
currentInsn.acceptVisitor(optimizer);
|
currentInsn.acceptVisitor(optimizer);
|
||||||
if (eliminate) {
|
if (eliminate) {
|
||||||
block.getInstructions().remove(i--);
|
block.getInstructions().set(i, new EmptyInstruction());
|
||||||
eliminate = false;
|
eliminate = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (Incoming incoming : outgoings.get(v)) {
|
||||||
|
int value = map[incoming.getValue().getIndex()];
|
||||||
|
incoming.setValue(program.variableAt(value));
|
||||||
|
}
|
||||||
for (int succ : dom.outgoingEdges(v)) {
|
for (int succ : dom.outgoingEdges(v)) {
|
||||||
stack[top++] = succ;
|
stack[top++] = succ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (int v = 0; v < program.basicBlockCount(); ++v) {
|
|
||||||
BasicBlock block = program.basicBlockAt(v);
|
|
||||||
for (int i = 0; i < block.getPhis().size(); ++i) {
|
|
||||||
Phi phi = block.getPhis().get(i);
|
|
||||||
for (Incoming incoming : phi.getIncomings()) {
|
|
||||||
int value = map[incoming.getValue().getIndex()];
|
|
||||||
incoming.setValue(program.variableAt(value));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < map.length; ++i) {
|
for (int i = 0; i < map.length; ++i) {
|
||||||
if (map[i] != i) {
|
if (map[i] != i) {
|
||||||
|
@ -114,6 +116,21 @@ public class CommonSubexpressionElimination implements MethodOptimization {
|
||||||
program = null;
|
program = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<List<Incoming>> findOutgoings(Program program) {
|
||||||
|
List<List<Incoming>> outgoings = new ArrayList<>();
|
||||||
|
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
||||||
|
outgoings.add(new ArrayList<Incoming>());
|
||||||
|
}
|
||||||
|
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
||||||
|
for (Phi phi : program.basicBlockAt(i).getPhis()) {
|
||||||
|
for (Incoming incoming : phi.getIncomings()) {
|
||||||
|
outgoings.get(incoming.getSource().getIndex()).add(incoming);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return outgoings;
|
||||||
|
}
|
||||||
|
|
||||||
private void bind(int var, String value) {
|
private void bind(int var, String value) {
|
||||||
KnownValue known = knownValues.get(value);
|
KnownValue known = knownValues.get(value);
|
||||||
if (known != null && domTree.dominates(known.location, currentBlockIndex)) {
|
if (known != null && domTree.dominates(known.location, currentBlockIndex)) {
|
||||||
|
@ -166,16 +183,19 @@ public class CommonSubexpressionElimination implements MethodOptimization {
|
||||||
int b = map[insn.getSecondOperand().getIndex()];
|
int b = map[insn.getSecondOperand().getIndex()];
|
||||||
insn.setFirstOperand(program.variableAt(a));
|
insn.setFirstOperand(program.variableAt(a));
|
||||||
insn.setSecondOperand(program.variableAt(b));
|
insn.setSecondOperand(program.variableAt(b));
|
||||||
|
boolean commutative = false;
|
||||||
String value;
|
String value;
|
||||||
switch (insn.getOperation()) {
|
switch (insn.getOperation()) {
|
||||||
case ADD:
|
case ADD:
|
||||||
value = "+";
|
value = "+";
|
||||||
|
commutative = true;
|
||||||
break;
|
break;
|
||||||
case SUBTRACT:
|
case SUBTRACT:
|
||||||
value = "-";
|
value = "-";
|
||||||
break;
|
break;
|
||||||
case MULTIPLY:
|
case MULTIPLY:
|
||||||
value = "*";
|
value = "*";
|
||||||
|
commutative = true;
|
||||||
break;
|
break;
|
||||||
case DIVIDE:
|
case DIVIDE:
|
||||||
value = "/";
|
value = "/";
|
||||||
|
@ -188,12 +208,15 @@ public class CommonSubexpressionElimination implements MethodOptimization {
|
||||||
break;
|
break;
|
||||||
case AND:
|
case AND:
|
||||||
value = "&";
|
value = "&";
|
||||||
|
commutative = true;
|
||||||
break;
|
break;
|
||||||
case OR:
|
case OR:
|
||||||
value = "|";
|
value = "|";
|
||||||
|
commutative = true;
|
||||||
break;
|
break;
|
||||||
case XOR:
|
case XOR:
|
||||||
value = "^";
|
value = "^";
|
||||||
|
commutative = true;
|
||||||
break;
|
break;
|
||||||
case SHIFT_LEFT:
|
case SHIFT_LEFT:
|
||||||
value = "<<";
|
value = "<<";
|
||||||
|
@ -207,8 +230,10 @@ public class CommonSubexpressionElimination implements MethodOptimization {
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
value = "@" + a + value + "@" + b;
|
bind(insn.getReceiver().getIndex(), "@" + a + value + "@" + b);
|
||||||
bind(insn.getReceiver().getIndex(), value);
|
if (commutative) {
|
||||||
|
bind(insn.getReceiver().getIndex(), "@" + b + value + "@" + a);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
Loading…
Reference in New Issue
Block a user