View | Details | Raw Unified | Return to bug 129297 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/aspectj/weaver/BoundedReferenceType.java (+2 lines)
Lines 269-273 Link Here
269
			resolvedTypeX.getDelegate().ensureDelegateConsistent();
269
			resolvedTypeX.getDelegate().ensureDelegateConsistent();
270
		}
270
		}
271
271
272
		public void evictReweavingState() {}
273
272
	}
274
	}
273
}
275
}
(-)src/org/aspectj/weaver/CrosscuttingMembersSet.java (+6 lines)
Lines 20-25 Link Here
20
import java.util.List;
20
import java.util.List;
21
import java.util.Map;
21
import java.util.Map;
22
import java.util.Set;
22
import java.util.Set;
23
import java.util.Map.Entry;
23
24
24
import org.aspectj.weaver.patterns.CflowPointcut;
25
import org.aspectj.weaver.patterns.CflowPointcut;
25
import org.aspectj.weaver.patterns.DeclareParents;
26
import org.aspectj.weaver.patterns.DeclareParents;
Lines 49-54 Link Here
49
		this.world = world;
50
		this.world = world;
50
	}
51
	}
51
52
53
	public void evictReweavingState() {		
54
    	for (Iterator it=members.keySet().iterator(); it.hasNext();) {
55
    		world.evictIfReferenceType(it.next());
56
    	}
57
    }
52
58
53
	/**
59
	/**
54
	 * @return whether or not that was a change to the global signature
60
	 * @return whether or not that was a change to the global signature
(-)src/org/aspectj/weaver/ReferenceTypeDelegate.java (-1 / +3 lines)
Lines 66-70 Link Here
66
	public String getSourcefilename();
66
	public String getSourcefilename();
67
	
67
	
68
	public String getDeclaredGenericSignature();
68
	public String getDeclaredGenericSignature();
69
	
69
70
	/** optimization: tells the type to evict any state required solely to support reweaving */ 
71
	public void evictReweavingState();
70
}
72
}
(-)src/org/aspectj/weaver/World.java (+15 lines)
Lines 24-29 Link Here
24
import java.util.Map;
24
import java.util.Map;
25
import java.util.Properties;
25
import java.util.Properties;
26
import java.util.WeakHashMap;
26
import java.util.WeakHashMap;
27
import java.util.Map.Entry;
27
28
28
import org.aspectj.asm.IHierarchy;
29
import org.aspectj.asm.IHierarchy;
29
import org.aspectj.bridge.IMessageHandler;
30
import org.aspectj.bridge.IMessageHandler;
Lines 956-961 Link Here
956
				);
957
				);
957
	}
958
	}
958
959
960
	public void evictReweavingState() {
961
    	evictReweavingState(typeMap.tMap);
962
    	evictReweavingState(typeMap.expendableMap); //XXX note interesting issue here: it is not safe to expend even not exposed/not reweavable aspects... yet they appear to end up here?!
963
    	crosscuttingMembersSet.evictReweavingState();//optimize: don't do this every time!!
964
    }
965
	private void evictReweavingState(Map map) {
966
    	for (Iterator it=map.entrySet().iterator(); it.hasNext();) {
967
    		Entry e = (Entry)it.next();
968
    		evictIfReferenceType(e.getValue());
969
    	}
970
    }
971
	public void evictIfReferenceType(Object resolvedType) {
972
	}		
