import java.util.*; import org.apache.commons.collections.map.AbstractReferenceMap; import org.apache.commons.collections.map.ReferenceIdentityMap; import org.apache.commons.collections.set.MapBackedSet; public aspect LeakingSync { dependency { strong sync, access; } //most common supertype of Map anc Collection is Object unfortunately pointcut createSync(Object toSync): call(* Collections.synchr*(..)) && args(toSync); Set origs = MapBackedSet.decorate(new ReferenceIdentityMap(AbstractReferenceMap.WEAK,AbstractReferenceMap.HARD,true),new Object()); dependent synchronized after sync(Object orig) returning(Object sync): !within(dacapo..*) && !within(LeakingSync) && createSync(orig) { origs.add(orig); } dependent synchronized before access(Object orig) : !within(dacapo..*) && !within(LeakingSync) && (call(* Collection+.*(..)) || call(* Map+.*(..))) && target(orig) { if(origs.contains(orig)) { //System.err.println("MATCHED at "+thisJoinPointStaticPart.getSourceLocation()); } } before(): call(* dacapo.Benchmark.run(..)) { //reset all data structures for new benchmark run origs.clear(); } } //class LeakingSyncTest { // // public static void main(String[] args) { // List l = new ArrayList(); // Collection s = Collections.synchronizedList(l); // s.clear(); // l.clear(); // } // //}