Package soot.jimple.toolkits.thread

Examples of soot.jimple.toolkits.thread.AbstractRuntimeThread


      Stmt startStmt = (Stmt) e.getKey();
      List runMethods = (List) e.getValue();
      List threadAllocNodes = startToAllocNodes.get(e.getKey());

      // Get a list of all possible unique Runnable.run methods for this thread start statement
      AbstractRuntimeThread thread = new AbstractRuntimeThread(); // provides a list interface to the methods in a thread's sub-call-graph
      thread.setStartStmt(startStmt);
//      List threadMethods = new ArrayList();
      Iterator runMethodsIt = runMethods.iterator();
      while(runMethodsIt.hasNext())
      {
        SootMethod method = (SootMethod) runMethodsIt.next();
        if(!thread.containsMethod(method))
        {
          thread.addMethod(method);
          thread.addRunMethod(method);
        }
      }
     
      // Get a list containing all methods in the call graph(s) rooted at the possible run methods for this thread start statement
      // AKA a list of all methods that might be called by the thread started here
      int methodNum = 0;
      while(methodNum < thread.methodCount()) // iterate over all methods in threadMethods, even as new methods are being added to it
      {
        Iterator succMethodsIt = pecg.getSuccsOf(thread.getMethod(methodNum)).iterator();
        while(succMethodsIt.hasNext())
        {
          SootMethod method = (SootMethod) succMethodsIt.next();
          // if all edges into this method are of Kind THREAD, ignore it
          // (because it's a run method that won't be called as part of THIS thread) THIS IS NOT OPTIMAL
          boolean ignoremethod = true;
          Iterator edgeInIt = callGraph.edgesInto(method);
          while(edgeInIt.hasNext())
          {
            Edge edge = (Edge) edgeInIt.next();
            if( edge.kind() != Kind.THREAD && thread.containsMethod(edge.src())) // called directly by any of the thread methods?
              ignoremethod = false;
          }
          if(!ignoremethod && !thread.containsMethod(method))
            thread.addMethod(method);
        }
        methodNum++;
      }
     
      // Add this list of methods to MHPLists
      MHPLists.add(thread);
      if(optionPrintDebug)
        System.out.println(thread.toString());
     
      // Find out if the "thread" in "thread.start()" could be more than one object
      boolean mayStartMultipleThreadObjects = (threadAllocNodes.size() > 1) || so.types_for_sites();
      if(!mayStartMultipleThreadObjects) // if there's only one alloc node
      {
        if(multiRunAllocNodes.contains(threadAllocNodes.iterator().next())) // but it gets run more than once
        {
          mayStartMultipleThreadObjects = true; // then "thread" in "thread.start()" could be more than one object
        }
      }
     
      if(mayStartMultipleThreadObjects)
        thread.setStartStmtHasMultipleReachingObjects();
     
      // Find out if the "thread.start()" statement may be run more than once
      SootMethod startStmtMethod = startToContainingMethod.get(startStmt);
      thread.setStartStmtMethod(startStmtMethod);
      boolean mayBeRunMultipleTimes = multiCalledMethods.contains(startStmtMethod); // if method is called more than once...
      if(!mayBeRunMultipleTimes)
      {
        UnitGraph graph = new CompleteUnitGraph(startStmtMethod.getActiveBody());
        MultiRunStatementsFinder finder = new MultiRunStatementsFinder(
          graph, startStmtMethod, multiCalledMethods, callGraph);
        FlowSet multiRunStatements = finder.getMultiRunStatements(); // list of all units that may be run more than once in this method
        if(multiRunStatements.contains(startStmt))
          mayBeRunMultipleTimes = true;
      }
     
      if(mayBeRunMultipleTimes)
      {
        thread.setStartStmtMayBeRunMultipleTimes();
      }

      // If a run-many thread.start() statement is (always) associated with a join statement in the same method,
      // then it may be possible to treat it as run-once, if this method is non-reentrant and called only
      // by one thread (sounds strict, but actually this is the most common case)
      if(mayBeRunMultipleTimes && startToJoin.containsKey(startStmt))
      {
        thread.setJoinStmt(startToJoin.get(startStmt));
        mayBeRunMultipleTimes = false; // well, actually, we don't know yet
        methodNum = 0;
        List<SootMethod> containingMethodCalls = new ArrayList<SootMethod>();
        containingMethodCalls.add(startStmtMethod);
        while(methodNum < containingMethodCalls.size()) // iterate over all methods in threadMethods, even as new methods are being added to it
        {
          Iterator succMethodsIt = pecg.getSuccsOf(containingMethodCalls.get(methodNum)).iterator();
          while(succMethodsIt.hasNext())
          {
            SootMethod method = (SootMethod) succMethodsIt.next();
            if(method == startStmtMethod)
            {// this method is reentrant
              mayBeRunMultipleTimes = true; // this time it's for sure
              thread.setStartMethodIsReentrant();
              thread.setRunsMany();
              break;
            }
            if(!containingMethodCalls.contains(method))
              containingMethodCalls.add(method);
          }
          methodNum++;
        }
        if(!mayBeRunMultipleTimes)
        {// There's still one thing that might cause this to be run multiple times: if it can be run in parallel with itself
         // but we can't find that out 'till we're done
          runAtOnceCandidates.add(thread);
        }
      }

      // If more than one thread might be started at this start statement,
      // and this start statement may be run more than once,
      // then add this list of methods to MHPLists *AGAIN*
      if(optionPrintDebug)
        System.out.println("Start Stmt " + startStmt.toString() +
          " mayStartMultipleThreadObjects=" + mayStartMultipleThreadObjects + " mayBeRunMultipleTimes=" + mayBeRunMultipleTimes);
      if(mayStartMultipleThreadObjects && mayBeRunMultipleTimes)
      {
        MHPLists.add(thread); // add another copy
        thread.setRunsMany();
        if(optionPrintDebug)
          System.out.println(thread.toString());
      }
      else
        thread.setRunsOnce();
      threadNum++;
    }

    // do same for main method
    AbstractRuntimeThread mainThread = new AbstractRuntimeThread();