973
959
	/**
974
	/**
960
	 * This class is used to compute and store precedence relationships between
975
	 * This class is used to compute and store precedence relationships between
961
	 * aspects.
976
	 * aspects.
(-)src/org/aspectj/weaver/asm/AsmDelegate.java (+5 lines)
Lines 630-634 Link Here
630
		// doesnt need to do anything until methods like addAnnotation() are implemented (i.e. methods that 
630
		// doesnt need to do anything until methods like addAnnotation() are implemented (i.e. methods that 
631
		// modify the delegate such that it differs from the on-disk contents)
631
		// modify the delegate such that it differs from the on-disk contents)
632
	}
632
	}
633
634
635
	public void evictReweavingState() {
636
		// this is a NO-OP: the ASM delegate already has all this state evicted!		
637
	}
633
	
638
	
634
}
639
}
(-)src/org/aspectj/weaver/bcel/BcelAdvice.java (-1 / +2 lines)
Lines 56-61 Link Here
56
	private ExposedState exposedState;
56
	private ExposedState exposedState;
57
    
57
    
58
    private boolean hasMatchedAtLeastOnce = false;
58
    private boolean hasMatchedAtLeastOnce = false;
59
    private boolean knownToBeWoven = false;
59
60
60
	public BcelAdvice(
61
	public BcelAdvice(
61
		AjAttribute.AdviceAttribute attribute,
62
		AjAttribute.AdviceAttribute attribute,
Lines 179-185 Link Here
179
180
180
		if (concreteAspect.getWorld().isXnoInline()) return false;
181
		if (concreteAspect.getWorld().isXnoInline()) return false;
181
    	//System.err.println("isWoven? " + ((BcelObjectType)concreteAspect).getLazyClassGen().getWeaverState());
182
    	//System.err.println("isWoven? " + ((BcelObjectType)concreteAspect).getLazyClassGen().getWeaverState());
182
    	return BcelWorld.getBcelObjectType(concreteAspect).getLazyClassGen().isWoven();
183
    	return knownToBeWoven || BcelWorld.getBcelObjectType(concreteAspect).getLazyClassGen().isWoven();
183
    }
184
    }
184
185
185
    public void implementOn(Shadow s) {
186
    public void implementOn(Shadow s) {
(-)src/org/aspectj/weaver/bcel/BcelMethod.java (+12 lines)
Lines 264-269 Link Here
264
	 }
264
	 }
265
	 
265
	 
266
	 private void ensureAnnotationTypesRetrieved() {
266
	 private void ensureAnnotationTypesRetrieved() {
267
		 if (method == null) {
268
			 return; // must be ok, we've evicted it
269
		 }
267
		if (annotationTypes == null || method.getAnnotations().length!=annotations.length) { // sometimes the list changes underneath us!
270
		if (annotationTypes == null || method.getAnnotations().length!=annotations.length) { // sometimes the list changes underneath us!
268
    		Annotation annos[] = method.getAnnotations();
271
    		Annotation annos[] = method.getAnnotations();
269
    		annotationTypes = new HashSet();
272
    		annotationTypes = new HashSet();
Lines 382-385 Link Here
382
			 genericParameterTypes = getParameterTypes();
385
			 genericParameterTypes = getParameterTypes();
383
		 }
386
		 }
384
	 }
387
	 }
388
	 
389
	 public void evictMethodHandle() {
390
		 if (method != null) {
391
			 unpackGenericSignature();
392
			 unpackJavaAttributes();
393
			 determineParameterNames();
394
			 method = null;
395
		 }
396
	 }
385
}
397
}
(-)src/org/aspectj/weaver/bcel/BcelObjectType.java (-19 / +69 lines)
Lines 26-31 Link Here
26
import org.aspectj.apache.bcel.classfile.JavaClass;
26
import org.aspectj.apache.bcel.classfile.JavaClass;
27
import org.aspectj.apache.bcel.classfile.Method;
27
import org.aspectj.apache.bcel.classfile.Method;
28
import org.aspectj.apache.bcel.classfile.Signature;
28
import org.aspectj.apache.bcel.classfile.Signature;
29
import org.aspectj.apache.bcel.classfile.Signature.ClassSignature;
29
import org.aspectj.apache.bcel.classfile.annotation.Annotation;
30
import org.aspectj.apache.bcel.classfile.annotation.Annotation;
30
import org.aspectj.apache.bcel.classfile.annotation.ArrayElementValue;
31
import org.aspectj.apache.bcel.classfile.annotation.ArrayElementValue;
31
import org.aspectj.apache.bcel.classfile.annotation.ElementNameValuePair;
32
import org.aspectj.apache.bcel.classfile.annotation.ElementNameValuePair;
Lines 92-98 Link Here
92
	private String retentionPolicy;
93
	private String retentionPolicy;
93
	private boolean discoveredAnnotationTargetKinds = false;
94
	private boolean discoveredAnnotationTargetKinds = false;
94
	private AnnotationTargetKind[] annotationTargetKinds;
95
	private AnnotationTargetKind[] annotationTargetKinds;
95
	
96
	private int modifiers;
97
	private String superclassName;
98
	private String className;
99
	
100
	public void evictReweavingState() {
101
		if (javaClass != null) {
102
			// force retrieval of any lazy information		
103
			getDeclaredFields();
104
			getDeclaredInterfaces();
105
			getDeclaredMethods();
106
			getDeclaredPointcuts();
107
			getTypeVariables();
108
			ensureAnnotationTypesRetrieved();
109
			ensureGenericInfoProcessed();
110
			
111
			if (weaverState != null) {
112
				weaverState.setReweavable(false);
113
				weaverState.setUnwovenClassFileData(null);
114
			}
115
			javaClass = null;
116
	        for (int i = methods.length - 1; i >= 0; i--) {
117
	        	((BcelMethod)methods[i]).evictMethodHandle();
118
	        }
119
		}
120
	}
96
	
121
	
97
	/**
122
	/**
98
	 * A BcelObjectType is 'damaged' if it has been modified from what was original constructed from
123
	 * A BcelObjectType is 'damaged' if it has been modified from what was original constructed from
Lines 100-105 Link Here
100
	 * ideally BcelObjectType should be immutable but that's a bigger piece of work!!!!!!!!!! XXX
125
	 * ideally BcelObjectType should be immutable but that's a bigger piece of work!!!!!!!!!! XXX
101
	 */
126
	 */
102
	private boolean damaged = false;
127
	private boolean damaged = false;
128
	private boolean isInterface;
129
	private boolean isEnum;
130
	private boolean isAnnotation;
131
	private boolean isAnonymous;
132
	private boolean isNested;
133
	private ClassSignature cachedGenericClassTypeSignature;
