Skip to content

Commit

Permalink
lazy getExceptionDests result
Browse files Browse the repository at this point in the history
  • Loading branch information
ste-lam committed Jul 31, 2015
1 parent 8fdbd29 commit fe313b0
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 53 deletions.
96 changes: 55 additions & 41 deletions src/soot/toolkits/graph/ExceptionalBlockGraph.java
Expand Up @@ -26,10 +26,17 @@

package soot.toolkits.graph;

import java.util.*;

import soot.*;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import soot.Body;
import soot.Trap;
import soot.Unit;
import soot.toolkits.exceptions.ThrowAnalysis;
import soot.toolkits.exceptions.ThrowableSet;

Expand Down Expand Up @@ -114,7 +121,8 @@ public ExceptionalBlockGraph(ExceptionalUnitGraph unitGraph)
* @return {@inheritDoc}
*/

protected Map<Unit,Block> buildBlocks(Set<Unit> leaders, UnitGraph uncastUnitGraph) {
@Override
protected Map<Unit,Block> buildBlocks(Set<Unit> leaders, UnitGraph uncastUnitGraph) {
ExceptionalUnitGraph unitGraph = (ExceptionalUnitGraph) uncastUnitGraph;
Map<Unit,Block> unitToBlock = super.buildBlocks(leaders, unitGraph);

Expand All @@ -133,9 +141,7 @@ protected Map<Unit,Block> buildBlocks(Set<Unit> leaders, UnitGraph uncastUnitGra
blockToExceptionalPreds = new HashMap<Block, List<Block>>(initialMapSize);
blockToExceptionalSuccs = new HashMap<Block, List<Block>>(initialMapSize);

for (Iterator<Block> blockIt = mBlocks.iterator(); blockIt.hasNext(); ) {
Block block = blockIt.next();

for (Block block : mBlocks) {
Unit blockHead = block.getHead();
List<Unit> exceptionalPredUnits = unitGraph.getExceptionalPredsOf(blockHead);
if (exceptionalPredUnits.size() != 0) {
Expand Down Expand Up @@ -194,8 +200,7 @@ protected Map<Unit,Block> buildBlocks(Set<Unit> leaders, UnitGraph uncastUnitGra
*/
private <K,V> List<V> mappedValues(List<K> keys, Map<K,V> keyToValue) {
List<V> result = new ArrayList<V>(keys.size());
for (Iterator<K> it = keys.iterator(); it.hasNext(); ) {
K key = it.next();
for (K key : keys) {
V value = keyToValue.get(key);
if (value == null) {
throw new IllegalStateException("No value corresponding to key: " + key.toString());
Expand All @@ -208,8 +213,7 @@ private <K,V> List<V> mappedValues(List<K> keys, Map<K,V> keyToValue) {
private Map<Block, Collection<ExceptionDest>> buildExceptionDests(ExceptionalUnitGraph unitGraph,
Map<Unit,Block> unitToBlock) {
Map<Block, Collection<ExceptionDest>> result = new HashMap<Block, Collection<ExceptionDest>>(mBlocks.size() * 2 + 1, 0.7f);
for (Iterator<Block> blockIt = mBlocks.iterator(); blockIt.hasNext(); ) {
Block block = blockIt.next();
for (Block block : mBlocks) {
result.put(block, collectDests(block, unitGraph, unitToBlock));
}
return result;
Expand Down Expand Up @@ -243,15 +247,13 @@ private Collection<ExceptionDest> collectDests(Block block, ExceptionalUnitGraph
Map<Trap, ThrowableSet> trapToThrowables = null; // Don't allocate unless we need it.
int caughtCount = 0;

for (Iterator<Unit> unitIt = block.iterator(); unitIt.hasNext(); ) {
Unit unit = (Unit) unitIt.next();
for (Unit unit2 : block) {
Unit unit = unit2;
Collection<ExceptionalUnitGraph.ExceptionDest> unitDests = unitGraph.getExceptionDests(unit);
if (unitDests.size() != 1 && unit != blockHead && unit != blockTail) {
throw new IllegalStateException("Multiple ExceptionDests associated with a unit which does not begin or end its block.");
}
for (Iterator<ExceptionalUnitGraph.ExceptionDest> destIt = unitDests.iterator(); destIt.hasNext(); ) {
ExceptionalUnitGraph.ExceptionDest unitDest
= destIt.next();
for (soot.toolkits.graph.ExceptionalUnitGraph.ExceptionDest unitDest : unitDests) {
if (unitDest.getTrap() == null) {
try {
escapingThrowables = escapingThrowables.add(unitDest.getThrowables());
Expand Down Expand Up @@ -309,7 +311,7 @@ private Collection<ExceptionDest> collectDests(Block block, ExceptionalUnitGraph
if (trapToThrowables != null) {
for (Map.Entry<Trap,ThrowableSet> entry : trapToThrowables.entrySet()) {
Trap trap = entry.getKey();
Block trapBlock = (Block) unitToBlock.get(trap.getHandlerUnit());
Block trapBlock = unitToBlock.get(trap.getHandlerUnit());
if (trapBlock == null) {
throw new IllegalStateException("catching unit is not recorded as a block leader.");
}
Expand All @@ -322,29 +324,32 @@ private Collection<ExceptionDest> collectDests(Block block, ExceptionalUnitGraph
}


public List<Block> getUnexceptionalPredsOf(Block b) {
@Override
public List<Block> getUnexceptionalPredsOf(Block b) {
if ((blockToUnexceptionalPreds == null)
|| (! blockToUnexceptionalPreds.containsKey(b))) {
Block block = (Block) b;
Block block = b;
return block.getPreds();
} else {
return blockToUnexceptionalPreds.get(b);
}
}


public List<Block> getUnexceptionalSuccsOf(Block b) {
@Override
public List<Block> getUnexceptionalSuccsOf(Block b) {
if ((blockToUnexceptionalSuccs == null)
|| (! blockToUnexceptionalSuccs.containsKey(b))) {
Block block = (Block) b;
Block block = b;
return block.getSuccs();
} else {
return blockToUnexceptionalSuccs.get(b);
}
}


public List<Block> getExceptionalPredsOf(Block b) {
@Override
public List<Block> getExceptionalPredsOf(Block b) {
if (blockToExceptionalPreds == null ||
(!blockToExceptionalPreds.containsKey(b))) {
return Collections.emptyList();
Expand All @@ -354,7 +359,8 @@ public List<Block> getExceptionalPredsOf(Block b) {
}


public List<Block> getExceptionalSuccsOf(Block b) {
@Override
public List<Block> getExceptionalSuccsOf(Block b) {
if (blockToExceptionalSuccs == null ||
(!blockToExceptionalSuccs.containsKey(b))) {
return Collections.emptyList();
Expand All @@ -364,22 +370,27 @@ public List<Block> getExceptionalSuccsOf(Block b) {
}


public Collection<ExceptionDest> getExceptionDests(Block b) {
if (blockToExceptionDests == null) {
Block block = (Block) b;
Collection<ExceptionDest> result = new ArrayList<ExceptionDest>(1);
ThrowableSet throwables = ThrowableSet.Manager.v().EMPTY;
for (Iterator<Unit> unitIt = block.iterator(); unitIt.hasNext(); ) {
Unit unit = unitIt.next();
throwables = throwables.add(throwAnalysis.mightThrow(unit));
}
result.add(new ExceptionalBlockGraph.ExceptionDest(null, throwables,
null));
return result;
} else {
return blockToExceptionDests.get(b);
@Override
public Collection<ExceptionDest> getExceptionDests(final Block b) {
if (blockToExceptionDests == null) {
ExceptionDest e = new ExceptionDest(null, null, null) {
private ThrowableSet throwables;

@Override
public ThrowableSet getThrowables() {
if (null == throwables) {
throwables = ThrowableSet.Manager.v().EMPTY;
for (Unit unit : b) {
throwables = throwables.add(throwAnalysis.mightThrow(unit));
}
}
return throwables;
}
};
return Collections.singletonList(e);
}
return blockToExceptionDests.get(b);
}
}


public static class ExceptionDest implements ExceptionalGraph.ExceptionDest<Block> {
Expand All @@ -393,21 +404,25 @@ protected ExceptionDest(Trap trap, ThrowableSet throwables, Block handler) {
this.handler = handler;
}

@Override
public Trap getTrap() {
return trap;
}

@Override
public ThrowableSet getThrowables() {
return throwables;
}

@Override
public Block getHandlerNode() {
return handler;
}

@Override
public String toString() {
StringBuffer buf = new StringBuffer();
buf.append(throwables.toString());
buf.append(getThrowables());
buf.append(" -> ");
if (trap == null) {
buf.append("(escapes)");
Expand All @@ -421,4 +436,3 @@ public String toString() {
}
}


45 changes: 33 additions & 12 deletions src/soot/toolkits/graph/ExceptionalUnitGraph.java
Expand Up @@ -574,6 +574,7 @@ class CFGEdge {
this.tail = tail;
}

@Override
public boolean equals(Object rhs) {
if (rhs == this) {
return true;
Expand All @@ -585,6 +586,7 @@ public boolean equals(Object rhs) {
return ((this.head == rhsEdge.head) && (this.tail == rhsEdge.tail));
}

@Override
public int hashCode() {
// Following Joshua Bloch's recipe in "Effective Java", Item 8:
int result = 17;
Expand Down Expand Up @@ -724,6 +726,7 @@ private boolean mightThrowToIntraproceduralCatcher(Unit u) {
* escape the method.
* </p>
*/
@Override
protected void buildHeadsAndTails() throws IllegalStateException {
throw new IllegalStateException(
"ExceptionalUnitGraph uses buildHeadsAndTails(List) instead of buildHeadsAndTails()");
Expand Down Expand Up @@ -792,13 +795,22 @@ private void buildHeadsAndTails(Set<Unit> additionalHeads) {
* traps, if any, which catch the exceptions which may be thrown by
* <code>u</code>.
*/
public Collection<ExceptionDest> getExceptionDests(Unit u) {
@Override
public Collection<ExceptionDest> getExceptionDests(final Unit u) {
Collection<ExceptionDest> result = unitToExceptionDests.get(u);
if (result != null)
return result;

ThrowableSet ts = throwAnalysis.mightThrow(u);
return Collections.singleton(new ExceptionDest(null, ts));
if (result == null) {
ExceptionDest e = new ExceptionDest(null, null) {
private ThrowableSet throwables;
@Override
public ThrowableSet getThrowables() {
if (null == throwables)
throwables = throwAnalysis.mightThrow(u);
return throwables;
}
};
return Collections.singletonList(e);
}
return result;
}

public static class ExceptionDest implements
Expand All @@ -811,14 +823,17 @@ protected ExceptionDest(Trap trap, ThrowableSet throwables) {
this.throwables = throwables;
}

@Override
public Trap getTrap() {
return trap;
}

@Override
public ThrowableSet getThrowables() {
return throwables;
}

@Override
public Unit getHandlerNode() {
if (trap == null) {
return null;
Expand All @@ -827,9 +842,10 @@ public Unit getHandlerNode() {
}
}

@Override
public String toString() {
StringBuffer buf = new StringBuffer();
buf.append(throwables.toString());
buf.append(getThrowables());
buf.append(" -> ");
if (trap == null) {
buf.append("(escapes)");
Expand All @@ -840,33 +856,37 @@ public String toString() {
}
}

@Override
public List<Unit> getUnexceptionalPredsOf(Unit u) {
if (!unitToUnexceptionalPreds.containsKey(u))
throw new RuntimeException("Invalid unit " + u);

return (List<Unit>) unitToUnexceptionalPreds.get(u);
return unitToUnexceptionalPreds.get(u);
}

@Override
public List<Unit> getUnexceptionalSuccsOf(Unit u) {
if (!unitToUnexceptionalSuccs.containsKey(u))
throw new RuntimeException("Invalid unit " + u);

return (List<Unit>) unitToUnexceptionalSuccs.get(u);
return unitToUnexceptionalSuccs.get(u);
}

@Override
public List<Unit> getExceptionalPredsOf(Unit u) {
if (!unitToExceptionalPreds.containsKey(u)) {
return Collections.emptyList();
} else {
return (List<Unit>) unitToExceptionalPreds.get(u);
return unitToExceptionalPreds.get(u);
}
}

@Override
public List<Unit> getExceptionalSuccsOf(Unit u) {
if (!unitToExceptionalSuccs.containsKey(u)) {
return Collections.emptyList();
} else {
return (List<Unit>) unitToExceptionalSuccs.get(u);
return unitToExceptionalSuccs.get(u);
}
}

Expand Down Expand Up @@ -895,6 +915,7 @@ ThrowAnalysis getThrowAnalysis() {
return throwAnalysis;
}

@Override
public String toString() {
StringBuffer buf = new StringBuffer();
for (Unit u : unitChain) {
Expand All @@ -915,4 +936,4 @@ public String toString() {

return buf.toString();
}
}
}

0 comments on commit fe313b0

Please sign in to comment.