Merge branch 'fix-performance-regression'

This commit is contained in:
Alexey Andreev 2015-05-01 11:03:29 +03:00
commit fee4fbc24e
2 changed files with 49 additions and 55 deletions

View File

@ -156,6 +156,6 @@ class BreakEliminator implements StatementVisitor {
} }
private boolean escapes(List<Statement> statements) { private boolean escapes(List<Statement> statements) {
return new EscapingStatementFinder().check(statements); return new EscapingStatementFinder(usageCounter).check(statements);
} }
} }

View File

@ -15,9 +15,7 @@
*/ */
package org.teavm.javascript; package org.teavm.javascript;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set;
import org.teavm.javascript.ast.*; import org.teavm.javascript.ast.*;
/** /**
@ -25,39 +23,48 @@ import org.teavm.javascript.ast.*;
* @author Alexey Andreev * @author Alexey Andreev
*/ */
class EscapingStatementFinder implements StatementVisitor { class EscapingStatementFinder implements StatementVisitor {
AllBlocksCountVisitor blockCountVisitor;
public boolean escaping; public boolean escaping;
private boolean last = true;
private Set<IdentifiedStatement> outerStatements = new HashSet<>(); public EscapingStatementFinder(AllBlocksCountVisitor blockCountVisitor) {
private Set<IdentifiedStatement> breakTargets = new HashSet<>(); this.blockCountVisitor = blockCountVisitor;
private IdentifiedStatement currentBlock; }
private boolean isEmpty(Statement statement) {
if (!(statement instanceof SequentialStatement)) {
return false;
}
SequentialStatement seq = (SequentialStatement)statement;
for (int i = seq.getSequence().size() - 1; i >= 0; --i) {
if (!isEmpty(seq.getSequence().get(i))) {
return false;
}
}
return true;
}
public boolean check(List<Statement> statements) { public boolean check(List<Statement> statements) {
if (escaping) { if (escaping) {
return true; return true;
} }
if (statements.isEmpty()) { if (statements.isEmpty()) {
escaping = last; escaping = true;
return true; return true;
} }
boolean oldLast = last; for (int i = statements.size() - 1; i >= 0; --i) {
for (int i = 0; i < statements.size(); ++i) { Statement stmt = statements.get(i);
last = false; if (!isEmpty(stmt)) {
statements.get(i).acceptVisitor(this); stmt.acceptVisitor(this);
if (escaping) { return escaping;
break;
} }
} }
last = oldLast; escaping = true;
if (!escaping) { return true;
statements.get(statements.size() - 1).acceptVisitor(this);
}
last = oldLast;
return escaping;
} }
@Override @Override
public void visit(AssignmentStatement statement) { public void visit(AssignmentStatement statement) {
escaping |= last; escaping |= true;
} }
@Override @Override
@ -74,56 +81,42 @@ class EscapingStatementFinder implements StatementVisitor {
@Override @Override
public void visit(SwitchStatement statement) { public void visit(SwitchStatement statement) {
IdentifiedStatement oldCurrentBlock = currentBlock; if (blockCountVisitor.getCount(statement) > 0) {
currentBlock = statement; escaping = true;
outerStatements.add(statement); return;
}
for (SwitchClause clause : statement.getClauses()) { for (SwitchClause clause : statement.getClauses()) {
if (check(clause.getBody())) { if (check(clause.getBody())) {
break; break;
} }
} }
check(statement.getDefaultClause()); if (!escaping) {
outerStatements.remove(statement); check(statement.getDefaultClause());
currentBlock = oldCurrentBlock;
if (breakTargets.contains(statement)) {
escaping |= last;
} }
} }
@Override @Override
public void visit(WhileStatement statement) { public void visit(WhileStatement statement) {
IdentifiedStatement oldCurrentBlock = currentBlock; if (blockCountVisitor.getCount(statement) > 0) {
currentBlock = statement; escaping = true;
outerStatements.add(statement); return;
if (!check(statement.getBody()) && statement.getCondition() != null) {
escaping |= last;
} }
outerStatements.remove(statement); if (statement.getCondition() != null && check(statement.getBody())) {
currentBlock = oldCurrentBlock; escaping = true;
if (breakTargets.contains(statement)) {
escaping |= last;
} }
} }
@Override @Override
public void visit(BlockStatement statement) { public void visit(BlockStatement statement) {
IdentifiedStatement oldCurrentBlock = currentBlock; if (blockCountVisitor.getCount(statement) > 0) {
currentBlock = statement; escaping = true;
outerStatements.add(statement); return;
check(statement.getBody());
outerStatements.remove(statement);
currentBlock = oldCurrentBlock;
if (breakTargets.contains(statement)) {
escaping |= last;
} }
check(statement.getBody());
} }
@Override @Override
public void visit(BreakStatement statement) { public void visit(BreakStatement statement) {
IdentifiedStatement target = statement.getTarget() != null ? statement.getTarget() : currentBlock;
if (target != null) {
breakTargets.add(target);
}
} }
@Override @Override
@ -140,13 +133,14 @@ class EscapingStatementFinder implements StatementVisitor {
@Override @Override
public void visit(InitClassStatement statement) { public void visit(InitClassStatement statement) {
escaping |= last; escaping = true;
} }
@Override @Override
public void visit(TryCatchStatement statement) { public void visit(TryCatchStatement statement) {
check(statement.getProtectedBody()); if (!check(statement.getProtectedBody())) {
check(statement.getHandler()); check(statement.getHandler());
}
} }
@Override @Override
@ -155,11 +149,11 @@ class EscapingStatementFinder implements StatementVisitor {
@Override @Override
public void visit(MonitorEnterStatement statement) { public void visit(MonitorEnterStatement statement) {
escaping |= last; escaping = true;
} }
@Override @Override
public void visit(MonitorExitStatement statement) { public void visit(MonitorExitStatement statement) {
escaping |= last; escaping = true;
} }
} }