/******************************************************************************* * Copyright (c) 2007 IBM Corporation. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package com.ibm.wala.ipa.slicer.thin; import java.util.Collection; import java.util.Iterator; import java.util.Map; import java.util.Set; import com.ibm.wala.ipa.callgraph.CGNode; import com.ibm.wala.ipa.callgraph.propagation.PointerKey; import com.ibm.wala.ipa.cha.IClassHierarchy; import com.ibm.wala.ipa.slicer.ISDG; import com.ibm.wala.ipa.slicer.PDG; import com.ibm.wala.ipa.slicer.SDG; import com.ibm.wala.ipa.slicer.Slicer.ControlDependenceOptions; import com.ibm.wala.ipa.slicer.Statement; import com.ibm.wala.util.collections.HashSetFactory; import com.ibm.wala.util.collections.Iterator2Collection; import com.ibm.wala.util.collections.IteratorUtil; import com.ibm.wala.util.collections.MapUtil; import com.ibm.wala.util.debug.Assertions; import com.ibm.wala.util.intset.IntSet; /** * A context-insensitive SDG. This class assumes that it is given a normal NO_HEAP SDG. It adds context-insensitive heap information * directly from heap stores to corresponding loads, based on an underlying pointer analysis. */ public class CISDG implements ISDG { private final static boolean DEBUG = false; /** * the basic SDG, without interprocedural heap edges */ final SDG noHeap; /** * What pointer keys does each statement mod? */ private final Map<Statement, Set<PointerKey>> ref; /** * What pointer keys does each statement ref? */ private final Map<Statement, Set<PointerKey>> mod; /** * What statements write each pointer key? */ final Map<PointerKey, Set<Statement>> invMod; /** * What statements ref each pointer key? */ final Map<PointerKey, Set<Statement>> invRef; protected CISDG(SDG noHeap, Map<Statement, Set<PointerKey>> mod, Map<Statement, Set<PointerKey>> ref) { this.noHeap = noHeap; this.mod = mod; this.ref = ref; invMod = MapUtil.inverseMap(mod); invRef = MapUtil.inverseMap(ref); } @Override public void addEdge(Statement src, Statement dst) { Assertions.UNREACHABLE(); noHeap.addEdge(src, dst); } @Override public void addNode(Statement n) { Assertions.UNREACHABLE(); noHeap.addNode(n); } @Override public boolean containsNode(Statement N) { return noHeap.containsNode(N); } @Override public boolean equals(Object obj) { Assertions.UNREACHABLE(); return noHeap.equals(obj); } @Override public ControlDependenceOptions getCOptions() { Assertions.UNREACHABLE(); return noHeap.getCOptions(); } @Override public int getMaxNumber() { return noHeap.getMaxNumber(); } @Override public Statement getNode(int number) { Assertions.UNREACHABLE(); return noHeap.getNode(number); } @Override public int getNumber(Statement N) { return noHeap.getNumber(N); } @Override public int getNumberOfNodes() { return noHeap.getNumberOfNodes(); } @Override public PDG getPDG(CGNode node) { Assertions.UNREACHABLE(); return noHeap.getPDG(node); } @Override public int getPredNodeCount(Statement N) { return IteratorUtil.count(getPredNodes(N)); } @Override public IntSet getPredNodeNumbers(Statement node) { Assertions.UNREACHABLE(); return noHeap.getPredNodeNumbers(node); } @Override public Iterator<Statement> getPredNodes(Statement N) { if (DEBUG) { System.err.println("getPredNodes " + N); } if (ref.get(N) == null) { return noHeap.getPredNodes(N); } else { Collection<Statement> pred = HashSetFactory.make(); for (PointerKey p : ref.get(N)) { if (invMod.get(p) != null) { pred.addAll(invMod.get(p)); } } pred.addAll(Iterator2Collection.toSet(noHeap.getPredNodes(N))); return pred.iterator(); } } @Override public int getSuccNodeCount(Statement N) { return IteratorUtil.count(getSuccNodes(N)); } @Override public IntSet getSuccNodeNumbers(Statement node) { Assertions.UNREACHABLE(); return noHeap.getSuccNodeNumbers(node); } @Override public Iterator<Statement> getSuccNodes(Statement N) { if (DEBUG) { System.err.println("getSuccNodes " + N); } if (mod.get(N) == null) { return noHeap.getSuccNodes(N); } else { Collection<Statement> succ = HashSetFactory.make(); for (PointerKey p : mod.get(N)) { if (invRef.get(p) != null) { succ.addAll(invRef.get(p)); } } succ.addAll(Iterator2Collection.toSet(noHeap.getSuccNodes(N))); return succ.iterator(); } } @Override public boolean hasEdge(Statement src, Statement dst) { Assertions.UNREACHABLE(); return noHeap.hasEdge(src, dst); } @Override public int hashCode() { Assertions.UNREACHABLE(); return noHeap.hashCode(); } @Override public Iterator<? extends Statement> iterateLazyNodes() { Assertions.UNREACHABLE(); return noHeap.iterateLazyNodes(); } @Override public Iterator<Statement> iterator() { return noHeap.iterator(); } @Override public Iterator<Statement> iterateNodes(IntSet s) { Assertions.UNREACHABLE(); return noHeap.iterateNodes(s); } @Override public void removeAllIncidentEdges(Statement node) { Assertions.UNREACHABLE(); noHeap.removeAllIncidentEdges(node); } @Override public void removeEdge(Statement src, Statement dst) { Assertions.UNREACHABLE(); noHeap.removeEdge(src, dst); } @Override public void removeIncomingEdges(Statement node) { Assertions.UNREACHABLE(); noHeap.removeIncomingEdges(node); } @Override public void removeNode(Statement n) { Assertions.UNREACHABLE(); noHeap.removeNode(n); } @Override public void removeNodeAndEdges(Statement N) { Assertions.UNREACHABLE(); noHeap.removeNodeAndEdges(N); } @Override public void removeOutgoingEdges(Statement node) { Assertions.UNREACHABLE(); noHeap.removeOutgoingEdges(node); } @Override public String toString() { Assertions.UNREACHABLE(); return noHeap.toString(); } @Override public IClassHierarchy getClassHierarchy() { return noHeap.getClassHierarchy(); } }