103
134
104
	public Collection getTypeMungers() {
135
	public Collection getTypeMungers() {
105
		return typeMungers;	
136
		return typeMungers;	
Lines 120-125 Link Here
120
    BcelObjectType(ReferenceType resolvedTypeX, JavaClass javaClass, boolean exposedToWeaver) {
151
    BcelObjectType(ReferenceType resolvedTypeX, JavaClass javaClass, boolean exposedToWeaver) {
121
        super(resolvedTypeX, exposedToWeaver);
152
        super(resolvedTypeX, exposedToWeaver);
122
        this.javaClass = javaClass;
153
        this.javaClass = javaClass;
154
        cacheFromJavaClass();
123
155
124
        //ATAJ: set the delegate right now for @AJ pointcut, else it is done too late to lookup
156
        //ATAJ: set the delegate right now for @AJ pointcut, else it is done too late to lookup
125
        // @AJ pc refs annotation in class hierarchy
157
        // @AJ pc refs annotation in class hierarchy
Lines 143-150 Link Here
143
    public void setJavaClass(JavaClass newclass) {
175
    public void setJavaClass(JavaClass newclass) {
144
    	this.javaClass = newclass;
176
    	this.javaClass = newclass;
145
    	resetState();
177
    	resetState();
178
    	cacheFromJavaClass();
146
    }
179
    }
147
    
180
    
181
    private void cacheFromJavaClass() {
182
		isInterface=javaClass.isInterface();
183
		isEnum=javaClass.isEnum();
184
		isAnnotation=javaClass.isAnnotation();
185
		isAnonymous=javaClass.isAnonymous();
186
		isNested=javaClass.isNested();    
187
		modifiers=javaClass.getAccessFlags();
188
		superclassName=javaClass.getSuperclassName();
189
		className=javaClass.getClassName();
190
		cachedGenericClassTypeSignature = javaClass.getGenericClassTypeSignature();
191
    }
192
148
   
193
   
149
    
194
    
150
    
195
    
Lines 174-180 Link Here
174
    }
219
    }
175
    
220
    
176
    public int getModifiers() {
221
    public int getModifiers() {
177
        return javaClass.getAccessFlags();
222
        return modifiers;
178
    }
223
    }
179
224
180
    /**
225
    /**
Lines 184-190 Link Here
184
        if (isObject) return null;
229
        if (isObject) return null;
185
    	unpackGenericSignature();
230
    	unpackGenericSignature();
186
        if (superClass == null) {
231
        if (superClass == null) {
187
            superClass = getResolvedTypeX().getWorld().resolve(UnresolvedType.forName(javaClass.getSuperclassName()));
232
            superClass = getResolvedTypeX().getWorld().resolve(UnresolvedType.forName(superclassName));
188
        }
233
        }
189
        return superClass;
234
        return superClass;
190
    }
235
    }
Lines 273-279 Link Here
273
		typeMungers = new ArrayList();
318
		typeMungers = new ArrayList();
274
		declares = new ArrayList();
319
		declares = new ArrayList();
275
		// Pass in empty list that can store things for readAj5 to process
320
		// Pass in empty list that can store things for readAj5 to process
276
        List l = BcelAttributes.readAjAttributes(javaClass.getClassName(),javaClass.getAttributes(), getResolvedTypeX().getSourceContext(),getResolvedTypeX().getWorld().getMessageHandler(),AjAttribute.WeaverVersionInfo.UNKNOWN);
321
        List l = BcelAttributes.readAjAttributes(className,javaClass.getAttributes(), getResolvedTypeX().getSourceContext(),getResolvedTypeX().getWorld().getMessageHandler(),AjAttribute.WeaverVersionInfo.UNKNOWN);
277
		processAttributes(l,pointcuts,false);
322
		processAttributes(l,pointcuts,false);
278
		l = AtAjAttributes.readAj5ClassAttributes(javaClass, getResolvedTypeX(), getResolvedTypeX().getSourceContext(), getResolvedTypeX().getWorld().getMessageHandler(),isCodeStyleAspect);
323
		l = AtAjAttributes.readAj5ClassAttributes(javaClass, getResolvedTypeX(), getResolvedTypeX().getSourceContext(), getResolvedTypeX().getWorld().getMessageHandler(),isCodeStyleAspect);
279
		AjAttribute.Aspect deferredAspectAttribute = processAttributes(l,pointcuts,true);
324
		AjAttribute.Aspect deferredAspectAttribute = processAttributes(l,pointcuts,true);
Lines 332-338 Link Here
332
		return perClause;
377
		return perClause;
333
	}
378
	}
334
    
379
    
335
    JavaClass getJavaClass() {
380
    public JavaClass getJavaClass() {
336
        return javaClass;
381
        return javaClass;
337
    }
382
    }
338
    
383
    
Lines 341-346 Link Here
341
    }
386
    }
342
    
387
    
343
    public void resetState() {
388
    public void resetState() {
389
    	if (javaClass == null) {
390
    		// we might store the classname and allow reloading? 
391
    		// At this point we are relying on the world to not evict if it might want to reweave multiple times  
392
    		throw new BCException("can't reweave evicted type");
393
    	}
344
		this.interfaces = null;
394
		this.interfaces = null;
345
    	this.superClass = null;
395
    	this.superClass = null;
346
    	this.fields = null;
396
    	this.fields = null;
Lines 401-407 Link Here
401
    		//System.err.println("creating lazy class gen for: " + this);
451
    		//System.err.println("creating lazy class gen for: " + this);
402
    		ret = new LazyClassGen(this);
452
    		ret = new LazyClassGen(this);
403
    		//ret.print(System.err);
453
    		//ret.print(System.err);
404
    		//System.err.println("made LCG from : " + this.getJavaClass().getSuperclassName() );
454
    		//System.err.println("made LCG from : " + this.getJavaClass().getSuperclassName );
405
    		if (isAspect()) {
455
    		if (isAspect()) {
406
    			lazyClassGen = ret;
456
    			lazyClassGen = ret;
407
    		}				
457
    		}				
Lines 410-432 Link Here
410
    }
460
    }
411
461
412
	public boolean isInterface() {
462
	public boolean isInterface() {
413
		return javaClass.isInterface();
463
		return isInterface;//javaClass.isInterface();
414
	}
464
	}
415
	
465
	
416
	public boolean isEnum() {
466
	public boolean isEnum() {
417
		return javaClass.isEnum();
467
		return isEnum;//javaClass.isEnum();
418
	}
468
	}
419
	
469
	
420
	public boolean isAnnotation() {
470
	public boolean isAnnotation() {
421
		return javaClass.isAnnotation();
471
		return isAnnotation;//javaClass.isAnnotation();
422
	}
472
	}
423
	
473
	
424
	public boolean isAnonymous() {
474
	public boolean isAnonymous() {
425
		return javaClass.isAnonymous();
475
		return isAnonymous;//javaClass.isAnonymous();
426
	}
476
	}
427
	
477
	
428
	public boolean isNested() {
478
	public boolean isNested() {
429
		return javaClass.isNested();
479
		return isNested;//javaClass.isNested();
430
	}
480
	}
431
	
481
	
432
	public void addAnnotation(AnnotationX annotation) {
482
	public void addAnnotation(AnnotationX annotation) {
Lines 552-558 Link Here
552
			
602
			
553
			interfaces = newInterfaceNames;
603
			interfaces = newInterfaceNames;
554
		}
604
		}
555
		//System.err.println("javaClass: " + Arrays.asList(javaClass.getInterfaceNames()) + " super " + javaClass.getSuperclassName());
605
		//System.err.println("javaClass: " + Arrays.asList(javaClass.getInterfaceNames()) + " super " + superclassName);
556
		//if (lazyClassGen != null) lazyClassGen.print();
606
		//if (lazyClassGen != null) lazyClassGen.print();
557
	}
607
	}
558
608
Lines 609-615 Link Here
609
	}
659
	}
610
	
660
	
611
	Signature.ClassSignature getGenericClassTypeSignature() {
661
	Signature.ClassSignature getGenericClassTypeSignature() {
612
		return javaClass.getGenericClassTypeSignature();
662
		return cachedGenericClassTypeSignature;
613
	}
663
	}
614
	
664
	
615
	private boolean genericSignatureUnpacked = false;
665
	private boolean genericSignatureUnpacked = false;
Lines 647-653 Link Here
647
			} catch (GenericSignatureFormatException e) {
697
			} catch (GenericSignatureFormatException e) {
648
				// development bug, fail fast with good info
698
				// development bug, fail fast with good info
649
				throw new IllegalStateException(
699
				throw new IllegalStateException(
650
						"While determing the generic superclass of " + this.javaClass.getClassName()
700
						"While determing the generic superclass of " + this.className
651
						+ " with generic signature " + this.javaClass.getGenericSignature() + " the following error was detected: "
701
						+ " with generic signature " + this.javaClass.getGenericSignature() + " the following error was detected: "
652
						+ e.getMessage());
702
						+ e.getMessage());
653
			}
703
			}
Lines 662-668 Link Here
662
				} catch (GenericSignatureFormatException e) {
712
				} catch (GenericSignatureFormatException e) {
663
					// development bug, fail fast with good info
713
					// development bug, fail fast with good info
664
					throw new IllegalStateException(
714
					throw new IllegalStateException(
665
							"While determing the generic superinterfaces of " + this.javaClass.getClassName()
715
							"While determing the generic superinterfaces of " + this.className
666
							+ " with generic signature " + this.javaClass.getGenericSignature() + " the following error was detected: "
716
							+ " with generic signature " + this.javaClass.getGenericSignature() + " the following error was detected: "
667
							+ e.getMessage());
717
							+ e.getMessage());
668
				}
718
				}
Lines 687-699 Link Here
687
	}
737
	}
688
	
738
	
689
	private boolean isNestedClass() {
739
	private boolean isNestedClass() {
690
		return javaClass.getClassName().indexOf('$') != -1;
740
		return className.indexOf('$') != -1;
691
	}
741
	}
692
	
742
	
693
	private ReferenceType getOuterClass() {
743
	private ReferenceType getOuterClass() {
694
		if (!isNestedClass()) throw new IllegalStateException("Can't get the outer class of a non-nested type");
744
		if (!isNestedClass()) throw new IllegalStateException("Can't get the outer class of a non-nested type");
695
		int lastDollar = javaClass.getClassName().lastIndexOf('$');
745
		int lastDollar = className.lastIndexOf('$');
696
		String superClassName = javaClass.getClassName().substring(0,lastDollar);
746
		String superClassName = className.substring(0,lastDollar);
697
		UnresolvedType outer = UnresolvedType.forName(superClassName);
747
		UnresolvedType outer = UnresolvedType.forName(superClassName);
698
		return (ReferenceType) outer.resolve(getResolvedTypeX().getWorld());
748
		return (ReferenceType) outer.resolve(getResolvedTypeX().getWorld());
699
	}
749
	}
Lines 732-738 Link Here
732
	}
782
	}
733
	
783
	
734
	public String toString() {
784
	public String toString() {
735
		return (javaClass==null?"BcelObjectType":"BcelObjectTypeFor:"+javaClass.getClassName());
785
		return (javaClass==null?"BcelObjectType":"BcelObjectTypeFor:"+className);
736
	}
786
	}
737
	
787
	
738
    // for testing - if we have this attribute, return it - will return null if it doesnt know anything 
788
    // for testing - if we have this attribute, return it - will return null if it doesnt know anything 
(-)src/org/aspectj/weaver/bcel/BcelWorld.java (-5 / +33 lines)
Lines 17-26 Link Here
17
import java.io.ByteArrayInputStream;
17
import java.io.ByteArrayInputStream;
18
import java.io.File;
18
import java.io.File;
19
import java.io.IOException;
19
import java.io.IOException;
20
import java.lang.reflect.Field;
20
import java.lang.reflect.Modifier;
21
import java.lang.reflect.Modifier;
21
import java.util.ArrayList;
22
import java.util.ArrayList;
22
import java.util.Iterator;
23
import java.util.Iterator;
23
import java.util.List;
24
import java.util.List;
25
import java.util.Map;
24
import java.util.Properties;
26
import java.util.Properties;
25
import java.util.StringTokenizer;
27
import java.util.StringTokenizer;
26
28
Lines 71-82 Link Here
71
import org.aspectj.weaver.patterns.PerClause;
73
import org.aspectj.weaver.patterns.PerClause;
72
import org.aspectj.weaver.patterns.Pointcut;
74
import org.aspectj.weaver.patterns.Pointcut;
73
import org.aspectj.weaver.patterns.SimpleScope;
75
import org.aspectj.weaver.patterns.SimpleScope;
76
import org.aspectj.weaver.reflect.ReflectionBasedReferenceTypeDelegate;
74
77
75
public class BcelWorld extends World implements Repository {
78
public class BcelWorld extends World implements Repository {
76
	private ClassPathManager classPath;
79
	private ClassPathManager classPath;
77
80
78
    private Repository delegate;
81
    private Repository delegate;
79
    
82
    
83
    
80
    private boolean fastDelegateSupportEnabled = isASMAround;
84
    private boolean fastDelegateSupportEnabled = isASMAround;
81
    private boolean checkedXsetAsmOffOption=false;
85
    private boolean checkedXsetAsmOffOption=false;
82
    
86
    
Lines 217-222 Link Here
217
    }
221
    }
218
    
222
    
219
    // ---- various interactions with bcel
223
    // ---- various interactions with bcel
224
	protected BcelObjectType makeBcelObjectType(ReferenceType resolvedTypeX, JavaClass jc, boolean exposedToWeaver) {
225
		BcelObjectType ret = new BcelObjectType(resolvedTypeX, jc, exposedToWeaver);
226
		return ret;
227
	}
220
228
221
    public static Type makeBcelType(UnresolvedType type) {
229
    public static Type makeBcelType(UnresolvedType type) {
222
        return Type.getType(type.getErasureSignature());
230
        return Type.getType(type.getErasureSignature());
Lines 288-294 Link Here
288
	protected ReferenceTypeDelegate resolveDelegate(ReferenceType ty) {
296
	protected ReferenceTypeDelegate resolveDelegate(ReferenceType ty) {
289
        String name = ty.getName();
297
        String name = ty.getName();
290
        JavaClass jc = null;
298
        JavaClass jc = null;
291
        
292
        // Check *once* whether the user has switched asm support off
299
        // Check *once* whether the user has switched asm support off
293
    	if (!checkedXsetAsmOffOption) {
300
    	if (!checkedXsetAsmOffOption) {
294
    		if (isASMAround) { // dont bother if its not...
301
    		if (isASMAround) { // dont bother if its not...
Lines 404-410 Link Here
404
		return ret;
411
		return ret;
405
	}
412
	}
406
	
413
	
407
	void deleteSourceObjectType(UnresolvedType ty) {
414
	public void deleteSourceObjectType(UnresolvedType ty) {
408
		typeMap.remove(ty.getSignature());
415
		typeMap.remove(ty.getSignature());
409
	}
416
	}
410
417
Lines 607-612 Link Here
607
     * quite often when incrementally compiling.
614
     * quite often when incrementally compiling.
608
     */
615
     */
609
	public static BcelObjectType getBcelObjectType(ResolvedType concreteAspect) {
616
	public static BcelObjectType getBcelObjectType(ResolvedType concreteAspect) {
617
		if (concreteAspect.isMissing()) {
618
			return null;
619
		}
610
		ReferenceTypeDelegate rtDelegate = ((ReferenceType)concreteAspect).getDelegate();
620
		ReferenceTypeDelegate rtDelegate = ((ReferenceType)concreteAspect).getDelegate();
611
		if (rtDelegate instanceof BcelObjectType) {
621
		if (rtDelegate instanceof BcelObjectType) {
612
			return (BcelObjectType)rtDelegate;
622
			return (BcelObjectType)rtDelegate;
Lines 638-646 Link Here
638
	}
648
	}
639
649
640
	public void removeClass(JavaClass clazz) {
650
	public void removeClass(JavaClass clazz) {
641
		throw new RuntimeException("Not implemented");
651
		delegate.removeClass(clazz);
642
	}
652
	}
643
653
	
644
	public JavaClass loadClass(Class clazz) throws ClassNotFoundException {
654
	public JavaClass loadClass(Class clazz) throws ClassNotFoundException {
645
		throw new RuntimeException("Not implemented");
655
		throw new RuntimeException("Not implemented");
646
	}
656
	}
Lines 671-677 Link Here
671
//			e.printStackTrace();
681
//			e.printStackTrace();
672
//		}
682
//		}
673
	}
683
	}
674
675
    /**
684
    /**
676
     * Checks if given bytecode is an @AspectJ aspect
685
     * Checks if given bytecode is an @AspectJ aspect
677
     *
686
     *
Lines 714-717 Link Here
714
            return true;
723
            return true;
715
        }
724
        }
716
    }
725
    }
726
    
727
728
    protected void evictClassLoaderRepository() {
729
    	if (delegate != this) {
730
        	// debug only ... I don't think this has any effect
731
//    		try {
732
//	    		Field loadedClasses = delegate.getClass().getDeclaredField("loadedClasses");
733
//	    		loadedClasses.setAccessible(true);
734
//	    		Map map = (Map)loadedClasses.get(delegate);
735
//	    		if (map.size()>0) {
736
//	    			System.out.println(map.size());
737
//	    		}
738
//    		} catch (Throwable t) {
739
//    			t.printStackTrace();
740
//    		}
741
    		
742
    		delegate.clear(); // shrink/crunch...
743
    	}
744
    }
717
}
745
}
(-)src/org/aspectj/weaver/ltw/LTWWorld.java (-5 / +148 lines)
Lines 15-28 Link Here
15
import java.lang.ref.WeakReference;
15
import java.lang.ref.WeakReference;
16
import java.util.Collections;
16
import java.util.Collections;
17
import java.util.HashMap;
17
import java.util.HashMap;
18
import java.util.Iterator;
19
import java.util.List;
18
import java.util.Map;
20
import java.util.Map;
21
import java.util.Map.Entry;
19
22
23
import org.aspectj.apache.bcel.classfile.JavaClass;
20
import org.aspectj.bridge.IMessageHandler;
24
import org.aspectj.bridge.IMessageHandler;
25
import org.aspectj.bridge.Message;
21
import org.aspectj.util.LangUtil;
26
import org.aspectj.util.LangUtil;
22
import org.aspectj.weaver.ICrossReferenceHandler;
27
import org.aspectj.weaver.ICrossReferenceHandler;
23
import org.aspectj.weaver.ReferenceType;
28
import org.aspectj.weaver.ReferenceType;
24
import org.aspectj.weaver.ReferenceTypeDelegate;
29
import org.aspectj.weaver.ReferenceTypeDelegate;
25
import org.aspectj.weaver.ResolvedType;
30
import org.aspectj.weaver.ResolvedType;
31
import org.aspectj.weaver.bcel.BcelObjectType;
26
import org.aspectj.weaver.bcel.BcelWorld;
32
import org.aspectj.weaver.bcel.BcelWorld;
27
import org.aspectj.weaver.reflect.AnnotationFinder;
33
import org.aspectj.weaver.reflect.AnnotationFinder;
28
import org.aspectj.weaver.reflect.IReflectionWorld;
34
import org.aspectj.weaver.reflect.IReflectionWorld;
Lines 48-56 Link Here
48
    private AnnotationFinder annotationFinder;
54
    private AnnotationFinder annotationFinder;
49
    private ClassLoader loader; // weavingContext?
55
    private ClassLoader loader; // weavingContext?
50
    
56
    
57
    private boolean loadingAspects = false;
51
    protected final static Class concurrentMapClass = makeConcurrentMapClass();
58
    protected final static Class concurrentMapClass = makeConcurrentMapClass();
52
    protected static Map/*<String, WeakReference<ReflectionBasedReferenceTypeDelegate>>*/ bootstrapTypes = makeConcurrentMap();
59
    protected static Map/*<String, WeakReference<ReflectionBasedReferenceTypeDelegate>>*/ bootstrapTypes = makeConcurrentMap();
53
    
60
    
61
    private static ThreadLocal loadingCount = new ThreadLocal() {
62
        public Object initialValue() {
63
            return new int[1];
64
        }
65
    };
66
    private static MapThreadLocal processedRefTypes = new MapThreadLocal();
67
    
54
    /**
68
    /**
55
     * Build a World from a ClassLoader, for LTW support
69
     * Build a World from a ClassLoader, for LTW support
56
     */
70
     */
Lines 66-79 Link Here
66
        return this.loader;
80
        return this.loader;
67
    }
81
    }
