protected SDGNode reachedNode(SDGEdge edge) { return edge.getSource(); }
@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; }