Пример #1
0
 protected SDGNode reachedNode(SDGEdge edge) {
   return edge.getSource();
 }
Пример #2
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;
  }