68
    
82
    
69
    //TEST
83
    public void setLoadingAspects(boolean isLoading) {
84
        loadingAspects = isLoading;
85
        flushOld();
86
    }
87
    // this was created to try to avoid circularity errors using reflection delegates, but that's not practical in general
88
    // now it's used to optimize performance, so we only evict objects when done with all local 
89
    // weaves...
90
    // it looks like overkill in this simplified version of LTWWorld, but it is laying a foundation to allow load-time weaving worlds
91
    // to share state, which ends up being quite important to optimize memory use
92
    public void startLoading(String name) {
93
        ((int[])loadingCount.get())[0]++;
94
    }
95
    
96
    public void stopLoading(String name) {
97
        int count = --((int[])loadingCount.get())[0];        
98
        if (count == 0) {
99
            // go back and swizzle out all those proxies
100
            flushOld();
101
        }
102
    }
103
    
104
    protected void flushOld() {
105
        // we can unload when nothing is now being loaded... while 
106
        // a ClassLoader can be re-engaged in between preloading and defining the class
107
        // it can't cycle, so we should be safe from cycles 
108
        // in the worst case, we'd just evict some bytecode and then reload from BCEL again...
109
        if (!loadingAspects) {
110
            evict();
111
        }
112
    }
113
    
114
    /** Evict details not needed after weaving a type (keeping only a "shape") */
