WALA/com.ibm.wala.core/src/com/ibm/wala/ssa/SSACache.java

156 lines
4.2 KiB
Java

/*******************************************************************************
* 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.ssa;
import com.ibm.wala.classLoader.IMethod;
import com.ibm.wala.ipa.callgraph.Context;
import com.ibm.wala.ipa.callgraph.impl.Everywhere;
/**
* A mapping from IMethod -> SSAOptions -> SoftReference -> Something
*
* This doesn't work very well ... GCs don't do such a great job with SoftReferences ... revamp it.
*/
public class SSACache {
/**
* used for debugging
*/
private static final boolean DISABLE = false;
/**
* The factory that actually creates new IR objects
*/
private final IRFactory<IMethod> factory;
/**
* A cache of SSA IRs
*/
final private IAuxiliaryCache irCache;
/**
* A cache of DefUse information
*/
final private IAuxiliaryCache duCache;
/**
* @param factory a factory for creating IRs
*/
public SSACache(IRFactory<IMethod> factory, IAuxiliaryCache irCache, IAuxiliaryCache duCache) {
this.factory = factory;
this.irCache = irCache;
this.duCache = duCache;
}
/**
* @param m a "normal" (bytecode-based) method
* @param options options governing ssa construction
* @return an IR for m, built according to the specified options. null if m is abstract or native.
* @throws IllegalArgumentException if m is null
*/
public synchronized IR findOrCreateIR(final IMethod m, Context c, final SSAOptions options) {
if (m == null) {
throw new IllegalArgumentException("m is null");
}
if (m.isAbstract() || m.isNative()) {
return null;
}
if (factory.contextIsIrrelevant(m)) {
c = Everywhere.EVERYWHERE;
}
if (DISABLE) {
return factory.makeIR(m, c, options);
}
IR ir = (IR) irCache.find(m, c, options);
if (ir == null) {
ir = factory.makeIR(m, c, options);
irCache.cache(m, c, options, ir);
}
return ir;
}
/**
* @param m a method
* @param options options governing ssa construction
* @return DefUse information for m, built according to the specified options. null if unavailable
* @throws IllegalArgumentException if m is null
*/
public synchronized DefUse findOrCreateDU(IMethod m, Context c, SSAOptions options) {
if (m == null) {
throw new IllegalArgumentException("m is null");
}
if (m.isAbstract() || m.isNative()) {
return null;
}
if (factory.contextIsIrrelevant(m)) {
c = Everywhere.EVERYWHERE;
}
DefUse du = (DefUse) duCache.find(m, c, options);
if (du == null) {
IR ir = findOrCreateIR(m, c, options);
du = new DefUse(ir);
duCache.cache(m, c, options, du);
}
return du;
}
/**
* @return {@link DefUse} information for m, built according to the specified options. null if unavailable
* @throws IllegalArgumentException if ir is null
*/
public synchronized DefUse findOrCreateDU(IR ir, Context C) {
if (ir == null) {
throw new IllegalArgumentException("ir is null");
}
DefUse du = (DefUse) duCache.find(ir.getMethod(), C, ir.getOptions());
if (du == null) {
du = new DefUse(ir);
duCache.cache(ir.getMethod(), C, ir.getOptions(), du);
}
return du;
}
/**
* The existence of this is unfortunate.
*/
public void wipe() {
irCache.wipe();
duCache.wipe();
}
/**
* Invalidate the cached IR for a &lt;method,context&gt; pair
*/
public void invalidateIR(IMethod method, Context c) {
irCache.invalidate(method, c);
}
/**
* Invalidate the cached {@link DefUse} for a &lt;method,context&gt; pair
*/
public void invalidateDU(IMethod method, Context c) {
duCache.invalidate(method, c);
}
/**
* Invalidate all cached information for a &lt;method,context&gt; pair
*/
public void invalidate(IMethod method, Context c) {
invalidateIR(method, c);
invalidateDU(method, c);
}
}