All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.ibm.wala.escape.TrivialMethodEscape Maven / Gradle / Ivy

/*
 * 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.PointerKey;
import com.ibm.wala.ipa.callgraph.propagation.ReturnValueKey;
import com.ibm.wala.types.MethodReference;
import com.ibm.wala.util.WalaException;
import com.ibm.wala.util.collections.HashSetFactory;
import com.ibm.wala.util.collections.Iterator2Iterable;
import java.util.Collections;
import java.util.Set;

/**
 * Trivial method-level escape analysis.
 *
 * 

An instance does not escape from method m if the following hold: * *

    *
  1. the instance is only ever pointed to by locals (it is never stored in the heap) *
  2. the method m does NOT return (either normally or exceptionally) a pointer to the instance *
*/ public class TrivialMethodEscape implements IMethodEscapeAnalysis, INodeEscapeAnalysis { /** Heap graph representation of pointer analysis */ private final HeapGraph hg; /** Governing call graph */ private final CallGraph cg; /** * @param hg Heap graph representation of pointer analysis * @param cg governing call graph */ public TrivialMethodEscape(CallGraph cg, HeapGraph hg) { this.hg = hg; this.cg = cg; } @Override public boolean mayEscape(MethodReference allocMethod, int allocPC, MethodReference m) throws WalaException { if (allocMethod == null) { throw new IllegalArgumentException("null allocMethod"); } // nodes:= set of call graph nodes representing method m Set nodes = cg.getNodes(m); if (nodes.isEmpty()) { throw new WalaException("could not find call graph node for method " + m); } // allocN := set of call graph nodes representing method allocMethod Set allocN = cg.getNodes(allocMethod); if (allocN.isEmpty()) { throw new WalaException( "could not find call graph node for allocation method " + allocMethod); } return mayEscape(allocN, allocPC, nodes); } @Override public boolean mayEscape(CGNode allocNode, int allocPC, CGNode node) throws WalaException { return mayEscape(Collections.singleton(allocNode), allocPC, Collections.singleton(node)); } /** * @param allocN {@code Set} representing the allocation site. * @param nodes {@code Set}, the nodes of interest * @return true iff some instance allocated at a site N \in <allocN, allocPC> might escape from * some activation of a node m \in { nodes } */ private boolean mayEscape(Set allocN, int allocPC, Set nodes) throws WalaException { Set instances = HashSetFactory.make(); // instances := set of instance key allocated at <allocMethod, allocPC> for (CGNode n : allocN) { NewSiteReference site = findAlloc(n, allocPC); InstanceKey ik = hg.getHeapModel().getInstanceKeyForAllocation(n, site); if (ik == null) { throw new WalaException("could not get instance key at site " + site + " in " + n); } instances.add(ik); } for (InstanceKey ik : instances) { for (Object o : Iterator2Iterable.make(hg.getPredNodes(ik))) { PointerKey p = (PointerKey) o; if (!(p instanceof AbstractLocalPointerKey)) { // a pointer from the heap. give up. return true; } else { if (p instanceof ReturnValueKey) { ReturnValueKey rk = (ReturnValueKey) p; if (nodes.contains(rk.getNode())) { // some node representing method m returns the instance to its // caller return true; } } } } } // if we get here, it may not escape return false; } /** * @param n a call graph node * @param allocPC a bytecode index corresponding to an allocation * @return the NewSiteReference for the allocation */ static NewSiteReference findAlloc(CGNode n, int allocPC) throws WalaException { if (n == null) { throw new IllegalArgumentException("null n"); } for (NewSiteReference site : Iterator2Iterable.make(n.iterateNewSites())) { if (site.getProgramCounter() == allocPC) { return site; } } throw new WalaException("Failed to find an allocation at pc " + allocPC + " in node " + n); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy