All Downloads are FREE. Search and download functionalities are using the official Maven repository.

soot.jimple.toolkits.base.Zonation Maven / Gradle / Ivy

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 int zoneCount;
  private Map unitToZone;

  public Zonation(StmtBody body) {
    Chain units = body.getUnits();
    Map> unitToTrapBoundaries = new HashMap>();

    // Build trap boundaries
    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();
      Zone currentZone;

      zoneCount = 0;
      unitToZone = new HashMap(units.size() * 2 + 1, 0.7f);

      // Initialize first empty 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(new Integer(zoneCount).toString());

              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!");
    }

    return z;
  }

  public int getZoneCount() {
    return zoneCount;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy