Made BytecodeClass.computeMethodMap thread-safe

This commit is contained in:
Andreas Sewe 2013-05-07 11:21:37 +02:00 committed by Manu Sridharan
parent d0b5e8ddd2
commit bc2594237b
2 changed files with 29 additions and 31 deletions

View File

@ -78,7 +78,7 @@ public abstract class BytecodeClass<T extends IClassLoader> implements IClass {
*
* TODO: get rid of this for classes (though keep it for interfaces) instead ... use a VMT.
*/
protected Map<Selector, IMethod> methodMap;
protected volatile Map<Selector, IMethod> methodMap;
/**
* A mapping from Selector to IMethod used to cache method lookups from superclasses
@ -385,14 +385,12 @@ public abstract class BytecodeClass<T extends IClassLoader> implements IClass {
* @see com.ibm.wala.classLoader.IClass#getDeclaredMethods()
*/
public Collection<IMethod> getDeclaredMethods() {
if (methodMap == null) {
try {
computeMethodMap();
} catch (InvalidClassFileException e) {
e.printStackTrace();
Assertions.UNREACHABLE();
}
}
return Collections.unmodifiableCollection(methodMap.values());
}
@ -400,14 +398,12 @@ public abstract class BytecodeClass<T extends IClassLoader> implements IClass {
* @see com.ibm.wala.classLoader.IClass#getMethod(com.ibm.wala.types.Selector)
*/
public IMethod getMethod(Selector selector) {
if (methodMap == null) {
try {
computeMethodMap();
} catch (InvalidClassFileException e1) {
e1.printStackTrace();
Assertions.UNREACHABLE();
}
}
// my methods + cached parent stuff
IMethod result = methodMap.get(selector);
@ -554,6 +550,8 @@ public abstract class BytecodeClass<T extends IClassLoader> implements IClass {
* set up the methodMap mapping
*/
protected void computeMethodMap() throws InvalidClassFileException {
if (methodMap == null) {
synchronized (this) {
if (methodMap == null) {
IMethod[] methods = computeDeclaredMethods();
if (methods.length > 5) {
@ -567,5 +565,7 @@ public abstract class BytecodeClass<T extends IClassLoader> implements IClass {
}
}
}
}
}
}

View File

@ -64,14 +64,12 @@ public abstract class JVMClass<T extends IClassLoader> extends BytecodeClass<T>
* @see com.ibm.wala.classLoader.IClass#getClassInitializer()
*/
public IMethod getClassInitializer() {
if (methodMap == null) {
try {
computeMethodMap();
} catch (InvalidClassFileException e) {
e.printStackTrace();
Assertions.UNREACHABLE();
}
}
return methodMap.get(MethodReference.clinitSelector);
}