/* Soot - a J*va Optimization Framework
* Copyright (C) 1999 Patrice Pominville, Raja Vallee-Rais
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
*/
package soot.jimple.toolkits.thread.mhp;
import soot.*;
import soot.jimple.*;
import soot.jimple.toolkits.thread.mhp.stmt.JPegStmt;
import soot.jimple.toolkits.thread.mhp.stmt.StartStmt;
import soot.toolkits.scalar.*;
import soot.jimple.spark.pag.*;
import soot.toolkits.graph.*;
import soot.jimple.toolkits.callgraph.*;
import soot.util.*;
import java.util.*;
import java.io.*;
//add for add tag
import soot.tagkit.*;
/**
* Oct. 7, 2003 modify buildPegChain() for building chain without inliner.
* June 19, 2003 add begin node to peg
* June 18, 2003 modify the iterator() to be iterator for all nodes of PEG
* and mainIterator() to be the iterator for main chain.
* June 12, 2003 add monitor Map,
* notifyAll Map,
* waitingNodes Map.
*/
// *** USE AT YOUR OWN RISK ***
// May Happen in Parallel (MHP) analysis by Lin Li.
// This code should be treated as beta-quality code.
// It was written in 2003, but not incorporated into Soot until 2006.
// As such, it may contain incorrect assumptions about the usage
// of certain Soot classes.
// Some portions of this MHP analysis have been quality-checked, and are
// now used by the Transactions toolkit.
//
// -Richard L. Halpert, 2006-11-30
// NOTE that this graph builder will only run to completion if all virtual
// method calls can be resolved to a single target method. This is a severely
// limiting caveat.
public class PegGraph implements DirectedGraph
//public class PegGraph extends SimplePegGraph
{
private List heads;
private List tails;
// private long numberOfEdge = 0;
protected HashMap<Object,List> unitToSuccs;
protected HashMap<Object,List> unitToPreds;
private HashMap unitToPegMap;
public HashMap<JPegStmt,List> startToThread;
public HashMap startToAllocNodes;
private HashMap<String, FlowSet> waitingNodes;
private Map startToBeginNodes;
private HashMap<String, Set<JPegStmt>> notifyAll;
private Set methodsNeedingInlining;
private boolean needInlining;
private Set<List> synch;
private Set<JPegStmt> specialJoin;
private Body body;
private Chain unitChain;
private Chain mainPegChain;
private FlowSet allNodes;
private Map<String, FlowSet> monitor;
private Set canNotBeCompacted;
private Set threadAllocSites;
private File logFile;
private FileWriter fileWriter;
private Set<Object> monitorObjs;
private Set<Unit> exceHandlers;
protected Map threadNo;//add for print to graph
protected Map threadNameToStart;
protected Map<AllocNode, String> allocNodeToObj;
protected Map<AllocNode, PegChain> allocNodeToThread;
protected Map<JPegStmt, Chain> joinStmtToThread;
// protected int count=0;
Set allocNodes;
List<List> inlineSites;
Map<SootMethod, String> synchObj;
Set multiRunAllocNodes;
/**
* Constructs a graph for the units found in the provided
* Body instance. Each node in the graph corresponds to
* a unit. The edges are derived from the control flow.
*
* @param Body The underlying body of main thread
* @param addExceptionEdges If true then the control flow edges associated with
* exceptions are added.
* @param Hierarchy Using class hierarchy analysis to find the run method of started thread
* @param PointsToAnalysis Using point to analysis (SPARK package) to improve the precision of results
*/
public PegGraph(CallGraph callGraph, Hierarchy hierarchy, PAG pag, Set<Object> methodsNeedingInlining, Set<AllocNode> allocNodes, List inlineSites, Map synchObj, Set<AllocNode> multiRunAllocNodes, Map allocNodeToObj, Body unitBody,
SootMethod sm,
boolean addExceptionEdges,
boolean dontAddEdgeFromStmtBeforeAreaOfProtectionToCatchBlock) {
/* public PegGraph( Body unitBody, Hierarchy hierarchy, boolean addExceptionEdges,
boolean dontAddEdgeFromStmtBeforeAreaOfProtectionToCatchBlock) {
*/
this( callGraph, hierarchy, pag, methodsNeedingInlining, allocNodes, inlineSites, synchObj, multiRunAllocNodes, allocNodeToObj, unitBody, "main", sm, addExceptionEdges,
dontAddEdgeFromStmtBeforeAreaOfProtectionToCatchBlock);
}
/**
* Constructs a graph for the units found in the provided
* Body instance. Each node in the graph corresponds to
* a unit. The edges are derived from the control flow.
*
* @param body The underlying body we want to make a
* graph for.
* @param addExceptionEdges If true then the control flow edges associated with
* exceptions are added.
* @param dontAddEdgeFromStmtBeforeAreaOfProtectionToCatchBlock This was added for Dava.
* If true, edges are not added from statement before area of
* protection to catch. If false, edges ARE added. For Dava,
* it should be true. For flow analyses, it should be false.
* @param Hierarchy Using class hierarchy analysis to find the run method of started thread
* @param PointsToAnalysis Using point to analysis (SPARK package) to improve the precision of results
*/
public PegGraph(CallGraph callGraph, Hierarchy hierarchy, PAG pag, Set methodsNeedingInlining, Set allocNodes, List<List> inlineSites, Map<SootMethod, String> synchObj, Set multiRunAllocNodes, Map<AllocNode, String> allocNodeToObj, Body unitBody,String threadName,
SootMethod sm,boolean addExceEdge,
boolean dontAddEdgeFromStmtBeforeAreaOfProtectionToCatchBlock) {
this.allocNodeToObj = allocNodeToObj;
this.multiRunAllocNodes = multiRunAllocNodes;
this.synchObj = synchObj;
this.inlineSites = inlineSites;
this.allocNodes = allocNodes;
this.methodsNeedingInlining = methodsNeedingInlining;
logFile = new File("log.txt");
try{
fileWriter = new FileWriter(logFile);
}
catch (IOException io){
System.err.println("Errors occur during create FileWriter !");
// throw io;
}
body = unitBody;
synch = new HashSet<List>();
exceHandlers = new HashSet<Unit>();
needInlining = true;
monitorObjs = new HashSet<Object>();
startToBeginNodes = new HashMap();
unitChain = body.getUnits();
int size = unitChain.size();
//initial unitToSuccs, unitToPreds, unitToPegMap, and startToThread
unitToSuccs = new HashMap(size*2+1,0.7f);
unitToPreds = new HashMap(size*2+1,0.7f);
//unitToPegMap is the map of a chain to its corresponding (cfg node --> peg node ) map.
unitToPegMap = new HashMap(size*2+1,0.7f);
startToThread = new HashMap(size*2+1,0.7f);
startToAllocNodes = new HashMap(size*2+1,0.7f);
waitingNodes = new HashMap<String, FlowSet>(size*2+1,0.7f);
joinStmtToThread = new HashMap<JPegStmt, Chain>();
threadNo = new HashMap();
threadNameToStart = new HashMap();
this.allocNodeToObj = new HashMap<AllocNode, String>(size*2+1,0.7f);
allocNodeToThread = new HashMap<AllocNode, PegChain>(size*2+1,0.7f);
notifyAll = new HashMap<String, Set<JPegStmt>>(size*2+1,0.7f);
methodsNeedingInlining = new HashSet();
allNodes = new ArraySparseSet();
canNotBeCompacted = new HashSet();
threadAllocSites = new HashSet();
specialJoin = new HashSet<JPegStmt>();
// if(Main.isVerbose)
// System.out.println(" Constructing PegGraph...");
//if(Main.isProfilingOptimization)
// Main.graphTimer.start();
//make a peg for debug
/*
mainPegChain = new HashChain();
specialTreatment1();
*/
//end make a peg
UnitGraph mainUnitGraph = new CompleteUnitGraph(body);
// mainPegChain = new HashChain();
mainPegChain = new PegChain( callGraph, hierarchy, pag, threadAllocSites, methodsNeedingInlining, allocNodes, inlineSites, synchObj, multiRunAllocNodes, allocNodeToObj, body, sm, threadName, true, this);
//testPegChain();
// System.out.println("finish building chain");
//testStartToThread();
//buildSuccessor(mainUnitGraph, mainPegChain,addExceptionEdges);
// buildSuccessorForExtendingMethod(mainPegChain);
//testSet(exceHandlers, "exceHandlers");
buildSuccessor(mainPegChain);
//System.out.println("finish building successors");
//unmodifiableSuccs(mainPegChain);
//testUnitToSucc );
buildPredecessor(mainPegChain);
//System.out.println("finish building predcessors");
//unmodifiablePreds(mainPegChain);
//testSynch();
addMonitorStmt();
addTag();
// System.out.println(this.toString());
buildHeadsAndTails();
//testIterator();
//testWaitingNodes();
// System.out.println("finish building heads and tails");
//testSet(canNotBeCompacted, "canNotBeCompacted");
// computeEdgeAndThreadNo();
// testExtendingPoints();
// testUnitToSucc();
//testPegChain();
/* if (print) {
PegToDotFile printer1 = new PegToDotFile(this, false, sm.getName());
}
*/
try{
fileWriter.flush();
fileWriter.close();
}
catch (IOException io){
System.err.println("Errors occur during close file "+logFile.getName());
// throw io;
}
//System.out.println("==threadAllocaSits==\n"+threadAllocSites.toString());
}
protected Map getStartToBeginNodes(){
return startToBeginNodes;
}
protected Map<JPegStmt, Chain> getJoinStmtToThread(){
return joinStmtToThread;
}
protected Map getUnitToPegMap(){
return unitToPegMap;
}
// This method adds the monitorenter/exit statements into whichever pegChain contains the corresponding node statement
protected void addMonitorStmt(){
//System.out.println("====entering addMonitorStmt");
if (synch.size()>0){
// System.out.println("synch: "+synch);
Iterator<List> it = synch.iterator();
while (it.hasNext()){
List list = it.next();
JPegStmt node = (JPegStmt)list.get(0);
JPegStmt enter = (JPegStmt)list.get(1);
JPegStmt exit = (JPegStmt)list.get(2);
// System.out.println("monitor node: "+node);
//System.out.println("monitor enter: "+enter);
//System.out.println("monitor exit: "+exit);
//add for test
//System.out.println("allNodes contains node: "+allNodes.contains(node));
//end add for test
{
if (!mainPegChain.contains(node)){
boolean find = false;
//System.out.println("main chain does not contain node");
Set maps = startToThread.entrySet();
//System.out.println("size of startToThread: "+startToThread.size());
for(Iterator iter=maps.iterator(); iter.hasNext();){
Map.Entry entry = (Map.Entry)iter.next();
Object startNode = entry.getKey();
Iterator runIt = ((List)entry.getValue()).iterator();
while (runIt.hasNext()){
Chain chain=(Chain)runIt.next();
// testPegChain(chain);
if (chain.contains(node)) {
find = true;
//System.out.println("---find it---");
chain.add(enter);
chain.add(exit);
break;
}
}
}
if (find == false){
System.err.println("fail to find stmt: "+node+" in chains!");
System.exit(1);
}
//this.toString();
}
else{
mainPegChain.add(enter);
mainPegChain.add(exit);
}
}
allNodes.add(enter);
allNodes.add(exit);
insertBefore(node, enter);
insertAfter(node, exit);
}
}
// add for test
/*
{
// System.out.println("===main peg chain===");
//testPegChain(mainPegChain);
//System.out.println("===end main peg chain===");
Set maps = startToThread.entrySet();
for(Iterator iter=maps.iterator(); iter.hasNext();){
Map.Entry entry = (Map.Entry)iter.next();
Object startNode = entry.getKey();
Iterator runIt = ((List)entry.getValue()).iterator();
while (runIt.hasNext()){
Chain chain=(Chain)runIt.next();
testPegChain(chain);
}
}
}
*/
// System.out.println(this.toString());
//end add for test
}
private void insertBefore(JPegStmt node, JPegStmt enter){
//build preds of before
List predOfBefore = new ArrayList();
predOfBefore.addAll(getPredsOf(node));
unitToPreds.put(enter,predOfBefore );
// System.out.println("put into unitToPreds enter: "+enter);
// System.out.println("put into unitToPreds value: "+predOfBefore);
Iterator predsIt = getPredsOf(node).iterator();
//build succs of former preds of node
while (predsIt.hasNext()){
Object pred = predsIt.next();
List succ = getSuccsOf(pred);
succ.remove(node);
succ.add(enter);
// System.out.println("in unitToPred pred: "+pred);
// System.out.println("in unitToPred value is: "+succ);
}
List succOfBefore = new ArrayList();
succOfBefore.add(node);
unitToSuccs.put(enter, succOfBefore);
// System.out.println("put into unitToSuccs enter: "+enter);
//System.out.println("put into unitToSuccs value: "+succOfBefore);
List predOfNode = new ArrayList();
predOfNode.add(enter);
unitToPreds.put(node, predOfNode);
//System.out.println("put into unitToPreds enter: "+node);
//System.out.println("put into unitToPreds value: "+predOfNode);
//buildPreds();
}
private void insertAfter(JPegStmt node, JPegStmt after){
//System.out.println("node: "+node);
//System.out.println("after: "+after);
// System.out.println("succs of node: "+getSuccsOf(node));
// this must be done first because the succs of node will be chanaged lately
List succOfAfter = new ArrayList();
succOfAfter.addAll(getSuccsOf(node));
unitToSuccs.put(after,succOfAfter );
Iterator succsIt = getSuccsOf(node).iterator();
while (succsIt.hasNext()){
Object succ = succsIt.next();
List pred = getPredsOf(succ);
pred.remove(node);
pred.add(after);
}
List succOfNode = new ArrayList();
succOfNode.add(after);
unitToSuccs.put(node, succOfNode);
List predOfAfter = new ArrayList();
predOfAfter.add(node);
unitToPreds.put(after, predOfAfter);
// buildPredecessor(Chain pegChain);
}
private void buildSuccessor(Chain pegChain)
{
// Add regular successors
{
HashMap unitToPeg =(HashMap)unitToPegMap.get(pegChain);
Iterator pegIt = pegChain.iterator();
JPegStmt currentNode, nextNode;
currentNode = pegIt.hasNext() ? (JPegStmt) pegIt.next(): null;
//June 19 add for begin node
if (currentNode != null){
//System.out.println("currentNode: "+currentNode);
//if the unit is "begin" node
nextNode = pegIt.hasNext() ? (JPegStmt) pegIt.next(): null;
if (currentNode.getName().equals("begin")){
List<JPegStmt> successors = new ArrayList<JPegStmt>();
successors.add(nextNode);
unitToSuccs.put(currentNode, successors);
currentNode = nextNode;
}
//end June 19 add for begin node
while(currentNode != null) {
// System.out.println("currentNode: "+currentNode);
/* If unitToSuccs contains currentNode, it is the point to inline methods,
* we need not compute its successors again
*/
if (unitToSuccs.containsKey(currentNode) && !currentNode.getName().equals("wait")){
currentNode = pegIt.hasNext() ? (JPegStmt) pegIt.next(): null;
continue;
}
List<JPegStmt> successors = new ArrayList<JPegStmt>();
Unit unit = currentNode.getUnit();
UnitGraph unitGraph = currentNode.getUnitGraph();
List unitSucc = unitGraph.getSuccsOf(unit);
Iterator succIt = unitSucc.iterator();
while (succIt.hasNext()){
Unit un = (Unit)succIt.next();
//Don't build the edge from "monitor exit" to exception handler
if (unit instanceof ExitMonitorStmt && exceHandlers.contains(un) ){
//System.out.println("====find it! unit: "+unit+"\n un: "+un);
continue;
}
else if ( unitToPeg.containsKey(un) ){
JPegStmt pp= (JPegStmt)(unitToPeg.get(un));
if (pp !=null && !successors.contains(pp) )
successors.add(pp);
}
}//end while
if (currentNode.getName().equals("wait")){
while ( !(currentNode.getName().equals("notified-entry"))){
currentNode = pegIt.hasNext() ? (JPegStmt) pegIt.next(): null;
}
unitToSuccs.put(currentNode, successors);
//System.out.println("put key: "+currentNode+" into unitToSucc");
}
else{
unitToSuccs.put(currentNode, successors);
}
if (currentNode.getName().equals("start")){
// System.out.println("-----build succ for start----");
if (startToThread.containsKey(currentNode)){
List runMethodChainList = startToThread.get(currentNode);
Iterator possibleMethodIt = runMethodChainList.iterator();
while (possibleMethodIt.hasNext()){
Chain subChain = (Chain)possibleMethodIt.next();
if ( subChain != null){
//System.out.println("build succ for subChain");
// buildSuccessor(subGraph, subChain, addExceptionEdges);
buildSuccessor(subChain);
}
else
System.out.println("*********subgraph is null!!!");
}
}
}
currentNode = pegIt.hasNext() ? (JPegStmt) pegIt.next(): null;
}//while
//June 19 add for begin node
}
//end June 19 add for begin node
}
}
/*
private void deleteExitToException(){
Iterator it = iterator();
while (it.hasNext()){
JPegStmt stmt = (JPegStmt)it.next();
Unit unit = stmt.getUnit();
UnitGraph unitGraph = stmt.getUnitGraph();
if (unit instanceof ExitMonitorStmt){
Iterator succIt = unitGraph.getSuccsOf(unit).iterator();
while(succIt.next
&& exceHandlers.contains(un) ){
System.out.println("====find it! unit: "+unit+"\n un: "+un);
continue;
}
}
}
*/
private void buildPredecessor(Chain pegChain){
//System.out.println("==building predcessor===");
// initialize the pred sets to empty
{
JPegStmt s=null;
Iterator unitIt = pegChain.iterator();
while(unitIt.hasNext()){
s = (JPegStmt)unitIt.next();
unitToPreds.put(s, new ArrayList());
}
}
// System.out.println("==finish init of unitToPred===");
{
Iterator unitIt = pegChain.iterator();
while(unitIt.hasNext()){
Object s = unitIt.next();
// System.out.println("s is: "+s);
// Modify preds set for each successor for this statement
if (unitToSuccs.containsKey(s)){
List succList = unitToSuccs.get(s);
Iterator succIt = succList.iterator();
// System.out.println("unitToSuccs contains "+s);
// System.out.println("succList is: "+succList);
while(succIt.hasNext()){
//Object successor = succIt.next();
JPegStmt successor = (JPegStmt)succIt.next();
// System.out.println("successor is: "+successor);
List<Object> predList = unitToPreds.get(successor);
// System.out.println("predList is: "+predList);
if (predList != null && !predList.contains(s)) {
try {
predList.add(s);
/*
Tag tag1 = (Tag)((JPegStmt)s).getTags().get(0);
System.out.println("add "+tag1+" "+s+" to predListof");
Tag tag2 = (Tag)((JPegStmt)successor).getTags().get(0);
System.out.println(tag2+" "+successor);
*/
} catch(NullPointerException e) {
System.out.println(s + "successor: " + successor);
throw e;
}
// if (((JPegStmt)successor).getName().equals("start")){
if (successor instanceof StartStmt){
List runMethodChainList = startToThread.get(successor);
if (runMethodChainList == null){
throw new RuntimeException("null runmehtodchain: \n"+successor.getUnit());
}
Iterator possibleMethodIt = runMethodChainList.iterator();
while (possibleMethodIt.hasNext()){
Chain subChain = (Chain)possibleMethodIt.next();
buildPredecessor(subChain);
}
}
}
else{
System.err.println("predlist of "+s +" is null");
// System.exit(1);
}
// unitToPreds.put(successor, predList);
}
}
else{
System.err.println("unitToSuccs does not contains key"+s);
System.exit(1);
}
}
}
}
// Make pred lists unmodifiable.
private void buildHeadsAndTails(){
List tailList = new ArrayList();
List headList = new ArrayList();
// Build the sets
{
Iterator unitIt = mainPegChain.iterator();
while(unitIt.hasNext())
{
JPegStmt s = (JPegStmt) unitIt.next();
List succs = unitToSuccs.get(s);
if(succs.size() == 0)
tailList.add(s);
if (!unitToPreds.containsKey(s)){
System.err.println("unitToPreds does not contain key: "+s);
System.exit(1);
}
List preds = unitToPreds.get(s);
if(preds.size() == 0)
headList.add(s);
// System.out.println("head is:");
}
}
tails = (List)tailList;
heads = (List)headList;
// tails = Collections.unmodifiableList(tailList);
//heads = Collections.unmodifiableList(headList);
Iterator tmpIt =heads.iterator();
while (tmpIt.hasNext()){
Object temp = tmpIt.next();
//System.out.println(temp);
}
buildPredecessor(mainPegChain);
}
public boolean addPeg(PegGraph pg,Chain chain){
if (!pg.removeBeginNode()) return false;
// System.out.println("adding one peg into another");
// System.out.println("after removeBeginNode===");
// pg.testPegChain();
//System.out.println(pg);
//put every node of peg into this
Iterator mainIt = pg.mainIterator();
while (mainIt.hasNext()){
JPegStmt s = (JPegStmt)mainIt.next();
// System.out.println("add to mainPegChain: "+s);
mainPegChain.addLast(s);
// if (chain.contains(s)){
// System.err.println("error! chain contains: "+s);
// System.exit(1);
// }
// else
// chain.addLast(s);
}
Iterator it = pg.iterator();
while (it.hasNext()){
JPegStmt s = (JPegStmt)it.next();
//System.out.println("add to allNodes: "+s);
if (allNodes.contains(s)){
System.err.println("error! allNodes contains: "+s);
System.exit(1);
}
else
allNodes.add(s);
}
// testPegChain();
// testIterator();
unitToSuccs.putAll(pg.getUnitToSuccs());
unitToPreds.putAll(pg.getUnitToPreds());
// testUnitToSucc();
//testUnitToPred();
// buildMaps(pg); // RLH
return true;
}
private boolean removeBeginNode(){
List heads = getHeads();
if (heads.size() != 1){
// System.out.println("heads: "+heads);
//System.out.println("Error: the size of heads is not equal to 1!");
return false;
// System.exit(1);
}
else{
JPegStmt head =(JPegStmt)heads.get(0);
//System.out.println("test head: "+head);
if (!head.getName().equals("begin")){
System.err.println("Error: the head is not begin node!");
System.exit(1);
}
//remove begin node from heads list
heads.remove(0);
//set the preds list of the succs of head to a new list and put succs of head into heads
Iterator succOfHeadIt = getSuccsOf(head).iterator();
while (succOfHeadIt.hasNext()){
JPegStmt succOfHead = (JPegStmt)succOfHeadIt.next();
unitToPreds.put(succOfHead, new ArrayList());
//put succs of head into heads
heads.add(succOfHead);
}
//remove begin node from inlinee Peg
if (!mainPegChain.remove(head)) {
System.err.println("fail to remove begin node in from mainPegChain!");
System.exit(1);
}
if (!allNodes.contains(head)){
System.err.println("fail to find begin node in FlowSet allNodes!");
System.exit(1);
}
else{
allNodes.remove(head);
}
//remove begin node from unitToSuccs
if (unitToSuccs.containsKey(head)){
unitToSuccs.remove(head);
}
}
return true;
}
protected void buildSuccsForInlining(JPegStmt stmt, Chain chain, PegGraph inlinee){
//System.out.println("entering buildSuccsForInlining...");
Tag tag = (Tag)stmt.getTags().get(0);
//System.out.println("stmt is: "+tag+" "+stmt);
/*connect heads of inlinee with the preds of invokeStmt and
* delete stmt from the succs list from the preds
*/
Iterator predIt = getPredsOf(stmt).iterator();
//System.out.println("preds list: "+getPredsOf(stmt));
//System.out.println("preds size: "+getPredsOf(stmt).size());
Iterator headsIt = inlinee.getHeads().iterator();
{
//System.out.println("heads: "+inlinee.getHeads());
while (predIt.hasNext()){
JPegStmt pred = (JPegStmt)predIt.next();
//System.out.println("pred: "+pred);
List succList = (List)getSuccsOf(pred);
//System.out.println("succList of pred: "+succList);
int pos = succList.indexOf(stmt);
//System.out.println("remove : "+stmt + " from succList: \n"+succList+ "\n of pred" );
//remove invokeStmt
succList.remove(pos);
while (headsIt.hasNext()){
succList.add(headsIt.next());
}
unitToSuccs.put(pred, succList);
}
{
while (headsIt.hasNext()){
Object head = headsIt.next();
List predsOfHeads = new ArrayList();
predsOfHeads.addAll(getPredsOf(head));
unitToPreds.put(head, predsOfHeads);
}
}
/*
{
predIt = getPredsOf(stmt).iterator();
while (predIt.hasNext()){
JPegStmt s = (JPegStmt)predIt.next();
if (unitToSuccs.containsKey(s)){
Iterator succIt = ((List) unitToSuccs.get(s)).iterator();
while(succIt.hasNext()){
//Object successor = succIt.next();
JPegStmt successor = (JPegStmt)succIt.next();
List predList = (List) unitToPreds.get(successor);
if (predList != null) {
try {
predList.add(s);
} catch(NullPointerException e) {
System.out.println(s + "successor: " + successor);
throw e;
}
}
}
}
}
}*/
}
/*connect tails of inlinee with the succ of invokeStmt and
* delete stmt from the
*/
Iterator tailsIt = inlinee.getTails().iterator();
{
//System.out.println("tails: "+inlinee.getTails());
while (tailsIt.hasNext()){
Iterator succIt = getSuccsOf(stmt).iterator();
JPegStmt tail = (JPegStmt)tailsIt.next();
List succList = null;
if (unitToSuccs.containsKey(tail)){
//System.out.println("error: unitToSucc containsKey: "+tail);
succList = (List)getSuccsOf(tail);
//System.out.println("succList: "+succList);
}
else{
succList = new ArrayList();
}
while (succIt.hasNext()){
JPegStmt succ = (JPegStmt)succIt.next();
succList.add(succ);
//System.out.println("succ: "+succ);
//remove stmt from the preds list of the succs of itself.
List predListOfSucc = getPredsOf(succ);
if (predListOfSucc == null){
System.err.println("Error: predListOfSucc is null!");
System.exit(1);
}
else{
if (predListOfSucc.size() != 0){
int pos = predListOfSucc.indexOf(stmt);
if (pos > 0 || pos == 0 ){
// System.out.println("remove stmt: "+stmt+" from the preds list"+predListOfSucc+" of the succ");
predListOfSucc.remove(pos);
}
// System.out.println("remove(from PRED): ");
}
}
unitToPreds.put(succ,predListOfSucc);
}
unitToSuccs.put(tail, succList);
//System.out.println("put: "+tail);
//System.out.println("succList: "+succList+ "into unitToSucc");
}
}
//add Nov 1
{
tailsIt = inlinee.getTails().iterator();
while (tailsIt.hasNext()){
JPegStmt s = (JPegStmt)tailsIt.next();
if (unitToSuccs.containsKey(s)){
Iterator succIt = unitToSuccs.get(s).iterator();
while(succIt.hasNext()){
//Object successor = succIt.next();
JPegStmt successor = (JPegStmt)succIt.next();
List<JPegStmt> predList = unitToPreds.get(successor);
if (predList != null && !predList.contains(s)) {
try {
predList.add(s);
/*
Tag tag = (Tag)successor.getTags().get(0);
System.out.println("add "+s+" to predlist of "+tag+" "+successor);
*/
} catch(NullPointerException e) {
System.out.println(s + "successor: " + successor);
throw e;
}
}
}
}
}
}
//end add Nov 1
//System.out.println("stmt: "+stmt);
//remove stmt from allNodes and mainPegChain
//System.out.println("mainPegChain contains stmt: "+mainPegChain.contains(stmt));
// testPegChain();
if (!allNodes.contains(stmt)){
System.err.println("fail to find begin node in allNodes!");
System.exit(1);
}
else{
allNodes.remove(stmt);
// System.out.println("remove from allNode: "+stmt);
}
if (!chain.contains(stmt)){
System.err.println("Error! Chain does not contains stmt (extending point)!");
System.exit(1);
}
else{
if (!chain.remove(stmt)){
System.err.println("fail to remove invoke stmt in from Chain!");
System.exit(1);
}
}
/*
if (!mainPegChain.contains(stmt)){
boolean find = false;
//System.out.println("main chain does not contain AFTER");
Set maps = startToThread.entrySet();
for(Iterator iter=maps.iterator(); iter.hasNext();){
Map.Entry entry = (Map.Entry)iter.next();
Object startNode = entry.getKey();
Iterator runIt = ((List)entry.getValue()).iterator();
while (runIt.hasNext()){
Chain chain=(Chain)runIt.next();
if (chain.contains(stmt)) {
find = true;
if (!chain.remove(stmt)){
System.err.println("fail to remove begin node in from mainPegChain!");
System.exit(1);
}
break;
}
}
if (find == false){
System.err.println("fail to find stmt: "+stmt+" in chains!");
System.exit(1);
}
}
//this.toString();
}
else{
if (!mainPegChain.remove(stmt)) {
System.err.println("fail to remove begin node in from mainPegChain!");
System.exit(1);
}
else{
// System.out.println("remove(from mainchain): "+stmt);
}
}
*/
//remove stmt from unitToSuccs and unitToPreds
if (unitToSuccs.containsKey(stmt)) {
unitToSuccs.remove(stmt);
}
if (unitToPreds.containsKey(stmt)) {
unitToPreds.remove(stmt);
}
}
protected void buildMaps(PegGraph pg){
exceHandlers.addAll(pg.getExceHandlers());
startToThread.putAll(pg.getStartToThread());
startToAllocNodes.putAll(pg.getStartToAllocNodes());
startToBeginNodes.putAll(pg.getStartToBeginNodes());
waitingNodes.putAll(pg.getWaitingNodes());
notifyAll.putAll(pg.getNotifyAll());
canNotBeCompacted.addAll(pg.getCanNotBeCompacted());
synch.addAll(pg.getSynch());
threadNameToStart.putAll(pg.getThreadNameToStart());
specialJoin.addAll(pg.getSpecialJoin());
joinStmtToThread.putAll(pg.getJoinStmtToThread());
threadAllocSites.addAll(pg.getThreadAllocSites());
allocNodeToThread.putAll(pg.getAllocNodeToThread());
}
protected void buildPreds(){
buildPredecessor(mainPegChain);
Set maps = getStartToThread().entrySet();
for(Iterator iter=maps.iterator(); iter.hasNext();){
Map.Entry entry = (Map.Entry)iter.next();
List runMethodChainList = (List)entry.getValue();
Iterator it = runMethodChainList.iterator();
while (it.hasNext()){
Chain chain=(Chain)it.next();
// System.out.println("chain is null: "+(chain == null));
buildPredecessor(chain);
}
}
}
public void computeMonitorObjs(){
Set maps = monitor.entrySet();
for(Iterator iter=maps.iterator(); iter.hasNext();){
Map.Entry entry = (Map.Entry)iter.next();
FlowSet fs = (FlowSet)entry.getValue();
Iterator it = fs.iterator();
while (it.hasNext()){
Object obj = it.next();
if (!monitorObjs.contains(obj)) monitorObjs.add(obj);
}
}
}
protected boolean getNeedInlining(){
//System.out.println("return needInlining: "+ needInlining);
return needInlining;
}
protected FlowSet getAllNodes(){
return (FlowSet)allNodes;
}
protected HashMap getUnitToSuccs(){
return (HashMap)unitToSuccs;
}
protected HashMap getUnitToPreds(){
return (HashMap)unitToPreds;
}
public Body getBody()
{
return body;
}
/* DirectedGraph implementation */
public List getHeads()
{
return heads;
}
public List getTails()
{
return tails;
}
public List getPredsOf(Object s)
{
if(!unitToPreds.containsKey(s))
throw new RuntimeException("Invalid stmt" + s);
return unitToPreds.get(s);
}
public List getSuccsOf(Object s)
{
if(!unitToSuccs.containsKey(s))
{
return new ArrayList();
// throw new RuntimeException("Invalid stmt:" + s);
}
return unitToSuccs.get(s);
}
public Set getCanNotBeCompacted(){
return (Set)canNotBeCompacted;
}
public int size()
{
return allNodes.size();
// return pegSize;
}
public Iterator mainIterator()
{
return mainPegChain.iterator();
}
public Iterator iterator()
{
return allNodes.iterator();
}
public String toString()
{
Iterator it = iterator();
StringBuffer buf = new StringBuffer();
while(it.hasNext()) {
JPegStmt u = (JPegStmt) it.next();
buf.append("u is: "+u+"\n");
List l = new ArrayList(); l.addAll(getPredsOf(u));
buf.append("preds: "+l+"\n");
//buf.append(u.toString() + '\n');
l = new ArrayList(); l.addAll(getSuccsOf(u));
buf.append("succs: "+l+"\n");
}
return buf.toString();
}
protected Set<Unit> getExceHandlers(){
return (Set<Unit>)exceHandlers;
}
protected void setMonitor(Map<String, FlowSet> m){
monitor = m;
}
public Map<String, FlowSet> getMonitor(){
return (Map<String, FlowSet>)monitor;
}
public Set<Object> getMonitorObjs(){
return (Set<Object>)monitorObjs;
}
protected Set getThreadAllocSites(){
return (Set)threadAllocSites;
}
protected Set<JPegStmt> getSpecialJoin(){
return (Set<JPegStmt>)specialJoin;
}
public HashSet<List> getSynch(){
return (HashSet<List>)synch;
}
public Map<JPegStmt,List> getStartToThread(){
return startToThread;
}
public Map getStartToAllocNodes()
{
return (Map)startToAllocNodes;
}
protected Map<String, FlowSet> getWaitingNodes(){
return (Map<String, FlowSet>)waitingNodes;
}
public Map<String, Set<JPegStmt>> getNotifyAll(){
return (Map<String, Set<JPegStmt>>)notifyAll;
}
protected Map<AllocNode, String> getAllocNodeToObj(){
return (Map<AllocNode, String>)allocNodeToObj;
}
public Map<AllocNode, PegChain> getAllocNodeToThread(){
return (Map<AllocNode, PegChain>)allocNodeToThread;
}
protected Map getThreadNameToStart(){
return (Map)threadNameToStart;
}
public PegChain getMainPegChain(){
return (PegChain)mainPegChain;
}
public Set getMethodsNeedingInlining(){
return (Set)methodsNeedingInlining;
}
//helper function
protected void testIterator(){
System.out.println("********begin test iterator*******");
Iterator testIt = iterator();
while (testIt.hasNext()){
System.out.println(testIt.next());
}
System.out.println("********end test iterator*******");
System.out.println("=======size is: "+size());
}
public void testWaitingNodes(){
System.out.println("------waiting---begin");
Set maps = waitingNodes.entrySet();
for(Iterator iter=maps.iterator(); iter.hasNext();){
Map.Entry entry = (Map.Entry)iter.next();
System.out.println("---key= "+entry.getKey());
FlowSet fs = (FlowSet)entry.getValue();
if (fs.size()>0){
System.out.println("**waiting nodes set:");
Iterator it = fs.iterator();
while (it.hasNext()){
JPegStmt unit =(JPegStmt)it.next();
System.out.println(unit.toString());
}
}
}
System.out.println("------------waitingnodes---ends--------");
}
protected void testStartToThread(){
System.out.println("=====test startToThread ");
Set maps = startToThread.entrySet();
for(Iterator iter=maps.iterator(); iter.hasNext();){
Map.Entry entry = (Map.Entry)iter.next();
JPegStmt key = (JPegStmt)entry.getKey();
Tag tag = (Tag)key.getTags().get(0);
System.out.println("---key= "+tag+" "+key);
/* List list = (List)entry.getValue();
if (list.size()>0){
System.out.println("**thread set:");
Iterator it = list.iterator();
while (it.hasNext()){
Chain chain =(Chain)it.next();
Iterator chainIt = chain.iterator();
System.out.println("the size of chain is: "+chain.size());
while (chainIt.hasNext()){
JPegStmt stmt = (JPegStmt)chainIt.next();
System.out.println(stmt);
}
}
}
*/
}
System.out.println("=========startToThread--ends--------");
}
protected void testUnitToPeg(HashMap unitToPeg){
System.out.println("=====test unitToPeg ");
Set maps = unitToPeg.entrySet();
for(Iterator iter=maps.iterator(); iter.hasNext();){
Map.Entry entry = (Map.Entry)iter.next();
System.out.println("---key= "+entry.getKey());
JPegStmt s= (JPegStmt)entry.getValue();
System.out.println("--value= "+s);
}
System.out.println("=========unitToPeg--ends--------");
}
protected void testUnitToSucc(){
System.out.println("=====test unitToSucc ");
Set maps = unitToSuccs.entrySet();
for(Iterator iter=maps.iterator(); iter.hasNext();){
Map.Entry entry = (Map.Entry)iter.next();
JPegStmt key = (JPegStmt)entry.getKey();
Tag tag = (Tag)key.getTags().get(0);
System.out.println("---key= "+tag+" "+key);
List list = (List)entry.getValue();
if (list.size()>0){
System.out.println("**succ set: size: "+list.size());
Iterator it = list.iterator();
while (it.hasNext()){
JPegStmt stmt = (JPegStmt)it.next();
Tag tag1 = (Tag)stmt.getTags().get(0);
System.out.println(tag1+" "+stmt);
}
}
}
System.out.println("=========unitToSucc--ends--------");
}
protected void testUnitToPred(){
System.out.println("=====test unitToPred ");
Set maps = unitToPreds.entrySet();
for(Iterator iter=maps.iterator(); iter.hasNext();){
Map.Entry entry = (Map.Entry)iter.next();
JPegStmt key = (JPegStmt)entry.getKey();
Tag tag = (Tag)key.getTags().get(0);
System.out.println("---key= "+tag+" "+key);
List list = (List)entry.getValue();
// if (list.size()>0){
System.out.println("**pred set: size: "+list.size());
Iterator it = list.iterator();
while (it.hasNext()){
JPegStmt stmt = (JPegStmt)it.next();
Tag tag1 = (Tag)stmt.getTags().get(0);
System.out.println(tag1+" "+stmt);
}
// }
}
System.out.println("=========unitToPred--ends--------");
}
protected void addTag(){
//add tag for each stmt
Iterator it = iterator();
// int count = 0;
while (it.hasNext()){
JPegStmt stmt = (JPegStmt)it.next();
int count = Counter.getTagNo();
// count++;
StringTag t = new StringTag(Integer.toString(count));
stmt.addTag(t);
}
}
protected void testSynch(){
Iterator<List> it = synch.iterator();
System.out.println("========test synch======");
while (it.hasNext()){
//JPegStmt s = (JPegStmt)it.next();
//Tag tag = (Tag)s.getTags().get(0);
// System.out.println(tag+" "+s);
System.out.println(it.next());
}
System.out.println("========end test synch======");
}
protected void testThreadNameToStart(){
System.out.println("=====test ThreadNameToStart");
Set maps = threadNameToStart.entrySet();
for(Iterator iter=maps.iterator(); iter.hasNext();){
Map.Entry entry = (Map.Entry)iter.next();
Object key = entry.getKey();
System.out.println("---key= "+key);
JPegStmt stmt = (JPegStmt)entry.getValue();
Tag tag1 = (Tag)stmt.getTags().get(0);
System.out.println("value: "+tag1+" "+stmt);
}
System.out.println("=========ThreadNameToStart--ends--------");
}
protected void testJoinStmtToThread(){
System.out.println("=====test JoinStmtToThread");
Set maps = threadNameToStart.entrySet();
for(Iterator iter=maps.iterator(); iter.hasNext();){
Map.Entry entry = (Map.Entry)iter.next();
Object key = entry.getKey();
System.out.println("---key= "+key);
System.out.println("value: "+entry.getValue());
}
System.out.println("=========JoinStmtToThread--ends--------");
}
protected void testPegChain(Chain chain)
{
System.out.println("******** chain********");
Iterator it = chain.iterator();
while (it.hasNext()) {
/*Object o = it.next();
System.out.println(o);
if (!(o instanceof JPegStmt)) System.out.println("not instanceof JPegStmt: "+o);
JPegStmt s = (JPegStmt)o;
*/
JPegStmt stmt =(JPegStmt)it.next();
System.out.println(stmt.toString());
/*if (stmt.getName().equals("start")){
System.out.println("find start method in : " + stmt.toString() );
List list =(List)startToThread.get(stmt);
Iterator chainIt = list.iterator();
while (chainIt.hasNext()){
Chain chain = (Chain)chainIt.next();
Iterator subit = chain.iterator();
while (subit.hasNext()){
System.out.println("**" + ((JPegStmt)subit.next()).toString());
}
}
System.out.println("$$$$$$returing to main chain");
}
*/
}
}
protected void computeEdgeAndThreadNo(){
Iterator it = iterator();
int numberOfEdge = 0;
while (it.hasNext()){
List succList =(List)getSuccsOf(it.next());
numberOfEdge = numberOfEdge + succList.size();
}
numberOfEdge = numberOfEdge + startToThread.size();
System.err.println("**number of edges: "+numberOfEdge);
System.err.println("**number of threads: "+ (startToThread.size()+ 1 ));
/* Set keySet = startToThread.keySet();
Iterator keyIt = keySet.iterator();
while (keyIt.hasNext()){
List list = (List)startToThread.get(keyIt.next());
System.out.println("********start thread:");
Iterator itit = list.iterator();
while (itit.hasNext()){
System.out.println(it.next());
}
}
*/
}
protected void testList(List list){
// System.out.println("test list");
Iterator listIt = list.iterator();
while (listIt.hasNext()){
System.out.println(listIt.next());
}
}
protected void testSet(Set set, String name){
System.out.println("$test set "+name);
Iterator setIt = set.iterator();
while (setIt.hasNext()){
Object s = setIt.next();
// JPegStmt s = (JPegStmt)setIt.next();
//Tag tag = (Tag)s.getTags().get(0);
System.out.println(s);
}
}
public void testMonitor(){
System.out.println("=====test monitor size: "+monitor.size());
Set maps = monitor.entrySet();
for(Iterator iter=maps.iterator(); iter.hasNext();){
Map.Entry entry = (Map.Entry)iter.next();
String key = (String)entry.getKey();
System.out.println("---key= "+key);
FlowSet list = (FlowSet)entry.getValue();
if (list.size()>0){
System.out.println("**set: "+list.size());
Iterator it = list.iterator();
while (it.hasNext()){
Object obj = it.next();
if (obj instanceof JPegStmt){
JPegStmt stmt = (JPegStmt)obj;
Tag tag1 = (Tag)stmt.getTags().get(0);
System.out.println(tag1+" "+stmt);
}
else{
System.out.println("---list---");
Iterator listIt = ((List)obj).iterator();
while (listIt.hasNext()){
Object oo = listIt.next();
if (oo instanceof JPegStmt){
JPegStmt unit = (JPegStmt)oo;
Tag tag = (Tag)unit.getTags().get(0);
System.out.println(tag+" "+unit);
}
else
System.out.println(oo);
}
System.out.println("---list--end-");
}
}
}
}
System.out.println("=========monitor--ends--------");
}
}