protect against some pathological context explosion with synthetic factory methods

git-svn-id: https://wala.svn.sourceforge.net/svnroot/wala/trunk@2549 f5eafffb-2e1d-0410-98e4-8ec43c5233c4
This commit is contained in:
sjfink 2008-02-07 22:41:26 +00:00
parent d0ebf2e4be
commit 49639c7ed9
4 changed files with 123 additions and 91 deletions

View File

@ -19,7 +19,8 @@ import com.ibm.wala.ipa.callgraph.Context;
import com.ibm.wala.ipa.callgraph.ContextSelector;
import com.ibm.wala.ipa.callgraph.MethodTargetSelector;
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
import com.ibm.wala.ipa.callgraph.propagation.cfa.CallerSiteContext;
import com.ibm.wala.ipa.callgraph.propagation.cfa.CallString;
import com.ibm.wala.ipa.callgraph.propagation.cfa.CallStringContext;
import com.ibm.wala.ipa.cha.IClassHierarchy;
/**
@ -51,7 +52,7 @@ class FactoryContextSelector implements ContextSelector {
if (callee.isSynthetic()) {
SyntheticMethod s = (SyntheticMethod) callee;
if (s.isFactoryMethod()) {
return new CallerSiteContext(caller, site);
return new CallStringContext(new CallString(site, caller.getMethod()));
}
}
return null;
@ -137,4 +138,5 @@ class FactoryContextSelector implements ContextSelector {
return true;
}
}
}

View File

@ -0,0 +1,72 @@
/*******************************************************************************
* 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.callgraph.propagation.cfa;
import com.ibm.wala.classLoader.CallSiteReference;
import com.ibm.wala.classLoader.IMethod;
import com.ibm.wala.ipa.callgraph.ContextItem;
public class CallString implements ContextItem {
private final CallSiteReference sites[];
private final IMethod methods[];
public CallString(CallSiteReference site, IMethod method) {
this.sites = new CallSiteReference[] { site };
this.methods = new IMethod[] { method };
}
CallString(CallSiteReference site, IMethod method, int length, CallString base) {
sites = new CallSiteReference[length];
sites[0] = site;
System.arraycopy(base.sites, 0, sites, 1, Math.min(length - 1, base.sites.length));
methods = new IMethod[length];
methods[0] = method;
System.arraycopy(base.methods, 0, methods, 1, Math.min(length - 1, base.methods.length));
}
@Override
public String toString() {
StringBuffer str = new StringBuffer("[");
for (int i = 0; i < sites.length; i++)
str.append(" ").append(methods[i].getName()).append("@").append(sites[i].getProgramCounter());
str.append(" ]");
return str.toString();
}
@Override
public int hashCode() {
int code = 1;
for (int i = 0; i < sites.length; i++) {
code *= sites[i].hashCode() * methods[i].hashCode();
}
return code;
}
@Override
public boolean equals(Object o) {
if (o instanceof CallString) {
CallString oc = (CallString) o;
if (oc.sites.length == sites.length) {
for (int i = 0; i < sites.length; i++) {
if (!(sites[i].equals(oc.sites[i]) && methods[i].equals(oc.methods[i]))) {
return false;
}
}
return true;
}
}
return false;
}
}

View File

@ -0,0 +1,46 @@
/*******************************************************************************
* 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.callgraph.propagation.cfa;
import com.ibm.wala.ipa.callgraph.Context;
import com.ibm.wala.ipa.callgraph.ContextItem;
import com.ibm.wala.ipa.callgraph.ContextKey;
public class CallStringContext implements Context {
private final CallString cs;
public CallStringContext(CallString cs) {
this.cs = cs;
}
@Override
public boolean equals(Object o) {
return (o instanceof CallStringContext) && ((CallStringContext) o).cs.equals(cs);
}
@Override
public int hashCode() {
return cs.hashCode();
}
@Override
public String toString() {
return "CallStringContext: " + cs.toString();
}
public ContextItem get(ContextKey name) {
if (CallStringContextSelector.CALL_STRING.equals(name)) {
return cs;
} else {
return null;
}
}
}

View File

@ -22,101 +22,13 @@ import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
public abstract class CallStringContextSelector implements ContextSelector {
private static final ContextKey CALL_STRING = new ContextKey() {
static final ContextKey CALL_STRING = new ContextKey() {
@Override
public String toString() {
return "CALL_STRING_KEY";
}
};
private class CallString implements ContextItem {
private final CallSiteReference sites[];
private final IMethod methods[];
private CallString(CallSiteReference site, IMethod method) {
this.sites = new CallSiteReference[] { site };
this.methods = new IMethod[] { method };
}
private CallString(CallSiteReference site, IMethod method, int length, CallString base) {
sites = new CallSiteReference[length];
sites[0] = site;
System.arraycopy(base.sites, 0, sites, 1, Math.min(length - 1, base.sites.length));
methods = new IMethod[length];
methods[0] = method;
System.arraycopy(base.methods, 0, methods, 1, Math.min(length - 1, base.methods.length));
}
@Override
public String toString() {
StringBuffer str = new StringBuffer("[");
for (int i = 0; i < sites.length; i++)
str.append(" ").append(methods[i].getName()).append("@").append(sites[i].getProgramCounter());
str.append(" ]");
return str.toString();
}
@Override
public int hashCode() {
int code = 1;
for (int i = 0; i < sites.length; i++) {
code *= sites[i].hashCode() * methods[i].hashCode();
}
return code;
}
@Override
public boolean equals(Object o) {
if (o instanceof CallString) {
CallString oc = (CallString) o;
if (oc.sites.length == sites.length) {
for (int i = 0; i < sites.length; i++) {
if (!(sites[i].equals(oc.sites[i]) && methods[i].equals(oc.methods[i]))) {
return false;
}
}
return true;
}
}
return false;
}
}
private class CallStringContext implements Context {
private final CallString cs;
private CallStringContext(CallString cs) {
this.cs = cs;
}
@Override
public boolean equals(Object o) {
return (o instanceof CallStringContext) && ((CallStringContext) o).cs.equals(cs);
}
@Override
public int hashCode() {
return cs.hashCode();
}
@Override
public String toString() {
return "CallStringContext: " + cs.toString();
}
public ContextItem get(ContextKey name) {
if (CALL_STRING.equals(name)) {
return cs;
} else {
return null;
}
}
};
private class CallStringContextPair implements Context {
private final CallString cs;