Browse Source

tested eviction code plugged in. not activated yet in whats in CVS yet though. Enables BcelDelegates/methods/fields to completely unpack what they need from the JavaClass and then discard it.

tags/V1_5_1_final
aclement 18 years ago
parent
commit
ced353c60f

+ 2
- 0
weaver/src/org/aspectj/weaver/JoinPointSignature.java View File

@@ -404,4 +404,6 @@ public class JoinPointSignature implements ResolvedMember {
public ResolvedMember getBackingGenericMember() {
return realMember.getBackingGenericMember();
}

public void evictWeavingState() { realMember.evictWeavingState(); }
}

+ 2
- 0
weaver/src/org/aspectj/weaver/ResolvedMember.java View File

@@ -157,4 +157,6 @@ public interface ResolvedMember extends Member, AnnotatedElement, TypeVariableDe
public void resetKind(Kind newKind);
public void resetModifiers(int newModifiers);
public void resetReturnTypeToObjectArray();
public void evictWeavingState();
}

+ 2
- 0
weaver/src/org/aspectj/weaver/ResolvedMemberImpl.java View File

@@ -926,5 +926,7 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno

// Do generic aspects with ITDs that share type variables with the aspect and the target type and have their own tvars cause this to be messier?
}

public void evictWeavingState() { }
}

+ 57
- 14
weaver/src/org/aspectj/weaver/World.java View File