115
    protected void evict() {
116
    	// evicting can load new types when caching, requiring this loop
117
        while (!processedRefTypes.isEmpty()) {
118
            Map map = processedRefTypes.snapOffMap();
119
            for (Iterator it = map.entrySet().iterator(); it.hasNext();) {
120
                Entry entry = (Entry)it.next();
121
                ReferenceType refType = (ReferenceType)(entry.getKey()); 
122
                LTWWorld world = (LTWWorld)(entry.getValue());
123
                world.evict(refType);
124
            }
125
            map.clear();
126
            evictReweavingState();
127
        }
128
        evictClassLoaderRepository();
129
    }
130
    
131
    public BcelObjectType addSourceObjectType(JavaClass jc) {
132
        BcelObjectType objectType = super.addSourceObjectType(jc);
133
        
134
        processedRefTypes.put(objectType.getResolvedTypeX(), this);            
135
136
        return objectType;
137
    }
138
70
    //this is probably easier: just mark anything loaded while loading aspects as not
139
    //this is probably easier: just mark anything loaded while loading aspects as not
71
    //expendible... it also fixes a possible bug whereby non-rewoven aspects are deemed expendible
140
    //expendible... it also fixes a possible bug whereby non-rewoven aspects are deemed expendible
72
    //<exclude within="org.foo.aspects..*"/>
