Skip to content
Commits on Source (6)
......@@ -38,9 +38,4 @@ matrix:
- oracle-java9-installer
env: JDK=9
- jdk: openjdk7
- jdk: openjdk6
addons:
apt:
packages:
- openjdk-6-jdk
......@@ -9,7 +9,7 @@
<parent>
<groupId>cglib</groupId>
<artifactId>cglib-parent</artifactId>
<version>3.2.6</version>
<version>3.2.8</version>
</parent>
<!-- ====================================================================== -->
......
......@@ -7,7 +7,7 @@
<parent>
<artifactId>cglib-parent</artifactId>
<groupId>cglib</groupId>
<version>3.2.6</version>
<version>3.2.8</version>
</parent>
<modelVersion>4.0.0</modelVersion>
......@@ -44,7 +44,6 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<jmh.version>1.11.3</jmh.version>
<javac.target>1.6</javac.target>
<uberjar.name>benchmarks</uberjar.name>
</properties>
......@@ -54,7 +53,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<compilerVersion>${javac.target}</compilerVersion>
<source>${javac.target}</source>
......@@ -64,7 +63,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.2</version>
<version>3.1.1</version>
<executions>
<execution>
<phase>package</phase>
......@@ -102,39 +101,39 @@
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>2.5</version>
<version>3.1.0</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.1</version>
<version>2.8.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.1</version>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<version>${maven-jar-plugin.version}</version>
</plugin>
<plugin>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9.1</version>
<version>${maven-javadoc-plugin.version}</version>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
<version>${maven-resources-plugin.version}</version>
</plugin>
<plugin>
<artifactId>maven-site-plugin</artifactId>
<version>3.3</version>
<version>3.7.1</version>
</plugin>
<plugin>
<artifactId>maven-source-plugin</artifactId>
<version>2.2.1</version>
<version>3.0.1</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.17</version>
<version>2.21.0</version>
</plugin>
</plugins>
</pluginManagement>
......
......@@ -9,7 +9,7 @@
<parent>
<groupId>cglib</groupId>
<artifactId>cglib-parent</artifactId>
<version>3.2.6</version>
<version>3.2.8</version>
</parent>
<!-- ====================================================================== -->
......
......@@ -9,7 +9,7 @@
<parent>
<groupId>cglib</groupId>
<artifactId>cglib-parent</artifactId>
<version>3.2.6</version>
<version>3.2.8</version>
</parent>
<!-- ====================================================================== -->
......@@ -38,7 +38,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jarsigner-plugin</artifactId>
<version>1.3.2</version>
<version>1.4</version>
<executions>
<execution>
<id>sign</id>
......
......@@ -9,7 +9,7 @@
<parent>
<groupId>cglib</groupId>
<artifactId>cglib-parent</artifactId>
<version>3.2.6</version>
<version>3.2.8</version>
</parent>
<!-- ====================================================================== -->
......
package net.sf.cglib.core;
import java.security.AccessController;
import java.security.PrivilegedAction;
import org.objectweb.asm.Opcodes;
final class AsmApi {
private static final String EXPERIMENTAL_ASM7_PROPERTY_NAME = "net.sf.cglib.experimental_asm7";
/**
* Returns the latest stable ASM API value in {@link Opcodes} unless overridden via the
* net.sf.cglib.experimental_asm7 property.
*/
static int value() {
boolean experimentalAsm7;
try {
experimentalAsm7 = Boolean.parseBoolean(AccessController.doPrivileged(
new PrivilegedAction<String>() {
public String run() {
return System.getProperty(EXPERIMENTAL_ASM7_PROPERTY_NAME);
}
}));
} catch (Exception ignored) {
experimentalAsm7 = false;
}
return experimentalAsm7 ? Opcodes.ASM7_EXPERIMENTAL : Opcodes.ASM6;
}
private AsmApi() {
}
}
......@@ -20,7 +20,6 @@ import net.sf.cglib.transform.ClassTransformer;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import java.util.HashMap;
......@@ -44,7 +43,7 @@ public class ClassEmitter extends ClassTransformer {
}
public ClassEmitter() {
super(Opcodes.ASM6);
super(Constants.ASM_API);
}
public void setTarget(ClassVisitor cv) {
......@@ -148,7 +147,7 @@ public class ClassEmitter extends ClassTransformer {
TypeUtils.toInternalNames(exceptions));
if (sig.equals(Constants.SIG_STATIC) && !TypeUtils.isInterface(getAccess())) {
rawStaticInit = v;
MethodVisitor wrapped = new MethodVisitor(Opcodes.ASM6, v) {
MethodVisitor wrapped = new MethodVisitor(Constants.ASM_API, v) {
public void visitMaxs(int maxStack, int maxLocals) {
// ignore
}
......
......@@ -17,7 +17,6 @@ package net.sf.cglib.core;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.Opcodes;
import java.util.*;
......@@ -38,7 +37,7 @@ public class ClassNameReader {
public static String[] getClassInfo(ClassReader r) {
final List array = new ArrayList();
try {
r.accept(new ClassVisitor(Opcodes.ASM6, null) {
r.accept(new ClassVisitor(Constants.ASM_API, null) {
public void visit(int version,
int access,
String name,
......
......@@ -22,6 +22,10 @@ import org.objectweb.asm.Type;
* @version $Id: Constants.java,v 1.21 2006/03/05 02:43:19 herbyderby Exp $
*/
public interface Constants extends org.objectweb.asm.Opcodes {
/* Indicates the ASM API version that is used throughout cglib */
public static final int ASM_API = AsmApi.value();
public static final Class[] EMPTY_CLASS_ARRAY = {};
public static final Type[] TYPES_EMPTY = {};
......
......@@ -46,7 +46,7 @@ public class DebuggingClassWriter extends ClassVisitor {
}
public DebuggingClassWriter(int flags) {
super(Opcodes.ASM6, new ClassWriter(flags));
super(Constants.ASM_API, new ClassWriter(flags));
}
public void visit(int version,
......
......@@ -15,13 +15,150 @@
*/
package net.sf.cglib.core;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.*;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
public class DuplicatesPredicate implements Predicate {
private Set unique = new HashSet();
private final Set unique;
private final Set rejected;
/**
* Constructs a DuplicatesPredicate that will allow subclass bridge methods to be preferred over
* superclass non-bridge methods.
*/
public DuplicatesPredicate() {
unique = new HashSet();
rejected = Collections.emptySet();
}
/**
* Constructs a DuplicatesPredicate that prefers using superclass non-bridge methods despite a
* subclass method with the same signtaure existing (if the subclass is a bridge method).
*/
public DuplicatesPredicate(List allMethods) {
rejected = new HashSet();
unique = new HashSet();
// Traverse through the methods and capture ones that are bridge
// methods when a subsequent method (from a non-interface superclass)
// has the same signature but isn't a bridge. Record these so that
// we avoid using them when filtering duplicates.
Map scanned = new HashMap();
Map suspects = new HashMap();
for (Object o : allMethods) {
Method method = (Method) o;
Object sig = MethodWrapper.create(method);
Method existing = (Method) scanned.get(sig);
if (existing == null) {
scanned.put(sig, method);
} else if (!suspects.containsKey(sig) && existing.isBridge() && !method.isBridge()) {
// TODO: this currently only will capture a single bridge. it will not work
// if there's Child.bridge1 Middle.bridge2 Parent.concrete. (we'd offer the 2nd bridge).
// no idea if that's even possible tho...
suspects.put(sig, existing);
}
}
if (!suspects.isEmpty()) {
Set classes = new HashSet();
UnnecessaryBridgeFinder finder = new UnnecessaryBridgeFinder(rejected);
for (Object o : suspects.values()) {
Method m = (Method) o;
classes.add(m.getDeclaringClass());
finder.addSuspectMethod(m);
}
for (Object o : classes) {
Class c = (Class) o;
try {
ClassLoader cl = getClassLoader(c);
if (cl == null) {
continue;
}
InputStream is = cl.getResourceAsStream(c.getName().replace('.', '/') + ".class");
if (is == null) {
continue;
}
try {
new ClassReader(is).accept(finder, ClassReader.SKIP_FRAMES | ClassReader.SKIP_DEBUG);
} finally {
is.close();
}
} catch (IOException ignored) {
}
}
}
}
public boolean evaluate(Object arg) {
return unique.add(MethodWrapper.create((Method)arg));
return !rejected.contains(arg) && unique.add(MethodWrapper.create((Method) arg));
}
private static ClassLoader getClassLoader(Class c) {
ClassLoader cl = c.getClassLoader();
if (cl == null) {
cl = DuplicatesPredicate.class.getClassLoader();
}
if (cl == null) {
cl = Thread.currentThread().getContextClassLoader();
}
return cl;
}
private static class UnnecessaryBridgeFinder extends ClassVisitor {
private final Set rejected;
private Signature currentMethodSig = null;
private Map methods = new HashMap();
UnnecessaryBridgeFinder(Set rejected) {
super(Constants.ASM_API);
this.rejected = rejected;
}
void addSuspectMethod(Method m) {
methods.put(ReflectUtils.getSignature(m), m);
}
public void visit(
int version,
int access,
String name,
String signature,
String superName,
String[] interfaces) {}
public MethodVisitor visitMethod(
int access, String name, String desc, String signature, String[] exceptions) {
Signature sig = new Signature(name, desc);
final Method currentMethod = (Method) methods.remove(sig);
if (currentMethod != null) {
currentMethodSig = sig;
return new MethodVisitor(Constants.ASM_API) {
public void visitMethodInsn(
int opcode, String owner, String name, String desc, boolean itf) {
if (opcode == Opcodes.INVOKESPECIAL && currentMethodSig != null) {
Signature target = new Signature(name, desc);
if (target.equals(currentMethodSig)) {
rejected.add(currentMethod);
}
currentMethodSig = null;
}
}
};
} else {
return null;
}
}
}
}
......@@ -63,7 +63,7 @@ public class LocalVariablesSorter extends MethodVisitor {
final String desc,
final MethodVisitor mv)
{
super(Opcodes.ASM6, mv);
super(Constants.ASM_API, mv);
state = new State();
Type[] args = Type.getArgumentTypes(desc);
state.nextLocal = ((Opcodes.ACC_STATIC & access) != 0) ? 0 : 1;
......@@ -74,7 +74,7 @@ public class LocalVariablesSorter extends MethodVisitor {
}
public LocalVariablesSorter(LocalVariablesSorter lvs) {
super(Opcodes.ASM6, lvs.mv);
super(Constants.ASM_API, lvs.mv);
state = lvs.state;
firstLocal = lvs.firstLocal;
}
......
......@@ -23,14 +23,11 @@ import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import net.sf.cglib.core.Constants;
import net.sf.cglib.core.Signature;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.Attribute;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
......@@ -84,7 +81,7 @@ class BridgeMethodResolver {
private Signature currentMethod = null;
BridgedFinder(Set eligibleMethods, Map resolved) {
super(Opcodes.ASM6);
super(Constants.ASM_API);
this.resolved = resolved;
this.eligibleMethods = eligibleMethods;
}
......@@ -98,7 +95,7 @@ class BridgeMethodResolver {
Signature sig = new Signature(name, desc);
if (eligibleMethods.remove(sig)) {
currentMethod = sig;
return new MethodVisitor(Opcodes.ASM6) {
return new MethodVisitor(Constants.ASM_API) {
public void visitMethodInsn(int opcode, String owner, String name,
String desc, boolean itf) {
if (opcode == Opcodes.INVOKESPECIAL && currentMethod != null) {
......
......@@ -554,7 +554,7 @@ public class Enhancer extends AbstractClassGenerator
}
CollectionUtils.filter(methods, new RejectModifierPredicate(Constants.ACC_STATIC));
CollectionUtils.filter(methods, new VisibilityPredicate(superclass, true));
CollectionUtils.filter(methods, new DuplicatesPredicate());
CollectionUtils.filter(methods, new DuplicatesPredicate(methods));
CollectionUtils.filter(methods, new RejectModifierPredicate(Constants.ACC_FINAL));
}
......
......@@ -15,12 +15,12 @@
*/
package net.sf.cglib.transform;
import net.sf.cglib.core.Constants;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.Opcodes;
abstract public class AbstractClassTransformer extends ClassTransformer {
protected AbstractClassTransformer() {
super(Opcodes.ASM6);
super(Constants.ASM_API);
}
public void setTarget(ClassVisitor target) {
......
......@@ -15,8 +15,8 @@
*/
package net.sf.cglib.transform;
import net.sf.cglib.core.Constants;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.Opcodes;
public class AnnotationVisitorTee extends AnnotationVisitor {
private AnnotationVisitor av1, av2;
......@@ -30,7 +30,7 @@ public class AnnotationVisitorTee extends AnnotationVisitor {
}
public AnnotationVisitorTee(AnnotationVisitor av1, AnnotationVisitor av2) {
super(Opcodes.ASM6);
super(Constants.ASM_API);
this.av1 = av1;
this.av2 = av2;
}
......
......@@ -15,12 +15,12 @@
*/
package net.sf.cglib.transform;
import net.sf.cglib.core.Constants;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.Opcodes;
public abstract class ClassTransformer extends ClassVisitor {
public ClassTransformer() {
super(Opcodes.ASM6);
super(Constants.ASM_API);
}
public ClassTransformer(int opcode) {
super(opcode);
......
......@@ -15,14 +15,14 @@
*/
package net.sf.cglib.transform;
import net.sf.cglib.core.Constants;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.Opcodes;
public class ClassTransformerTee extends ClassTransformer {
private ClassVisitor branch;
public ClassTransformerTee(ClassVisitor branch) {
super(Opcodes.ASM6);
super(Constants.ASM_API);
this.branch = branch;
}
......
......@@ -15,13 +15,14 @@
*/
package net.sf.cglib.transform;
import net.sf.cglib.core.Constants;
import org.objectweb.asm.*;
public class ClassVisitorTee extends ClassVisitor {
private ClassVisitor cv1, cv2;
public ClassVisitorTee(ClassVisitor cv1, ClassVisitor cv2) {
super(Opcodes.ASM6);
super(Constants.ASM_API);
this.cv1 = cv1;
this.cv2 = cv2;
}
......