mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
Prevent PhiUpdater from placing e-phis with source variable equal to receiver
This commit is contained in:
parent
10bb4ef3da
commit
ad39024795
|
@ -152,14 +152,10 @@ class LoopInversionImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
private LoopWithExits getLoopWithExits(Map<Loop, LoopWithExits> cache, Loop loop) {
|
private LoopWithExits getLoopWithExits(Map<Loop, LoopWithExits> cache, Loop loop) {
|
||||||
LoopWithExits result = cache.get(loop);
|
return cache.computeIfAbsent(loop, k ->
|
||||||
if (result == null) {
|
new LoopWithExits(loop.getHead(), loop.getParent() != null
|
||||||
result = new LoopWithExits(loop.getHead(), loop.getParent() != null
|
? getLoopWithExits(cache, loop.getParent())
|
||||||
? getLoopWithExits(cache, loop.getParent())
|
: null));
|
||||||
: null);
|
|
||||||
cache.put(loop, result);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sortLoops(LoopWithExits loop, Set<LoopWithExits> visited, List<LoopWithExits> target) {
|
private void sortLoops(LoopWithExits loop, Set<LoopWithExits> visited, List<LoopWithExits> target) {
|
||||||
|
@ -179,7 +175,6 @@ class LoopInversionImpl {
|
||||||
final IntSet nodesAndCopies = new IntOpenHashSet();
|
final IntSet nodesAndCopies = new IntOpenHashSet();
|
||||||
final IntSet exits = new IntOpenHashSet();
|
final IntSet exits = new IntOpenHashSet();
|
||||||
int bodyStart;
|
int bodyStart;
|
||||||
int copyStart;
|
|
||||||
int headCopy;
|
int headCopy;
|
||||||
final IntIntMap copiedNodes = new IntIntOpenHashMap();
|
final IntIntMap copiedNodes = new IntIntOpenHashMap();
|
||||||
boolean shouldSkip;
|
boolean shouldSkip;
|
||||||
|
@ -352,7 +347,7 @@ class LoopInversionImpl {
|
||||||
TryCatchJoint jointCopy = new TryCatchJoint();
|
TryCatchJoint jointCopy = new TryCatchJoint();
|
||||||
jointCopy.setReceiver(joint.getReceiver());
|
jointCopy.setReceiver(joint.getReceiver());
|
||||||
jointCopy.getSourceVariables().addAll(joint.getSourceVariables());
|
jointCopy.getSourceVariables().addAll(joint.getSourceVariables());
|
||||||
tryCatchCopy.getJoints().add(joint);
|
tryCatchCopy.getJoints().add(jointCopy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -244,7 +244,7 @@ public class PhiUpdater {
|
||||||
TryCatchBlock tryCatch = currentBlock.getTryCatchBlocks().get(i);
|
TryCatchBlock tryCatch = currentBlock.getTryCatchBlocks().get(i);
|
||||||
catchSuccessors.add(tryCatch.getHandler().getIndex());
|
catchSuccessors.add(tryCatch.getHandler().getIndex());
|
||||||
for (TryCatchJoint joint : synthesizedJoints.get(index).get(i)) {
|
for (TryCatchJoint joint : synthesizedJoints.get(index).get(i)) {
|
||||||
joint.setReceiver(define(joint.getReceiver()));
|
joint.setReceiver(defineForExceptionPhi(joint.getReceiver()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
variableMap = regularVariableMap;
|
variableMap = regularVariableMap;
|
||||||
|
@ -308,36 +308,55 @@ public class PhiUpdater {
|
||||||
while (head > 0) {
|
while (head > 0) {
|
||||||
BasicBlock block = worklist[--head];
|
BasicBlock block = worklist[--head];
|
||||||
int[] frontiers = domFrontiers[block.getIndex()];
|
int[] frontiers = domFrontiers[block.getIndex()];
|
||||||
if (frontiers == null) {
|
|
||||||
continue;
|
if (frontiers != null) {
|
||||||
|
for (int frontier : frontiers) {
|
||||||
|
BasicBlock frontierBlock = program.basicBlockAt(frontier);
|
||||||
|
if (frontierBlock.getExceptionVariable() == var) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean exists = frontierBlock.getPhis().stream()
|
||||||
|
.flatMap(phi -> phi.getIncomings().stream())
|
||||||
|
.anyMatch(incoming -> incoming.getSource() == block && incoming.getValue() == var);
|
||||||
|
if (exists) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Phi phi = phiMap[frontier][var.getIndex()];
|
||||||
|
if (phi == null) {
|
||||||
|
phi = new Phi();
|
||||||
|
phi.setReceiver(var);
|
||||||
|
phiIndexMap[frontier][synthesizedPhis.get(frontier).size()] = var.getIndex();
|
||||||
|
synthesizedPhis.get(frontier).add(phi);
|
||||||
|
phiMap[frontier][var.getIndex()] = phi;
|
||||||
|
worklist[head++] = frontierBlock;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int frontier : frontiers) {
|
List<TryCatchBlock> tryCatchBlocks = block.getTryCatchBlocks();
|
||||||
BasicBlock frontierBlock = program.basicBlockAt(frontier);
|
for (int i = 0; i < tryCatchBlocks.size(); i++) {
|
||||||
if (frontierBlock.getExceptionVariable() == var) {
|
TryCatchBlock tryCatch = tryCatchBlocks.get(i);
|
||||||
continue;
|
TryCatchJoint joint = jointMap.computeIfAbsent(tryCatch, k -> new HashMap<>()).get(var);
|
||||||
}
|
if (joint == null) {
|
||||||
|
joint = new TryCatchJoint();
|
||||||
boolean exists = frontierBlock.getPhis().stream()
|
joint.setReceiver(var);
|
||||||
.flatMap(phi -> phi.getIncomings().stream())
|
synthesizedJoints.get(block.getIndex()).get(i).add(joint);
|
||||||
.anyMatch(incoming -> incoming.getSource() == block && incoming.getValue() == var);
|
jointMap.get(tryCatch).put(var, joint);
|
||||||
if (exists) {
|
worklist[head++] = tryCatch.getHandler();
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Phi phi = phiMap[frontier][var.getIndex()];
|
|
||||||
if (phi == null) {
|
|
||||||
phi = new Phi();
|
|
||||||
phi.setReceiver(var);
|
|
||||||
phiIndexMap[frontier][synthesizedPhis.get(frontier).size()] = var.getIndex();
|
|
||||||
synthesizedPhis.get(frontier).add(phi);
|
|
||||||
phiMap[frontier][var.getIndex()] = phi;
|
|
||||||
worklist[head++] = frontierBlock;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Variable defineForExceptionPhi(Variable var) {
|
||||||
|
Variable original = var;
|
||||||
|
var = introduce(var);
|
||||||
|
mapVariable(original.getIndex(), var);
|
||||||
|
return var;
|
||||||
|
}
|
||||||
|
|
||||||
private Variable define(Variable var) {
|
private Variable define(Variable var) {
|
||||||
Variable old = variableMap[var.getIndex()];
|
Variable old = variableMap[var.getIndex()];
|
||||||
Variable original = var;
|
Variable original = var;
|
||||||
|
@ -354,15 +373,13 @@ public class PhiUpdater {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<Variable, TryCatchJoint> joints = jointMap.computeIfAbsent(tryCatch, k -> new HashMap<>());
|
Map<Variable, TryCatchJoint> joints = jointMap.get(tryCatch);
|
||||||
|
if (joints == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
TryCatchJoint joint = joints.get(original);
|
TryCatchJoint joint = joints.get(original);
|
||||||
if (joint == null) {
|
if (joint == null) {
|
||||||
joint = new TryCatchJoint();
|
|
||||||
joint.setReceiver(original);
|
|
||||||
joints.put(original, joint);
|
|
||||||
synthesizedJoints.get(currentBlock.getIndex()).get(i).add(joint);
|
|
||||||
}
|
|
||||||
if (joint.getReceiver() == var) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,8 @@ package org.teavm.vm;
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
import org.teavm.jso.JSBody;
|
||||||
|
import org.teavm.junit.SkipJVM;
|
||||||
import org.teavm.junit.TeaVMTestRunner;
|
import org.teavm.junit.TeaVMTestRunner;
|
||||||
|
|
||||||
@RunWith(TeaVMTestRunner.class)
|
@RunWith(TeaVMTestRunner.class)
|
||||||
|
@ -132,6 +134,27 @@ public class VMTest {
|
||||||
assertEquals("ok", AsyncClinitClass.state);
|
assertEquals("ok", AsyncClinitClass.state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@SkipJVM
|
||||||
|
public void loopAndExceptionPhi() {
|
||||||
|
int[] a = createArray();
|
||||||
|
int s = 0;
|
||||||
|
for (int i = 0; i < 10; ++i) {
|
||||||
|
int x = 0;
|
||||||
|
try {
|
||||||
|
x += 2;
|
||||||
|
x += 3;
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
fail("Unexpected exception caught: " + x);
|
||||||
|
}
|
||||||
|
s += a[0] + a[1];
|
||||||
|
}
|
||||||
|
assertEquals(30, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
@JSBody(params = {}, script = "return [1, 2]")
|
||||||
|
private static native int[] createArray();
|
||||||
|
|
||||||
static int initCount = 0;
|
static int initCount = 0;
|
||||||
|
|
||||||
private static class AsyncClinitClass {
|
private static class AsyncClinitClass {
|
||||||
|
|
|
@ -15,7 +15,9 @@
|
||||||
<root url="jar://$MODULE_DIR$/lib/teavm-all.jar!/" />
|
<root url="jar://$MODULE_DIR$/lib/teavm-all.jar!/" />
|
||||||
</CLASSES>
|
</CLASSES>
|
||||||
<JAVADOC />
|
<JAVADOC />
|
||||||
<SOURCES />
|
<SOURCES>
|
||||||
|
<root url="file://$MODULE_DIR$/../../core/src/main/java" />
|
||||||
|
</SOURCES>
|
||||||
</library>
|
</library>
|
||||||
</orderEntry>
|
</orderEntry>
|
||||||
</component>
|
</component>
|
||||||
|
|
|
@ -228,11 +228,19 @@ public class TeaVMTestRunner extends Runner implements Filterable {
|
||||||
});
|
});
|
||||||
|
|
||||||
for (TeaVMTestConfiguration configuration : configurations) {
|
for (TeaVMTestConfiguration configuration : configurations) {
|
||||||
TestRun run = compileByTeaVM(child, notifier, expectedExceptions, configuration, onSuccess.get(0));
|
try {
|
||||||
if (run != null) {
|
TestRun run = compileByTeaVM(child, notifier, expectedExceptions, configuration, onSuccess.get(0));
|
||||||
runs.add(run);
|
if (run != null) {
|
||||||
} else {
|
runs.add(run);
|
||||||
|
} else {
|
||||||
|
notifier.fireTestFinished(description);
|
||||||
|
latch.countDown();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch (Throwable e) {
|
||||||
|
notifier.fireTestFailure(new Failure(description, e));
|
||||||
notifier.fireTestFinished(description);
|
notifier.fireTestFinished(description);
|
||||||
|
latch.countDown();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user