//    List mainMethods = new ArrayList();
    MHPLists.add(mainThread);
    mainThread.setRunsOnce();
    mainThread.addMethod(mainMethod);
    mainThread.addRunMethod(mainMethod);
    mainThread.setIsMainThread();
    // get all the successors, add to threadMethods
    int methodNum = 0;
    while(methodNum < mainThread.methodCount())
    {
      Iterator succMethodsIt = pecg.getSuccsOf(mainThread.getMethod(methodNum)).iterator();
      while(succMethodsIt.hasNext())
      {
        SootMethod method = (SootMethod) succMethodsIt.next();
        // if all edges into this are of Kind THREAD, ignore it
        boolean ignoremethod = true;
        Iterator edgeInIt = callGraph.edgesInto(method);
        while(edgeInIt.hasNext())
        {
          if( ((Edge) edgeInIt.next()).kind() != Kind.THREAD )
            ignoremethod = false;
        }
        if(!ignoremethod && !mainThread.containsMethod(method))
          mainThread.addMethod(method);
      }
      methodNum++;
    }
    if(optionPrintDebug)
      G.v().out.println(mainThread.toString());
     
    // Revisit the containing methods of start-join pairs that are non-reentrant but might be called in parallel
    boolean addedNew = true;
    while(addedNew)
    {
      addedNew = false;
      Iterator<AbstractRuntimeThread> it = runAtOnceCandidates.iterator();
      while(it.hasNext())
      {
        AbstractRuntimeThread someThread = it.next();
        SootMethod someStartMethod = someThread.getStartStmtMethod();
        if(mayHappenInParallelInternal(someStartMethod, someStartMethod))
        {
          MHPLists.add(someThread); // add a second copy of it
          someThread.setStartMethodMayHappenInParallel();
          someThread.setRunsMany();
          runAtOnceCandidates.remove(someThread);
          if(optionPrintDebug)
            G.v().out.println(someThread.toString());
          addedNew = true;
        }
      }
    }
   
    // mark the remaining threads here as run-one-at-a-time
    Iterator<AbstractRuntimeThread> it = runAtOnceCandidates.iterator();
    while(it.hasNext())
    {
      AbstractRuntimeThread someThread = it.next();
      someThread.setRunsOneAtATime();
    }
  }
View Full Code Here


   
    List<SootClass> threadClasses = new ArrayList<SootClass>();
    int size = MHPLists.size();
    for(int i = 0; i < size; i++)
    {
      AbstractRuntimeThread thread = MHPLists.get(i);
      Iterator<Object> threadRunMethodIt = thread.getRunMethods().iterator();
      while(threadRunMethodIt.hasNext())
      {
        SootClass threadClass = ((SootMethod) threadRunMethodIt.next()).getDeclaringClass(); // what about subclasses???
        if( !threadClasses.contains(threadClass) && threadClass.isApplicationClass() ) // only include application threads
          threadClasses.add(threadClass);
View Full Code Here

TOP

Related Classes of soot.jimple.toolkits.thread.AbstractRuntimeThread

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.