141
    //<exclude within="org.foo.aspects..*"/>
73
//    protected boolean isExpendable(ResolvedType type) {
142
    protected boolean isExpendable(ResolvedType type) {
74
//		return ((type != null) && !loadingAspects && !type.isAspect() && (!type
143
		return ((type != null) && !loadingAspects && !type.isAspect() && (!type.isPrimitiveType()));
75
//				.isPrimitiveType()));
144
	}
76
//	}
77
	
145
	
78
    /**
146
    /**
79
	 * @Override
147
	 * @Override
Lines 87-92 Link Here
87
            return bootstrapLoaderDelegate;
155
            return bootstrapLoaderDelegate;
88
        }
156
        }
89
        
157
        
158
        processedRefTypes.put(ty, this);
90
       	return super.resolveDelegate(ty);
159
       	return super.resolveDelegate(ty);
91
    }
160
    }
92
161
Lines 181-184 Link Here
181
    	return null;
250
    	return null;
182
    }
251
    }
183
    
252
    
253
    protected void evict(ReferenceType refType) {
254
        ReferenceTypeDelegate refDelegate = refType.getDelegate();
255
        if (refDelegate instanceof BcelObjectType) {
256
            BcelObjectType bcelObject = (BcelObjectType)refDelegate;
257
            if (bcelObject.getJavaClass() != null) {
258
                // not needed: we are retaining the key information and we do proper hollowing 
259
                removeClass(bcelObject.getJavaClass());
260
            }
261
            //this should probably be either/or: either we are removing the class altogether or we are keeping it and evicting reweaving state...
262
            //bcelObject.evictReweavingState();
263
        }
264
        // advice inlining uses the JavaClass later on for Lazy instantiation
265
        if (refDelegate != null && !refType.isAspect()) {
266
            refDelegate.evictReweavingState();
267
        }
268
    }
269
    
270
    private static class MapThreadLocal {
271
        private MapThreadLocalData mapHolder = new MapThreadLocalData();
272
        private MapThreadLocalData altHolder = new MapThreadLocalData();
273
        private static class MapThreadLocalData extends ThreadLocal/*<Map<Type, Ref>>*/ {
274
            public Object initialValue() {
275
                return new HashMap();
276
            }
277
        };