@@ -84,6 +84,9 @@ public abstract class World implements Dump.INode {
/** When behaving in a Java 5 way autoboxing is considered */
private boolean behaveInJava5Way = false;
/** Determines if this world could be used for multiple compiles */
private boolean incrementalCompileCouldFollow = false;
/** The level of the aspectjrt.jar the code we generate needs to run on */
private String targetAspectjRuntimeLevel = Constants.RUNTIME_LEVEL_DEFAULT;
@@ -94,6 +97,12 @@ public abstract class World implements Dump.INode {
private Properties extraConfiguration = null;
private boolean checkedAdvancedConfiguration=false;
// Xset'table options
private boolean fastDelegateSupportEnabled = isASMAround;
private boolean runMinimalMemory = true;

// Records whether ASM is around ... so we might use it for delegates
protected static boolean isASMAround;
@@ -706,7 +715,8 @@ public abstract class World implements Dump.INode {
return extraConfiguration;
}
public final static String xsetCAPTURE_ALL_CONTEXT = "captureAllContext"; // default false
public final static String xsetACTIVATE_LIGHTWEIGHT_DELEGATES = "activateLightweightDelegates"; // default true
public final static String xsetRUN_MINIMAL_MEMORY ="runMinimalMemory"; // default true
public boolean isInJava5Mode() {
return behaveInJava5Way;
@@ -758,7 +768,7 @@ public abstract class World implements Dump.INode {
public static int policy = USE_SOFT_REFS;

// Map of types that never get thrown away
private Map tMap = new HashMap();
private Map /* String -> ResolvedType */ tMap = new HashMap();
// Map of types that may be ejected from the cache if we need space
private Map expendableMap = new WeakHashMap();
@@ -853,7 +863,10 @@ public abstract class World implements Dump.INode {
while (rq.poll()!=null) collectedTypes++;
}
/** Lookup a type by its signature */
/**
* Lookup a type by its signature, always look
* in the real map before the expendable map
*/
public ResolvedType get(String key) {
checkq();
ResolvedType ret = (ResolvedType) tMap.get(key);
@@ -882,14 +895,11 @@ public abstract class World implements Dump.INode {
if (policy==USE_WEAK_REFS) {
WeakReference wref = (WeakReference)expendableMap.remove(key);
if (wref!=null) ret = (ResolvedType)wref.get();
return ret;
} else if (policy==USE_SOFT_REFS) {
SoftReference wref = (SoftReference)expendableMap.remove(key);
if (wref!=null) ret = (ResolvedType)wref.get();
return ret;
} else {
ret = (ResolvedType)expendableMap.remove(key);
return ret;
}
}
return ret;
@@ -1068,15 +1078,48 @@ public abstract class World implements Dump.INode {
public boolean isAddSerialVerUID() { return addSerialVerUID;}
public void flush() {
// System.err.println("BEFORE FLUSHING");
// System.err.println(typeMap.toString());
typeMap.expendableMap.clear();
// System.err.println("AFTER FLUSHING");
// System.err.println(typeMap.toString());
// System.gc();
System.gc();
}

// ---
public void ensureAdvancedConfigurationProcessed() {
// Check *once* whether the user has switched asm support off
if (!checkedAdvancedConfiguration) {
Properties p = getExtraConfiguration();
if (p!=null) {
if (isASMAround) { // dont bother if its not...
String s = p.getProperty(xsetACTIVATE_LIGHTWEIGHT_DELEGATES,"true");
fastDelegateSupportEnabled = s.equalsIgnoreCase("true");
if (!fastDelegateSupportEnabled)
getMessageHandler().handleMessage(MessageUtil.info("[activateLightweightDelegates=false] Disabling optimization to use lightweight delegates for non-woven types"));
}
// wonder if this should be based on whether an incremental build can follow?
String s = p.getProperty(xsetRUN_MINIMAL_MEMORY,"false");
runMinimalMemory = s.equalsIgnoreCase("true");
// if (runMinimalMemory)
// getMessageHandler().handleMessage(MessageUtil.info("[runMinimalMemory=true] Optimizing bcel processing (and cost of performance) to use less memory"));
}
checkedAdvancedConfiguration=true;
}
}
public boolean isRunMinimalMemory() {
ensureAdvancedConfigurationProcessed();
return runMinimalMemory;
}
public void setFastDelegateSupport(boolean b) {
if (b && !isASMAround) {
throw new BCException("Unable to activate fast delegate support, ASM classes cannot be found");
}
fastDelegateSupportEnabled = b;
}
public boolean isFastDelegateSupportEnabled() {
ensureAdvancedConfigurationProcessed();
return fastDelegateSupportEnabled;
}
public void setIncrementalCompileCouldFollow(boolean b) {incrementalCompileCouldFollow = b;}
public boolean couldIncrementalCompileFollow() {return incrementalCompileCouldFollow;}
}

+ 28
- 8
weaver/src/org/aspectj/weaver/bcel/BcelField.java View File

@@ -13,6 +13,7 @@

package org.aspectj.weaver.bcel;

import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
@@ -122,14 +123,20 @@ final class BcelField extends ResolvedMemberImpl {
private void ensureAnnotationTypesRetrieved() {
if (annotationTypes == null) {
Annotation annos[] = field.getAnnotations();
annotationTypes = new HashSet();
annotations = new AnnotationX[annos.length];
for (int i = 0; i < annos.length; i++) {
Annotation annotation = annos[i];
ResolvedType rtx = world.resolve(UnresolvedType.forName(annotation.getTypeName()));
annotationTypes.add(rtx);
annotations[i] = new AnnotationX(annotation,world);
}
if (annos==null || annos.length==0) {
annotationTypes = Collections.EMPTY_SET;
annotations = AnnotationX.NONE;
} else {
annotationTypes = new HashSet();
annotations = new AnnotationX[annos.length];
for (int i = 0; i < annos.length; i++) {
Annotation annotation = annos[i];
System.err.println(annotation);
ResolvedType rtx = world.resolve(UnresolvedType.forName(annotation.getTypeName()));
annotationTypes.add(rtx);
annotations[i] = new AnnotationX(annotation,world);
}
}
}
}
@@ -142,6 +149,9 @@ final class BcelField extends ResolvedMemberImpl {
ret[len] = annotation;
annotations = ret;
if (annotationTypes==Collections.EMPTY_SET) {
annotationTypes = new HashSet();
}
// Add it to the set of annotation types
annotationTypes.add(UnresolvedType.forName(annotation.getTypeName()).resolve(world));
// FIXME asc this call here suggests we are managing the annotations at
@@ -198,4 +208,14 @@ final class BcelField extends ResolvedMemberImpl {
genericFieldType = getReturnType();
}
}
public void evictWeavingState() {
if (field != null) {
unpackGenericSignature();
unpackAttributes(world);
ensureAnnotationTypesRetrieved();
// this.sourceContext = SourceContextImpl.UNKNOWN_SOURCE_CONTEXT;
field = null;
}
}
}

+ 23
- 10
weaver/src/org/aspectj/weaver/bcel/BcelMethod.java View File

@@ -57,6 +57,14 @@ final class BcelMethod extends ResolvedMemberImpl {
private AjAttribute.MethodDeclarationLineNumberAttribute declarationLineNumber;
private World world;
private BcelObjectType bcelObjectType;
private boolean parameterNamesInitialized = false;

private boolean canBeParameterized = false;
// genericized version of return and parameter types
private boolean unpackedGenericSignature = false;
private UnresolvedType genericReturnType = null;
private UnresolvedType[] genericParameterTypes = null;

BcelMethod(BcelObjectType declaringType, Method method) {
super(
@@ -91,7 +99,6 @@ final class BcelMethod extends ResolvedMemberImpl {
return super.getParameterNames();
}

private boolean parameterNamesInitialized = false;
public void determineParameterNames() {
if (parameterNamesInitialized) return;
@@ -264,6 +271,7 @@ final class BcelMethod extends ResolvedMemberImpl {
}
private void ensureAnnotationTypesRetrieved() {
if (method == null) return; // must be ok, we have evicted it
if (annotationTypes == null || method.getAnnotations().length!=annotations.length) { // sometimes the list changes underneath us!
Annotation annos[] = method.getAnnotations();
annotationTypes = new HashSet();
@@ -274,11 +282,10 @@ final class BcelMethod extends ResolvedMemberImpl {
annotationTypes.add(rtx);
annotations[i] = new AnnotationX(annotation,world);
}
}
}
}

private boolean canBeParameterized = false;
/**
* A method can be parameterized if it has one or more generic
* parameters. A generic parameter (type variable parameter) is
@@ -289,10 +296,6 @@ final class BcelMethod extends ResolvedMemberImpl {
return canBeParameterized;
}
// genericized version of return and parameter types
private boolean unpackedGenericSignature = false;
private UnresolvedType genericReturnType = null;
private UnresolvedType[] genericParameterTypes = null;
public UnresolvedType[] getGenericParameterTypes() {
unpackGenericSignature();
@@ -309,16 +312,15 @@ final class BcelMethod extends ResolvedMemberImpl {
private void unpackGenericSignature() {
if (unpackedGenericSignature) return;
unpackedGenericSignature = true;
if (!world.isInJava5Mode()) {
this.genericReturnType = getReturnType();
this.genericParameterTypes = getParameterTypes();
return;
}
// ok, we have work to do...
unpackedGenericSignature = true;
String gSig = method.getGenericSignature();
if (gSig != null) {
Signature.MethodTypeSignature mSig = new GenericSignatureParser().parseAsMethodSignature(method.getGenericSignature());
Signature.MethodTypeSignature mSig = new GenericSignatureParser().parseAsMethodSignature(gSig);//method.getGenericSignature());
if (mSig.formalTypeParameters.length > 0) {
// generic method declaration
canBeParameterized = true;
@@ -382,4 +384,15 @@ final class BcelMethod extends ResolvedMemberImpl {
genericParameterTypes = getParameterTypes();
}
}
public void evictWeavingState() {
if (method != null) {
unpackGenericSignature();
unpackJavaAttributes();
ensureAnnotationTypesRetrieved();
determineParameterNames();
// this.sourceContext = SourceContextImpl.UNKNOWN_SOURCE_CONTEXT;
method = null;
}
}
}

+ 320
- 266
weaver/src/org/aspectj/weaver/bcel/BcelObjectType.java View File

@@ -1,5 +1,5 @@
/* *******************************************************************
* Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
* Copyright (c) 2002 Contributors
* All rights reserved.
* This program and the accompanying materials are made available
* under the terms of the Common Public License v1.0
@@ -8,9 +8,9 @@
*
* Contributors:
* PARC initial implementation
* RonBodkin/AndyClement optimizations for memory consumption/speed
* ******************************************************************/


package org.aspectj.weaver.bcel;

import java.io.PrintStream;
@@ -26,10 +26,12 @@ import org.aspectj.apache.bcel.classfile.Field;
import org.aspectj.apache.bcel.classfile.JavaClass;
import org.aspectj.apache.bcel.classfile.Method;
import org.aspectj.apache.bcel.classfile.Signature;
import org.aspectj.apache.bcel.classfile.Signature.ClassSignature;
import org.aspectj.apache.bcel.classfile.annotation.Annotation;
import org.aspectj.apache.bcel.classfile.annotation.ArrayElementValue;
import org.aspectj.apache.bcel.classfile.annotation.ElementNameValuePair;
import org.aspectj.apache.bcel.classfile.annotation.ElementValue;
import org.aspectj.bridge.IMessageHandler;
import org.aspectj.weaver.AbstractReferenceTypeDelegate;
import org.aspectj.weaver.AjAttribute;
import org.aspectj.weaver.AjcMemberMaker;
@@ -45,18 +47,18 @@ import org.aspectj.weaver.SourceContextImpl;
import org.aspectj.weaver.TypeVariable;
import org.aspectj.weaver.UnresolvedType;
import org.aspectj.weaver.WeaverStateInfo;
import org.aspectj.weaver.World;
import org.aspectj.weaver.bcel.BcelGenericSignatureToTypeXConverter.GenericSignatureFormatException;
import org.aspectj.weaver.patterns.PerClause;



// ??? exposed for testing
public class BcelObjectType extends AbstractReferenceTypeDelegate {
private JavaClass javaClass;
private boolean isObject = false; // set upon construction
public JavaClass javaClass;
private LazyClassGen lazyClassGen = null; // set lazily if it's an aspect

// lazy, for no particular reason I can discern
// Java related stuff
private int modifiers;
private String className;
private String superclassName;
private ResolvedType[] interfaces = null;
private ResolvedType superClass = null;
private ResolvedMember[] fields = null;
@@ -64,69 +66,68 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
private ResolvedType[] annotationTypes = null;
private AnnotationX[] annotations = null;
private TypeVariable[] typeVars = null;
private String retentionPolicy;
private AnnotationTargetKind[] annotationTargetKinds;

// track unpackAttribute. In some case (per clause inheritance) we encounter
// unpacked state when calling getPerClause
// this whole thing would require more clean up (AV)
private boolean isUnpacked = false;

// strangely non-lazy
// Aspect related stuff (pointcuts *could* be in a java class)
private AjAttribute.WeaverVersionInfo wvInfo = AjAttribute.WeaverVersionInfo.UNKNOWN;
private ResolvedPointcutDefinition[] pointcuts = null;
private PerClause perClause = null;
private ResolvedMember[] privilegedAccess = null;
private WeaverStateInfo weaverState = null;
private AjAttribute.WeaverVersionInfo wvInfo = AjAttribute.WeaverVersionInfo.UNKNOWN;
private PerClause perClause = null;
private List typeMungers = Collections.EMPTY_LIST;
private List declares = Collections.EMPTY_LIST;
private ResolvedMember[] privilegedAccess = null;

private boolean discoveredWhetherAnnotationStyle = false;
private Signature.FormalTypeParameter[] formalsForResolution = null;
private ClassSignature cachedGenericClassTypeSignature;
private String declaredSignature = null;

private boolean hasBeenWoven = false;
private boolean isGenericType = false;
private boolean isInterface;
private boolean isEnum;
private boolean isAnnotation;
private boolean isAnonymous;
private boolean isNested;
private boolean isObject = false; // set upon construction
private boolean isAnnotationStyleAspect = false;// set upon construction
private boolean isCodeStyleAspect = false; // not redundant with field above!

// TODO asc need soon but not just yet...
private boolean haveLookedForDeclaredSignature = false;
private String declaredSignature = null;
private boolean isGenericType = false;
private boolean discoveredRetentionPolicy = false;
private String retentionPolicy;
private boolean discoveredAnnotationTargetKinds = false;
private AnnotationTargetKind[] annotationTargetKinds;
/**
private int bitflag = 0x0000;
// discovery bits
private static final int DISCOVERED_ANNOTATION_RETENTION_POLICY = 0x0001;
private static final int UNPACKED_GENERIC_SIGNATURE = 0x0002;
private static final int UNPACKED_AJATTRIBUTES = 0x0004; // see note(1) below
private static final int DISCOVERED_ANNOTATION_TARGET_KINDS = 0x0008;
private static final int DISCOVERED_DECLARED_SIGNATURE = 0x0010;
private static final int DISCOVERED_WHETHER_ANNOTATION_STYLE = 0x0020;
private static final int DAMAGED = 0x0040; // see note(2) below
/*
* Notes:
* note(1):
* in some cases (perclause inheritance) we encounter unpacked state when calling getPerClause
*
* note(2):
* A BcelObjectType is 'damaged' if it has been modified from what was original constructed from
* the bytecode. This currently happens if the parents are modified or an annotation is added -
* ideally BcelObjectType should be immutable but that's a bigger piece of work!!!!!!!!!! XXX
* ideally BcelObjectType should be immutable but that's a bigger piece of work. XXX
*/
private boolean damaged = false;

public Collection getTypeMungers() {
return typeMungers;
}

public Collection getDeclares() {
return declares;
}
public Collection getPrivilegedAccesses() {
if (privilegedAccess == null) return Collections.EMPTY_LIST;
return Arrays.asList(privilegedAccess);
}
// ------------------ construction and initialization
// IMPORTANT! THIS DOESN'T do real work on the java class, just stores it away.
BcelObjectType(ReferenceType resolvedTypeX, JavaClass javaClass, boolean exposedToWeaver) {
super(resolvedTypeX, exposedToWeaver);
this.javaClass = javaClass;
initializeFromJavaclass();

//ATAJ: set the delegate right now for @AJ pointcut, else it is done too late to lookup
// @AJ pc refs annotation in class hierarchy
resolvedTypeX.setDelegate(this);

// if (resolvedTypeX.getSourceContext() == null) {
// resolvedTypeX.
if (resolvedTypeX.getSourceContext()==SourceContextImpl.UNKNOWN_SOURCE_CONTEXT) {
setSourceContext(new SourceContextImpl(this));
}
@@ -134,57 +135,53 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
// this should only ever be java.lang.Object which is
// the only class in Java-1.4 with no superclasses
isObject = (javaClass.getSuperclassNameIndex() == 0);
unpackAspectAttributes();
ensureAspectJAttributesUnpacked();
setSourcefilename(javaClass.getSourceFileName());
}
// repeat initialization
public void setJavaClass(JavaClass newclass) {
this.javaClass = newclass;
resetState();
initializeFromJavaclass();
}
private void initializeFromJavaclass() {
isInterface = javaClass.isInterface();
isEnum = javaClass.isEnum();
isAnnotation = javaClass.isAnnotation();
isAnonymous = javaClass.isAnonymous();
isNested = javaClass.isNested();
modifiers = javaClass.getAccessFlags();
superclassName = javaClass.getSuperclassName();
className = javaClass.getClassName();
cachedGenericClassTypeSignature = javaClass.getGenericClassTypeSignature();
}


public TypeVariable[] getTypeVariables() {
if (!isGeneric()) return new TypeVariable[0];
if (typeVars == null) {
Signature.ClassSignature classSig = javaClass.getGenericClassTypeSignature();
typeVars = new TypeVariable[classSig.formalTypeParameters.length];
for (int i = 0; i < typeVars.length; i++) {
Signature.FormalTypeParameter ftp = classSig.formalTypeParameters[i];
try {
typeVars[i] = BcelGenericSignatureToTypeXConverter.formalTypeParameter2TypeVariable(
ftp,
classSig.formalTypeParameters,
getResolvedTypeX().getWorld());
} catch (GenericSignatureFormatException e) {
// this is a development bug, so fail fast with good info
throw new IllegalStateException(
"While getting the type variables for type " + this.toString()
+ " with generic signature " + classSig +
" the following error condition was detected: " + e.getMessage());
}
}
}
return typeVars;
}
// --- getters
// Java related
public boolean isInterface() {return isInterface;}
public boolean isEnum() {return isEnum;}
public boolean isAnnotation() {return isAnnotation;}
public boolean isAnonymous() {return isAnonymous;}
public boolean isNested() {return isNested;}
public int getModifiers() {return modifiers;}
public int getModifiers() {
return javaClass.getAccessFlags();
}

/**
* Must take into account generic signature
*/
public ResolvedType getSuperclass() {
if (isObject) return null;
unpackGenericSignature();
ensureGenericSignatureUnpacked();
if (superClass == null) {
superClass = getResolvedTypeX().getWorld().resolve(UnresolvedType.forName(javaClass.getSuperclassName()));
superClass = getResolvedTypeX().getWorld().resolve(UnresolvedType.forName(superclassName));
}
return superClass;
}
@@ -195,7 +192,7 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
* erasure when the class was originally compiled.
*/
public ResolvedType[] getDeclaredInterfaces() {
unpackGenericSignature();
ensureGenericSignatureUnpacked();
if (interfaces == null) {
String[] ifaceNames = javaClass.getInterfaceNames();
interfaces = new ResolvedType[ifaceNames.length];
@@ -207,47 +204,69 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
}
public ResolvedMember[] getDeclaredMethods() {
unpackGenericSignature();
ensureGenericSignatureUnpacked();
if (methods == null) {
Method[] ms = javaClass.getMethods();
ResolvedMember[] ret = new ResolvedMember[ms.length];
methods = new ResolvedMember[ms.length];
for (int i = ms.length - 1; i >= 0; i--) {
ret[i] = new BcelMethod(this, ms[i]);
methods[i] = new BcelMethod(this, ms[i]);
}
methods = ret;
}
return methods;
}
public ResolvedMember[] getDeclaredFields() {
unpackGenericSignature();
ensureGenericSignatureUnpacked();
if (fields == null) {
Field[] fs = javaClass.getFields();
ResolvedMember[] ret = new ResolvedMember[fs.length];
fields = new ResolvedMember[fs.length];
for (int i = 0, len = fs.length; i < len; i++) {
ret[i] = new BcelField(this, fs[i]);
fields[i] = new BcelField(this, fs[i]);
}
fields = ret;
}
return fields;
}

// ----
// fun based on the aj attributes
public TypeVariable[] getTypeVariables() {
if (!isGeneric()) return TypeVariable.NONE;
if (typeVars == null) {
Signature.ClassSignature classSig = cachedGenericClassTypeSignature;//javaClass.getGenericClassTypeSignature();
typeVars = new TypeVariable[classSig.formalTypeParameters.length];
for (int i = 0; i < typeVars.length; i++) {
Signature.FormalTypeParameter ftp = classSig.formalTypeParameters[i];
try {
typeVars[i] = BcelGenericSignatureToTypeXConverter.formalTypeParameter2TypeVariable(
ftp,
classSig.formalTypeParameters,
getResolvedTypeX().getWorld());
} catch (GenericSignatureFormatException e) {
// this is a development bug, so fail fast with good info
throw new IllegalStateException(
"While getting the type variables for type " + this.toString()
+ " with generic signature " + classSig +
" the following error condition was detected: " + e.getMessage());
}
}
}
return typeVars;
}

public ResolvedMember[] getDeclaredPointcuts() {
// Aspect related
public Collection getTypeMungers() {return typeMungers;}
public Collection getDeclares() {return declares;}
public Collection getPrivilegedAccesses() {
if (privilegedAccess == null) return Collections.EMPTY_LIST;
return Arrays.asList(privilegedAccess);
}

public ResolvedMember[] getDeclaredPointcuts() {
return pointcuts;
}

//??? method only used for testing
public void addPointcutDefinition(ResolvedPointcutDefinition d) {
damaged = true;
int len = pointcuts.length;
ResolvedPointcutDefinition[] ret = new ResolvedPointcutDefinition[len+1];
System.arraycopy(pointcuts, 0, ret, 0, len);
ret[len] = d;
pointcuts = ret;
}

public boolean isAspect() {
return perClause != null;
@@ -260,22 +279,27 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
* @return true for @AJ aspect
*/
public boolean isAnnotationStyleAspect() {
if (!discoveredWhetherAnnotationStyle) {
discoveredWhetherAnnotationStyle = true;
if ((bitflag&DISCOVERED_WHETHER_ANNOTATION_STYLE)==0) {
bitflag|=DISCOVERED_WHETHER_ANNOTATION_STYLE;
isAnnotationStyleAspect = !isCodeStyleAspect && hasAnnotation(AjcMemberMaker.ASPECT_ANNOTATION);
}
return isAnnotationStyleAspect;
}

private void unpackAspectAttributes() {
isUnpacked = true;
/**
* Process any org.aspectj.weaver attributes stored against the class.
*/
private void ensureAspectJAttributesUnpacked() {
if ((bitflag&UNPACKED_AJATTRIBUTES)!=0) return;
bitflag|=UNPACKED_AJATTRIBUTES;
IMessageHandler msgHandler = getResolvedTypeX().getWorld().getMessageHandler();
// Pass in empty list that can store things for readAj5 to process
List l = BcelAttributes.readAjAttributes(className,javaClass.getAttributes(), getResolvedTypeX().getSourceContext(),msgHandler,AjAttribute.WeaverVersionInfo.UNKNOWN);
List pointcuts = new ArrayList();
typeMungers = new ArrayList();
declares = new ArrayList();
// Pass in empty list that can store things for readAj5 to process
List l = BcelAttributes.readAjAttributes(javaClass.getClassName(),javaClass.getAttributes(), getResolvedTypeX().getSourceContext(),getResolvedTypeX().getWorld().getMessageHandler(),AjAttribute.WeaverVersionInfo.UNKNOWN);
processAttributes(l,pointcuts,false);
l = AtAjAttributes.readAj5ClassAttributes(javaClass, getResolvedTypeX(), getResolvedTypeX().getSourceContext(), getResolvedTypeX().getWorld().getMessageHandler(),isCodeStyleAspect);
l = AtAjAttributes.readAj5ClassAttributes(javaClass, getResolvedTypeX(), getResolvedTypeX().getSourceContext(), msgHandler,isCodeStyleAspect);
AjAttribute.Aspect deferredAspectAttribute = processAttributes(l,pointcuts,true);
this.pointcuts = (ResolvedPointcutDefinition[])
@@ -326,21 +350,29 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
}

public PerClause getPerClause() {
if (!isUnpacked) {
unpackAspectAttributes();
}
ensureAspectJAttributesUnpacked();
return perClause;
}
JavaClass getJavaClass() {
public JavaClass getJavaClass() {
return javaClass;
}
public void ensureDelegateConsistent() {
if (damaged) {resetState();damaged=false;}
if ((bitflag&DAMAGED)!=0) {resetState();}
}
public void resetState() {
if (javaClass == null) {
// we might store the classname and allow reloading?
// At this point we are relying on the world to not evict if it might want to reweave multiple times
throw new BCException("can't weave evicted type");
}
bitflag=0x0000;
this.annotationTypes = null;
this.annotations = null;
this.interfaces = null;
this.superClass = null;
this.fields = null;
@@ -349,13 +381,11 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
this.perClause = null;
this.weaverState = null;
this.lazyClassGen = null;
this.annotations = null;
this.annotationTypes = null;
hasBeenWoven=false;
isObject = (javaClass.getSuperclassNameIndex() == 0);
unpackAspectAttributes();
discoveredWhetherAnnotationStyle = false;
isAnnotationStyleAspect=false;
ensureAspectJAttributesUnpacked();
}
public void finishedWith() {
@@ -382,12 +412,8 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
}
public void printWackyStuff(PrintStream out) {
if (typeMungers.size() > 0) {
out.println(" TypeMungers: " + typeMungers);
}
if (declares.size() > 0) {
out.println(" declares: " + declares);
}
if (typeMungers.size() > 0) out.println(" TypeMungers: " + typeMungers);
if (declares.size() > 0) out.println(" declares: " + declares);
}
/**
@@ -401,7 +427,7 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
//System.err.println("creating lazy class gen for: " + this);
ret = new LazyClassGen(this);
//ret.print(System.err);
//System.err.println("made LCG from : " + this.getJavaClass().getSuperclassName() );
//System.err.println("made LCG from : " + this.getJavaClass().getSuperclassName );
if (isAspect()) {
lazyClassGen = ret;
}
@@ -409,36 +435,64 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
return ret;
}

public boolean isInterface() {
return javaClass.isInterface();
}
public boolean isEnum() {
return javaClass.isEnum();
public boolean isSynthetic() {
return getResolvedTypeX().isSynthetic();
}
public boolean isAnnotation() {
return javaClass.isAnnotation();
public AjAttribute.WeaverVersionInfo getWeaverVersionAttribute() {
return wvInfo;
}
public boolean isAnonymous() {
return javaClass.isAnonymous();

public void addParent(ResolvedType newParent) {
bitflag|=DAMAGED;
if (newParent.isClass()) {
superClass = newParent;
} else {
ResolvedType[] oldInterfaceNames = getDeclaredInterfaces();
int len = oldInterfaceNames.length;
ResolvedType[] newInterfaceNames = new ResolvedType[len+1];
System.arraycopy(oldInterfaceNames, 0, newInterfaceNames, 0, len);
newInterfaceNames[len] = newParent;
interfaces = newInterfaceNames;
}
//System.err.println("javaClass: " + Arrays.asList(javaClass.getInterfaceNames()) + " super " + superclassName);
//if (lazyClassGen != null) lazyClassGen.print();
}
public boolean isNested() {
return javaClass.isNested();



// -- annotation related

public ResolvedType[] getAnnotationTypes() {
ensureAnnotationsUnpacked();
return annotationTypes;
}

public AnnotationX[] getAnnotations() {
ensureAnnotationsUnpacked();
return annotations;
}

public boolean hasAnnotation(UnresolvedType ofType) {
ensureAnnotationsUnpacked();
for (int i = 0; i < annotationTypes.length; i++) {
ResolvedType ax = annotationTypes[i];
if (ax.equals(ofType)) return true;
}
return false;
}
// evil mutator - adding state not stored in the java class
public void addAnnotation(AnnotationX annotation) {
damaged = true;
// Add it to the set of annotations
bitflag|=DAMAGED;
int len = annotations.length;
AnnotationX[] ret = new AnnotationX[len+1];
System.arraycopy(annotations, 0, ret, 0, len);
ret[len] = annotation;
annotations = ret;
// Add it to the set of annotation types
len = annotationTypes.length;
ResolvedType[] ret2 = new ResolvedType[len+1];
System.arraycopy(annotationTypes,0,ret2,0,len);
@@ -450,26 +504,25 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
return (getRetentionPolicy()==null?false:getRetentionPolicy().equals("RUNTIME"));
}
public String getRetentionPolicy() {
if (discoveredRetentionPolicy) return retentionPolicy;
discoveredRetentionPolicy=true;
retentionPolicy=null; // null means we have no idea
if (isAnnotation()) {
Annotation[] annotationsOnThisType = javaClass.getAnnotations();
for (int i = 0; i < annotationsOnThisType.length; i++) {
Annotation a = annotationsOnThisType[i];
if (a.getTypeName().equals(UnresolvedType.AT_RETENTION.getName())) {
List values = a.getValues();
boolean isRuntime = false;
for (Iterator it = values.iterator(); it.hasNext();) {
ElementNameValuePair element = (ElementNameValuePair) it.next();
ElementValue v = element.getValue();
retentionPolicy = v.stringifyValue();
return retentionPolicy;
}
}
}
if ((bitflag&DISCOVERED_ANNOTATION_RETENTION_POLICY)==0) {
bitflag|=DISCOVERED_ANNOTATION_RETENTION_POLICY;
retentionPolicy=null; // null means we have no idea
if (isAnnotation()) {
ensureAnnotationsUnpacked();
for (int i = annotations.length-1; i>=0; i--) {
AnnotationX ax = annotations[i];
if (ax.getTypeName().equals(UnresolvedType.AT_RETENTION.getName())) {
List values = ax.getBcelAnnotation().getValues();
for (Iterator it = values.iterator(); it.hasNext();) {
ElementNameValuePair element = (ElementNameValuePair) it.next();
ElementValue v = element.getValue();
retentionPolicy = v.stringifyValue();
return retentionPolicy;
}
}
}
}
}
return retentionPolicy;
}
@@ -486,8 +539,8 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
}
public AnnotationTargetKind[] getAnnotationTargetKinds() {
if (discoveredAnnotationTargetKinds) return annotationTargetKinds;
discoveredAnnotationTargetKinds = true;
if ((bitflag&DISCOVERED_ANNOTATION_TARGET_KINDS)!=0) return annotationTargetKinds;
bitflag|=DISCOVERED_ANNOTATION_TARGET_KINDS;
annotationTargetKinds = null; // null means we have no idea or the @Target annotation hasn't been used
List targetKinds = new ArrayList();
if (isAnnotation()) {
@@ -499,26 +552,15 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
ElementValue[] evs = arrayValue.getElementValuesArray();
if (evs!=null) {
for (int j = 0; j < evs.length; j++) {
ElementValue v = evs[j];
String targetKind = v.stringifyValue();
if (targetKind.equals("ANNOTATION_TYPE")) {
targetKinds.add(AnnotationTargetKind.ANNOTATION_TYPE);
} else if (targetKind.equals("CONSTRUCTOR")) {
targetKinds.add(AnnotationTargetKind.CONSTRUCTOR);
} else if (targetKind.equals("FIELD")) {
targetKinds.add(AnnotationTargetKind.FIELD);
} else if (targetKind.equals("LOCAL_VARIABLE")) {
targetKinds.add(AnnotationTargetKind.LOCAL_VARIABLE);
} else if (targetKind.equals("METHOD")) {
targetKinds.add(AnnotationTargetKind.METHOD);
} else if (targetKind.equals("PACKAGE")) {
targetKinds.add(AnnotationTargetKind.PACKAGE);
} else if (targetKind.equals("PARAMETER")) {
targetKinds.add(AnnotationTargetKind.PARAMETER);
} else if (targetKind.equals("TYPE")) {
targetKinds.add(AnnotationTargetKind.TYPE);
}
String targetKind = evs[j].stringifyValue();
if (targetKind.equals("ANNOTATION_TYPE")) { targetKinds.add(AnnotationTargetKind.ANNOTATION_TYPE);
} else if (targetKind.equals("CONSTRUCTOR")) { targetKinds.add(AnnotationTargetKind.CONSTRUCTOR);
} else if (targetKind.equals("FIELD")) { targetKinds.add(AnnotationTargetKind.FIELD);
} else if (targetKind.equals("LOCAL_VARIABLE")) { targetKinds.add(AnnotationTargetKind.LOCAL_VARIABLE);
} else if (targetKind.equals("METHOD")) { targetKinds.add(AnnotationTargetKind.METHOD);
} else if (targetKind.equals("PACKAGE")) { targetKinds.add(AnnotationTargetKind.PACKAGE);
} else if (targetKind.equals("PARAMETER")) { targetKinds.add(AnnotationTargetKind.PARAMETER);
} else if (targetKind.equals("TYPE")) { targetKinds.add(AnnotationTargetKind.TYPE);}
}
}
}
@@ -531,96 +573,44 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
return annotationTargetKinds;
}
public boolean isSynthetic() {
return getResolvedTypeX().isSynthetic();
}

public AjAttribute.WeaverVersionInfo getWeaverVersionAttribute() {
return wvInfo;
}

public void addParent(ResolvedType newParent) {
damaged = true;
if (newParent.isClass()) {
superClass = newParent;
} else {
ResolvedType[] oldInterfaceNames = getDeclaredInterfaces();
int len = oldInterfaceNames.length;
ResolvedType[] newInterfaceNames = new ResolvedType[len+1];
System.arraycopy(oldInterfaceNames, 0, newInterfaceNames, 0, len);
newInterfaceNames[len] = newParent;
interfaces = newInterfaceNames;
}
//System.err.println("javaClass: " + Arrays.asList(javaClass.getInterfaceNames()) + " super " + javaClass.getSuperclassName());
//if (lazyClassGen != null) lazyClassGen.print();
}



public boolean hasAnnotation(UnresolvedType ofType) {
ensureAnnotationTypesRetrieved();
for (int i = 0; i < annotationTypes.length; i++) {
ResolvedType annX = annotationTypes[i];
if (annX.equals(ofType)) return true;
}
return false;
}
// --- unpacking methods
private void ensureAnnotationTypesRetrieved() {
private void ensureAnnotationsUnpacked() {
if (annotationTypes == null) {
Annotation annos[] = javaClass.getAnnotations();
annotationTypes = new ResolvedType[annos.length];
annotations = new AnnotationX[annos.length];
for (int i = 0; i < annos.length; i++) {
Annotation annotation = annos[i];
ResolvedType rtx = getResolvedTypeX().getWorld().resolve(UnresolvedType.forName(annotation.getTypeName()));
annotationTypes[i] = rtx;
annotations[i] = new AnnotationX(annotation,getResolvedTypeX().getWorld());
}
if (annos==null || annos.length==0) {
annotationTypes = ResolvedType.NONE;
annotations = AnnotationX.NONE;
} else {
World w = getResolvedTypeX().getWorld();
annotationTypes = new ResolvedType[annos.length];
annotations = new AnnotationX[annos.length];
for (int i = 0; i < annos.length; i++) {
Annotation annotation = annos[i];
annotationTypes[i] = w.resolve(UnresolvedType.forName(annotation.getTypeName()));
annotations[i] = new AnnotationX(annotation,w);
}
}
}
}
public ResolvedType[] getAnnotationTypes() {
ensureAnnotationTypesRetrieved();
return annotationTypes;
}
/**
* Releases annotations wrapped in an annotationX
*/
public AnnotationX[] getAnnotations() {
ensureAnnotationTypesRetrieved();
return annotations;
}
// ---


public String getDeclaredGenericSignature() {
if (!haveLookedForDeclaredSignature) {
haveLookedForDeclaredSignature = true;
Attribute[] as = javaClass.getAttributes();
for (int i = 0; i < as.length && declaredSignature==null; i++) {
Attribute attribute = as[i];
if (attribute instanceof Signature) declaredSignature = ((Signature)attribute).getSignature();
}
if (declaredSignature!=null) isGenericType= (declaredSignature.charAt(0)=='<');
}
ensureGenericInfoProcessed();
return declaredSignature;
}
Signature.ClassSignature getGenericClassTypeSignature() {
return javaClass.getGenericClassTypeSignature();
return cachedGenericClassTypeSignature;
}
private boolean genericSignatureUnpacked = false;
private Signature.FormalTypeParameter[] formalsForResolution = null;
private void unpackGenericSignature() {
if (genericSignatureUnpacked) return;
if (!getResolvedTypeX().getWorld().isInJava5Mode()) {
return;
}
genericSignatureUnpacked = true;
private void ensureGenericSignatureUnpacked() {
if ((bitflag&UNPACKED_GENERIC_SIGNATURE)!=0) return;
bitflag|=UNPACKED_GENERIC_SIGNATURE;
if (!getResolvedTypeX().getWorld().isInJava5Mode()) return;
Signature.ClassSignature cSig = getGenericClassTypeSignature();
if (cSig != null) {
formalsForResolution = cSig.formalTypeParameters;
@@ -647,8 +637,8 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
} catch (GenericSignatureFormatException e) {
// development bug, fail fast with good info
throw new IllegalStateException(
"While determing the generic superclass of " + this.javaClass.getClassName()
+ " with generic signature " + this.javaClass.getGenericSignature() + " the following error was detected: "
"While determining the generic superclass of " + this.className
+ " with generic signature " + getDeclaredGenericSignature()+ " the following error was detected: "
+ e.getMessage());
}
this.interfaces = new ResolvedType[cSig.superInterfaceSignatures.length];
@@ -662,8 +652,8 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
} catch (GenericSignatureFormatException e) {
// development bug, fail fast with good info
throw new IllegalStateException(
"While determing the generic superinterfaces of " + this.javaClass.getClassName()
+ " with generic signature " + this.javaClass.getGenericSignature() + " the following error was detected: "
"While determing the generic superinterfaces of " + this.className
+ " with generic signature " + getDeclaredGenericSignature() +" the following error was detected: "
+ e.getMessage());
}
}
@@ -678,7 +668,7 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
}
public Signature.FormalTypeParameter[] getAllFormals() {
unpackGenericSignature();
ensureGenericSignatureUnpacked();
if (formalsForResolution == null) {
return new Signature.FormalTypeParameter[0];
} else {
@@ -687,13 +677,13 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
}
private boolean isNestedClass() {
return javaClass.getClassName().indexOf('$') != -1;
return className.indexOf('$') != -1;
}
private ReferenceType getOuterClass() {
if (!isNestedClass()) throw new IllegalStateException("Can't get the outer class of a non-nested type");
int lastDollar = javaClass.getClassName().lastIndexOf('$');
String superClassName = javaClass.getClassName().substring(0,lastDollar);
int lastDollar = className.lastIndexOf('$');
String superClassName = className.substring(0,lastDollar);
UnresolvedType outer = UnresolvedType.forName(superClassName);
return (ReferenceType) outer.resolve(getResolvedTypeX().getWorld());
}
@@ -724,7 +714,16 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
return ret;
}
private void ensureGenericInfoProcessed() { getDeclaredGenericSignature();}
private void ensureGenericInfoProcessed() {
if ((bitflag & DISCOVERED_DECLARED_SIGNATURE)!=0) return;
bitflag |= DISCOVERED_DECLARED_SIGNATURE;
Attribute[] as = javaClass.getAttributes();
for (int i = 0; i < as.length && declaredSignature==null; i++) {
Attribute attribute = as[i];
if (attribute instanceof Signature) declaredSignature = ((Signature)attribute).getSignature();
}
if (declaredSignature!=null) isGenericType= (declaredSignature.charAt(0)=='<');
}
public boolean isGeneric() {
ensureGenericInfoProcessed();
@@ -732,9 +731,51 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
}
public String toString() {
return (javaClass==null?"BcelObjectType":"BcelObjectTypeFor:"+javaClass.getClassName());
return (javaClass==null?"BcelObjectType":"BcelObjectTypeFor:"+className);
}
// --- state management
public void evictWeavingState() {
// Can't chuck all this away
if (getResolvedTypeX().getWorld().couldIncrementalCompileFollow()) return;
if (javaClass != null) {
// Force retrieval of any lazy information
ensureAnnotationsUnpacked();
ensureGenericInfoProcessed();

interfaces=null; // force reinit - may get us the right instances!
superClass=null;
getDeclaredInterfaces();
getDeclaredFields();
getDeclaredMethods();
// The lazyClassGen is preserved for aspects - it exists to enable around advice
// inlining since the method will need 'injecting' into the affected class. If
// XnoInline is on, we can chuck away the lazyClassGen since it won't be required
// later.
if (getResolvedTypeX().getWorld().isXnoInline()) lazyClassGen=null;
// discard expensive bytecode array containing reweavable info
if (weaverState != null) {
weaverState.setReweavable(false);
weaverState.setUnwovenClassFileData(null);
}
for (int i = methods.length - 1; i >= 0; i--) methods[i].evictWeavingState();
for (int i = fields.length - 1; i >= 0; i--) fields[i].evictWeavingState();
javaClass = null;
// setSourceContext(SourceContextImpl.UNKNOWN_SOURCE_CONTEXT); // bit naughty
}
}
public void weavingCompleted() {
hasBeenWoven = true;
if (getResolvedTypeX().getWorld().isRunMinimalMemory()) evictWeavingState();
}
// --- methods for testing


// for testing - if we have this attribute, return it - will return null if it doesnt know anything
public AjAttribute[] getAttributes(String name) {
List results = new ArrayList();
@@ -759,6 +800,19 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
return strs;
}
// for testing
public void addPointcutDefinition(ResolvedPointcutDefinition d) {
bitflag|=DAMAGED;
int len = pointcuts.length;
ResolvedPointcutDefinition[] ret = new ResolvedPointcutDefinition[len+1];
System.arraycopy(pointcuts, 0, ret, 0, len);
ret[len] = d;
pointcuts = ret;
}
public boolean hasBeenWoven() {
return hasBeenWoven;
}
}

+ 3
- 26
weaver/src/org/aspectj/weaver/bcel/BcelWorld.java View File

@@ -48,7 +48,6 @@ import org.aspectj.apache.bcel.util.ClassLoaderRepository;
import org.aspectj.apache.bcel.util.ClassPath;
import org.aspectj.apache.bcel.util.Repository;
import org.aspectj.bridge.IMessageHandler;
import org.aspectj.bridge.MessageUtil;
import org.aspectj.weaver.Advice;
import org.aspectj.weaver.AdviceKind;
import org.aspectj.weaver.AjAttribute;
@@ -77,8 +76,6 @@ public class BcelWorld extends World implements Repository {

private Repository delegate;
private boolean fastDelegateSupportEnabled = isASMAround;
private boolean checkedXsetAsmOffOption=false;
//private ClassPathManager aspectPath = null;
// private List aspectPathEntries;
@@ -103,12 +100,7 @@ public class BcelWorld extends World implements Repository {
}

public void setFastDelegateSupport(boolean b) {
if (b && !isASMAround) {
throw new BCException("Unable to activate fast delegate support, ASM classes cannot be found");
}
fastDelegateSupportEnabled = b;
}
private static List getPathEntries(String s) {
List ret = new ArrayList();
@@ -288,25 +280,10 @@ public class BcelWorld extends World implements Repository {
protected ReferenceTypeDelegate resolveDelegate(ReferenceType ty) {
String name = ty.getName();
JavaClass jc = null;
// Check *once* whether the user has switched asm support off
if (!checkedXsetAsmOffOption) {
if (isASMAround) { // dont bother if its not...
Properties p = getExtraConfiguration();
if (p!=null) {
String s = p.getProperty("activateLightweightDelegates","true");
fastDelegateSupportEnabled = s.equalsIgnoreCase("true");
if (!fastDelegateSupportEnabled)
getMessageHandler().handleMessage(MessageUtil.info("[activateLightweightDelegates=false] Disabling optimization to use lightweight delegates for non-woven types"));
}
}
checkedXsetAsmOffOption=true;
}
// fastDelegateSupportEnabled=false;
ensureAdvancedConfigurationProcessed();
//UnwovenClassFile classFile = (UnwovenClassFile)sourceJavaClasses.get(name);
//if (classFile != null) jc = classFile.getJavaClass();
if (fastDelegateSupportEnabled && classPath!=null && !ty.needsModifiableDelegate() && isNotOnPackageRestrictedList(name)) {
if (isFastDelegateSupportEnabled() && classPath!=null && !ty.needsModifiableDelegate() && isNotOnPackageRestrictedList(name)) {
ClassPathManager.ClassFile cf = classPath.find(ty);
if (cf==null) {
return null;

Loading…
Cancel
Save