Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright (c) 2002 - 2006 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.escape;
import com.ibm.wala.analysis.pointers.HeapGraph;
import com.ibm.wala.classLoader.NewSiteReference;
import com.ibm.wala.ipa.callgraph.CGNode;
import com.ibm.wala.ipa.callgraph.CallGraph;
import com.ibm.wala.ipa.callgraph.propagation.AbstractLocalPointerKey;
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
import com.ibm.wala.ipa.callgraph.propagation.LocalPointerKey;
import com.ibm.wala.ipa.callgraph.propagation.PropagationCallGraphBuilder.TypedPointerKey;
import com.ibm.wala.ipa.callgraph.propagation.StaticFieldKey;
import com.ibm.wala.ssa.DefUse;
import com.ibm.wala.ssa.IR;
import com.ibm.wala.util.WalaException;
import com.ibm.wala.util.collections.HashMapFactory;
import com.ibm.wala.util.collections.HashSetFactory;
import com.ibm.wala.util.collections.Iterator2Iterable;
import com.ibm.wala.util.debug.Assertions;
import com.ibm.wala.util.graph.impl.GraphInverter;
import com.ibm.wala.util.graph.traverse.DFS;
import com.ibm.wala.util.intset.IntIterator;
import com.ibm.wala.util.intset.IntSet;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
/** A simple liveness analysis based on flow-insensitive pointer analysis. */
public class FILiveObjectAnalysis implements ILiveObjectAnalysis {
/** governing call graph */
private final CallGraph callGraph;
/** Graph view of pointer analysis results */
private final HeapGraph> heapGraph;
/** Cached map from InstanceKey -> Set<CGNode> */
private final Map> liveNodes = HashMapFactory.make();
/** Set of instanceKeys which are live everywhere */
private final Set liveEverywhere = HashSetFactory.make();
/** A hack for now .. since right now the intraprocedural analysis is expensive */
private final boolean expensiveIntraproceduralAnalysis;
/** */
public FILiveObjectAnalysis(
CallGraph callGraph, HeapGraph> heapGraph, boolean expensiveIntraproceduralAnalysis) {
super();
this.callGraph = callGraph;
this.heapGraph = heapGraph;
this.expensiveIntraproceduralAnalysis = expensiveIntraproceduralAnalysis;
}
@Override
public boolean mayBeLive(CGNode allocMethod, int allocPC, CGNode m, int instructionIndex)
throws IllegalArgumentException, WalaException {
if (allocMethod == null) {
throw new IllegalArgumentException("allocMethod == null");
}
NewSiteReference site = TrivialMethodEscape.findAlloc(allocMethod, allocPC);
InstanceKey ik = heapGraph.getHeapModel().getInstanceKeyForAllocation(allocMethod, site);
return mayBeLive(ik, m, instructionIndex);
}
/**
* @param instructionIndex index of an SSA instruction
*/
@Override
public boolean mayBeLive(InstanceKey ik, CGNode m, int instructionIndex) {
if (liveEverywhere.contains(ik)) {
return true;
} else {
Set live = liveNodes.get(ik);
if (live != null) {
if (live.contains(m)) {
if (instructionIndex == -1) {
return true;
} else {
if (mayBeLiveInSomeCaller(ik, m)) {
// a hack. if it's live in some caller of m, assume it's live
// throughout m. this may be imprecise.
return true;
} else {
if (expensiveIntraproceduralAnalysis) {
return mayBeLiveIntraprocedural(ik, m, instructionIndex);
} else {
// be conservative
return true;
}
}
}
} else {
return false;
}
} else {
live = computeLiveNodes(ik);
liveNodes.put(ik, live);
return mayBeLive(ik, m, instructionIndex);
}
}
}
private boolean mayBeLiveInSomeCaller(InstanceKey ik, CGNode m) {
for (CGNode n : Iterator2Iterable.make(callGraph.getPredNodes(m))) {
if (mayBeLive(ik, n, -1)) {
return true;
}
}
return false;
}
/**
* precondition: !mayBeLiveInSomeCaller(ik, m)
*
* @param instructionIndex index of an SSA instruction
*/
private boolean mayBeLiveIntraprocedural(InstanceKey ik, CGNode m, int instructionIndex) {
IR ir = m.getIR();
DefUse du = m.getDU();
for (Object p :
Iterator2Iterable.make(DFS.iterateDiscoverTime(GraphInverter.invert(heapGraph), ik))) {
if (p instanceof LocalPointerKey) {
LocalPointerKey lpk = (LocalPointerKey) p;
if (lpk.getNode().equals(m)) {
if (LocalLiveRangeAnalysis.isLive(lpk.getValueNumber(), instructionIndex, ir, du)) {
return true;
}
}
}
}
return false;
}
/**
* Compute the set of nodes in which ik may be live. If it's live everywhere, return an EMPTY_SET,
* but also record this fact in the "liveEverywhere" set as a side effect
*/
private Set computeLiveNodes(InstanceKey ik) {
Set localRootNodes = HashSetFactory.make();
for (Object node :
Iterator2Iterable.make(DFS.iterateDiscoverTime(GraphInverter.invert(heapGraph), ik))) {
if (node instanceof StaticFieldKey) {
liveEverywhere.add(ik);
return Collections.emptySet();
} else {
if (node instanceof AbstractLocalPointerKey) {
AbstractLocalPointerKey local = (AbstractLocalPointerKey) node;
localRootNodes.add(local.getNode());
} else if (node instanceof TypedPointerKey) {
TypedPointerKey t = (TypedPointerKey) node;
node = t.getBase();
if (node instanceof AbstractLocalPointerKey) {
AbstractLocalPointerKey local = (AbstractLocalPointerKey) node;
localRootNodes.add(local.getNode());
} else {
Assertions.UNREACHABLE(
"unexpected base of TypedPointerKey: " + node.getClass() + ' ' + node);
}
}
}
}
return DFS.getReachableNodes(callGraph, localRootNodes);
}
@Override
public boolean mayBeLive(InstanceKey ik, CGNode m, IntSet instructionIndices) {
if (instructionIndices == null) {
throw new IllegalArgumentException("instructionIndices is null");
}
// TODO this sucks
for (IntIterator it = instructionIndices.intIterator(); it.hasNext(); ) {
int i = it.next();
if (mayBeLive(ik, m, i)) {
return true;
}
}
return false;
}
}