278
        private Map getMap() {
279
            return (Map)mapHolder.get();
280
        }
281
        private Map snapOffMap() {
282
            MapThreadLocalData alt = mapHolder;
283
            mapHolder = altHolder;
284
            altHolder = alt;
285
286
            getMap().clear();
287
            return (Map)altHolder.get();
288
        }
289
        
290
        public void put(Object key, Object val) {
291
            getMap().put(key, val);
292
        }
293
        
294
        public Object remove(Object key) {
295
            return getMap().remove(key);
296
        }
297
        
298
        public boolean isEmpty() {
299
            return getMap().isEmpty();
300
        }
301
        
302
        public Iterator entryIterator() {
303
            return getMap().entrySet().iterator();            
304
        }
305
306
        public void clear() {
307
            getMap().clear();            
308
        }
309
    };
310
311
//    /** 
312
//     * Allow reweaving is used to control whether we expect to reweave types after they've been loaded once.
313
//     * This allows the world to evict bytecode for method implementations. 
314
//     */  
315
//    public boolean isAllowReweaving() {
316
//        return allowReweaving;
317
//    }
318
//
319
//    /** 
320
//     * Sets whether we expect to reweave types after they've been loaded once.
321
//     * This allows the world to evict bytecode for method implementations after definition. 
322
//     */  
323
//    public void setAllowReweaving(boolean allowReweaving) {
324
//        this.allowReweaving = allowReweaving;
325
//    }
326
    
