156 lines
4.2 KiB
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 <method,context> pair
|
|
*/
|
|
public void invalidateIR(IMethod method, Context c) {
|
|
irCache.invalidate(method, c);
|
|
}
|
|
|
|
/**
|
|
* Invalidate the cached {@link DefUse} for a <method,context> pair
|
|
*/
|
|
public void invalidateDU(IMethod method, Context c) {
|
|
duCache.invalidate(method, c);
|
|
}
|
|
|
|
/**
|
|
* Invalidate all cached information for a <method,context> pair
|
|
*/
|
|
public void invalidate(IMethod method, Context c) {
|
|
invalidateIR(method, c);
|
|
invalidateDU(method, c);
|
|
}
|
|
}
|