soot.jimple.toolkits.base.Zonation Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of soot Show documentation
Show all versions of soot Show documentation
A Java Optimization Framework
package soot.jimple.toolkits.base;
/*-
* #%L
* Soot - a J*va Optimization Framework
* %%
* Copyright (C) 1997 - 1999 Raja Vallee-Rai
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 2.1 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* .
* #L%
*/
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import soot.Trap;
import soot.Unit;
import soot.jimple.StmtBody;
import soot.util.Chain;
public class Zonation {
private final Map unitToZone;
private int zoneCount;
public Zonation(StmtBody body) {
final Chain units = body.getUnits();
this.zoneCount = 0;
this.unitToZone = new HashMap(units.size() * 2 + 1, 0.7f);
// Build trap boundaries
Map> unitToTrapBoundaries = new HashMap>();
for (Trap t : body.getTraps()) {
addTrapBoundary(t.getBeginUnit(), t, unitToTrapBoundaries);
addTrapBoundary(t.getEndUnit(), t, unitToTrapBoundaries);
}
// Traverse units, assigning each to a zone
Map, Zone> trapListToZone = new HashMap, Zone>(10, 0.7f);
List currentTraps = new ArrayList();
// Initialize first empty zone
Zone currentZone = new Zone("0");
trapListToZone.put(new ArrayList(), currentZone);
for (Unit u : units) {
// Process trap boundaries
{
List trapBoundaries = unitToTrapBoundaries.get(u);
if (trapBoundaries != null && !trapBoundaries.isEmpty()) {
for (Trap trap : trapBoundaries) {
if (currentTraps.contains(trap)) {
currentTraps.remove(trap);
} else {
currentTraps.add(trap);
}
}
if (trapListToZone.containsKey(currentTraps)) {
currentZone = trapListToZone.get(currentTraps);
} else {
// Create a new zone
zoneCount++;
currentZone = new Zone(Integer.toString(zoneCount));
trapListToZone.put(currentTraps, currentZone);
}
}
}
unitToZone.put(u, currentZone);
}
}
private void addTrapBoundary(Unit unit, Trap t, Map> unitToTrapBoundaries) {
List boundary = unitToTrapBoundaries.get(unit);
if (boundary == null) {
boundary = new ArrayList();
unitToTrapBoundaries.put(unit, boundary);
}
boundary.add(t);
}
public Zone getZoneOf(Unit u) {
Zone z = unitToZone.get(u);
if (z == null) {
throw new RuntimeException("null zone!");
} else {
return z;
}
}
public int getZoneCount() {
return zoneCount;
}
}