예제 #1
0
  private static SDGNode findExitNode(SDGNode node, CFG cfg) {
    SDGNode entry = cfg.getEntry(node);
    LinkedList<SDGNode> wl = new LinkedList<SDGNode>();
    Set<SDGNode> visited = new HashSet<SDGNode>();
    wl.add(entry);
    while (!wl.isEmpty()) {
      SDGNode n = wl.poll();
      visited.add(n);
      if (n.getKind() == SDGNode.Kind.EXIT) {
        return n;
      } else {

        for (SDGEdge e : cfg.outgoingEdgesOf(n)) {
          if (!visited.contains(e.getTarget()) && e.getKind() == SDGEdge.Kind.CONTROL_FLOW) {
            wl.add(e.getTarget());
          }
        }
      }
    }

    throw new IllegalStateException(
        "Visited the following nodes, which not include an exit node: " + visited);
  }
예제 #2
0
 protected SDGNode reachedNode(SDGEdge edge) {
   return edge.getSource();
 }
예제 #3
0
  @Override
  public Collection<SDGNode> slice(Collection<SDGNode> criteria) {
    LinkedList<SDGNode> worklist_0 = new LinkedList<SDGNode>();
    LinkedList<SDGNode> worklist_1 = new LinkedList<SDGNode>();
    LinkedList<SDGNode> worklist_2 = new LinkedList<SDGNode>();
    HashSet<SDGNode> visited_0_1 = new HashSet<SDGNode>();
    HashSet<SDGNode> visited_2 = new HashSet<SDGNode>();
    worklist_0.addAll(criteria);
    visited_0_1.addAll(criteria);
    // System.out.println("searching for data channels");

    edgeListener.init();

    // die basis bildet ein iterierter zwei-phasen slice
    while (!worklist_0.isEmpty()) {
      // init the next iteration
      visited_2.clear();

      worklist_1.add(worklist_0.poll());
      visited_0_1.add(worklist_1.peek());

      // === phase 1 ===
      // only ascend to calling procedures
      while (!worklist_1.isEmpty()) {
        SDGNode next = worklist_1.poll();

        for (SDGEdge edge : g.incomingEdgesOf(next)) {
          edgeListener.edgeEncountered(edge);
          SDGNode adjacent = edge.getSource();

          if (edge.getKind() == SDGEdge.Kind.INTERFERENCE
              || edge.getKind() == SDGEdge.Kind.FORK_IN
              || edge.getKind() == SDGEdge.Kind.FORK_OUT
              || edge.getKind() == SDGEdge.Kind.FORK) {
            // handle thread edges - concurrency edges have to be
            // traversed in the next iteration
            // TODO: what about join edges? Why are thread numbers
            // not taken into account?
            // I suspect that this is not critical for correctness
            // but rather for precision...
            if (visited_0_1.add(adjacent)) {
              worklist_0.add(adjacent);
            }

          } else if (edge.getKind() == SDGEdge.Kind.PARAMETER_OUT) {
            // descend into called procedure in phase two!
            if (visited_2.add(adjacent)) {
              worklist_2.add(adjacent);
            }

          } else if (edge.getKind().isSDGEdge()) { // note that return
            // edges are no
            // sdg edges!

            // intra-procedural or ascending edge
            if (visited_0_1.add(adjacent)) {
              worklist_1.add(adjacent);
            }
          }
        }
      }

      // === phase 2 ===
      // visit all procedures called underway
      while (!worklist_2.isEmpty()) {
        SDGNode next = worklist_2.poll();

        for (SDGEdge edge : g.incomingEdgesOf(next)) {
          edgeListener.edgeEncountered(edge);
          SDGNode adjacent = edge.getSource();

          if (edge.getKind() == SDGEdge.Kind.INTERFERENCE) {
            // handle interference edges: create new elements for
            // worklist_0
            if (visited_0_1.add(adjacent)) {
              worklist_0.add(adjacent);
            }

          } else if (edge.getKind().isSDGEdge()
              && edge.getKind() != SDGEdge.Kind.CALL
              && edge.getKind() != SDGEdge.Kind.PARAMETER_IN
              && edge.getKind() != SDGEdge.Kind.FORK
              && edge.getKind() != SDGEdge.Kind.FORK_IN) {

            // intra-procedural or param-out edge
            if (visited_2.add(adjacent)) {
              worklist_2.add(adjacent);
            }
          }
        }
      }
    }

    return visited_0_1;
  }
예제 #4
-1
  private static Set<SDGNode> filterStatic(final SDG sdg, final Set<SDGNode> nodes) {
    final Set<SDGNode> filtered = new HashSet<SDGNode>();

    for (SDGNode n : nodes) {
      if (n.getBytecodeIndex() == BytecodeLocation.ROOT_PARAMETER) {
        filtered.add(n);
      }
    }

    LinkedList<SDGNode> work = new LinkedList<SDGNode>();
    work.addAll(filtered);
    while (!work.isEmpty()) {
      final SDGNode n = work.removeFirst();

      for (SDGEdge edge : sdg.getOutgoingEdgesOfKind(n, SDGEdge.Kind.PARAMETER_STRUCTURE)) {
        final SDGNode tgt = edge.getTarget();
        if (!filtered.contains(tgt)) {
          filtered.add(tgt);
          work.add(tgt);
        }
      }
    }

    return filtered;
  }