184
}
327
}
(-)src/org/aspectj/weaver/reflect/ReflectionBasedReferenceTypeDelegate.java (+4 lines)
Lines 17-22 Link Here
17
import java.lang.reflect.Method;
17
import java.lang.reflect.Method;
18
import java.util.Collection;
18
import java.util.Collection;
19
import java.util.Collections;
19
import java.util.Collections;
20
import java.util.HashMap;
21
import java.util.Iterator;
20
22
21
import org.aspectj.weaver.AnnotationTargetKind;
23
import org.aspectj.weaver.AnnotationTargetKind;
22
import org.aspectj.weaver.AnnotationX;
24
import org.aspectj.weaver.AnnotationX;
Lines 362-366 Link Here
362
	public ISourceContext getSourceContext() {
364
	public ISourceContext getSourceContext() {
363
		return SourceContextImpl.UNKNOWN_SOURCE_CONTEXT;
365
		return SourceContextImpl.UNKNOWN_SOURCE_CONTEXT;
364
	}
366
	}
367
	
368
	public void evictReweavingState() {}
365
369
366
}
370
}
(-)src/org/aspectj/weaver/tools/WeavingAdaptor.java (-2 / +3 lines)
Lines 44-49 Link Here
44
import org.aspectj.weaver.bcel.BcelWeaver;
44
import org.aspectj.weaver.bcel.BcelWeaver;
45
import org.aspectj.weaver.bcel.BcelWorld;
45
import org.aspectj.weaver.bcel.BcelWorld;
46
import org.aspectj.weaver.bcel.UnwovenClassFile;
46
import org.aspectj.weaver.bcel.UnwovenClassFile;
47
import org.aspectj.weaver.ltw.LTWWorld;
47
48
48
/**
49
/**
49
 * This adaptor allows the AspectJ compiler to be embedded in an existing
50
 * This adaptor allows the AspectJ compiler to be embedded in an existing
Lines 272-278 Link Here
272
	 * @return byte[] the woven bytes for the class
273
	 * @return byte[] the woven bytes for the class
273
	 * @throws IOException
274
	 * @throws IOException
274
	 */
275
	 */
275
	private byte[] getWovenBytes(String name, byte[] bytes) throws IOException {
276
	protected byte[] getWovenBytes(String name, byte[] bytes) throws IOException {
276
		WeavingClassFileProvider wcp = new WeavingClassFileProvider(name,bytes);
277
		WeavingClassFileProvider wcp = new WeavingClassFileProvider(name,bytes);
277
		weaver.weave(wcp);
278
		weaver.weave(wcp);
278
		return wcp.getBytes();		
279
		return wcp.getBytes();		
Lines 286-292 Link Here
286
     * @return byte[] the woven bytes for the class
287
     * @return byte[] the woven bytes for the class
287
     * @throws IOException
288
     * @throws IOException
288
     */
289
     */
289
    private byte[] getAtAspectJAspectBytes(String name, byte[] bytes) throws IOException {
290
	protected byte[] getAtAspectJAspectBytes(String name, byte[] bytes) throws IOException {
290
        WeavingClassFileProvider wcp = new WeavingClassFileProvider(name,bytes);
291
        WeavingClassFileProvider wcp = new WeavingClassFileProvider(name,bytes);
291
        wcp.setApplyAtAspectJMungersOnly();
292
        wcp.setApplyAtAspectJMungersOnly();
292
        weaver.weave(wcp);
293
        weaver.weave(wcp);

Return to bug 129297