Commit 2ffd19af authored by ebruneton's avatar ebruneton
Browse files

added tools to reduce ASM jars size

parent ea49e1e4
...@@ -107,13 +107,23 @@ ...@@ -107,13 +107,23 @@
<!-- =================================== --> <!-- =================================== -->
<target name="compile" depends="init"> <target name="compile" depends="init">
<mkdir dir="${out.build}"/> <mkdir dir="${out.build}/tmp"/>
<javac destdir="${out.build}" optimize="on"> <javac destdir="${out.build}/tmp" optimize="on">
<classpath refid="classpath"/> <classpath>
<pathelement location="${out.build}/tmp"/>
</classpath>
<src path="${src}"/> <src path="${src}"/>
<include name="**/*.java"/> <include name="**/*.java"/>
<exclude name="**/xml/*.java"/> <exclude name="**/xml/*.java"/>
</javac> </javac>
<java classname="org.objectweb.asm.optimizer.Shrinker">
<classpath>
<pathelement location="${out.build}/tmp"/>
</classpath>
<arg value="${src}/org/objectweb/asm/optimizer/shrink.properties"/>
<arg value="${out.build}/tmp"/>
<arg value="${out.build}"/>
</java>
</target> </target>
<!-- =================================== --> <!-- =================================== -->
...@@ -137,6 +147,10 @@ ...@@ -137,6 +147,10 @@
<target name="jar" depends="dist.init,compile"> <target name="jar" depends="dist.init,compile">
<multipleAnt dir="${archive}"/> <multipleAnt dir="${archive}"/>
<java classname="org.objectweb.asm.optimizer.JarOptimizer">
<classpath refid="classpath"/>
<arg value="${out.dist.lib}"/>
</java>
</target> </target>
<target name="jdoc" depends="init,dist.init"> <target name="jdoc" depends="init,dist.init">
......
...@@ -17,7 +17,13 @@ ...@@ -17,7 +17,13 @@
doctitle="ASM Documentation"> doctitle="ASM Documentation">
<sourcepath path="${src}"/> <sourcepath path="${src}"/>
<package name="org.*"/> <package name="org.objectweb.asm"/>
<package name="org.objectweb.asm.attrs"/>
<package name="org.objectweb.asm.tree"/>
<package name="org.objectweb.asm.tree.analysis"/>
<package name="org.objectweb.asm.util"/>
<package name="org.objectweb.asm.util.attrs"/>
<package name="org.objectweb.asm.xml"/>
<link href="${jdk.url}" offline="true" packagelistLoc="${jdoc}"/> <link href="${jdk.url}" offline="true" packagelistLoc="${jdoc}"/>
......
/***
* ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000,2002,2003 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.objectweb.asm.optimizer;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.Type;
/**
* An {@link AnnotationVisitor} that collects the {@link Constant}s of the
* annotations it visits.
*
* @author Eric Bruneton
*/
public class AnnotationConstantsCollector implements AnnotationVisitor {
private AnnotationVisitor av;
private ConstantPool cp;
public AnnotationConstantsCollector (
final AnnotationVisitor av,
final ConstantPool cp)
{
this.av = av;
this.cp = cp;
}
public void visit (final String name, final Object value) {
if (name != null) {
cp.newUTF8(name);
}
if (value instanceof Byte) {
cp.newInteger(((Byte)value).byteValue());
} else if (value instanceof Boolean) {
cp.newInteger(((Boolean)value).booleanValue() ? 1 : 0);
} else if (value instanceof Character) {
cp.newInteger(((Character)value).charValue());
} else if (value instanceof Short) {
cp.newInteger(((Short)value).shortValue());
} else if (value instanceof Type) {
cp.newUTF8(((Type)value).getDescriptor());
} else if (value instanceof byte[]) {
byte[] v = (byte[])value;
for (int i = 0; i < v.length; i++) {
cp.newInteger(v[i]);
}
} else if (value instanceof boolean[]) {
boolean[] v = (boolean[])value;
for (int i = 0; i < v.length; i++) {
cp.newInteger(v[i] ? 1 : 0);
}
} else if (value instanceof short[]) {
short[] v = (short[])value;
for (int i = 0; i < v.length; i++) {
cp.newInteger(v[i]);
}
} else if (value instanceof char[]) {
char[] v = (char[])value;
for (int i = 0; i < v.length; i++) {
cp.newInteger(v[i]);
}
} else if (value instanceof int[]) {
int[] v = (int[])value;
for (int i = 0; i < v.length; i++) {
cp.newInteger(v[i]);
}
} else if (value instanceof long[]) {
long[] v = (long[])value;
for (int i = 0; i < v.length; i++) {
cp.newLong(v[i]);
}
} else if (value instanceof float[]) {
float[] v = (float[])value;
for (int i = 0; i < v.length; i++) {
cp.newFloat(v[i]);
}
} else if (value instanceof double[]) {
double[] v = (double[])value;
for (int i = 0; i < v.length; i++) {
cp.newDouble(v[i]);
}
} else {
cp.newConst(value);
}
av.visit(name, value);
}
public void visitEnum (
final String name,
final String desc,
final String value)
{
if (name != null) {
cp.newUTF8(name);
}
cp.newUTF8(desc);
cp.newUTF8(value);
av.visitEnum(name, desc, value);
}
public AnnotationVisitor visitAnnotation (
final String name,
final String desc)
{
if (name != null) {
cp.newUTF8(name);
}
cp.newUTF8(desc);
return new AnnotationConstantsCollector(av.visitAnnotation(name, desc), cp);
}
public AnnotationVisitor visitArray (final String name) {
if (name != null) {
cp.newUTF8(name);
}
return new AnnotationConstantsCollector(av.visitArray(name), cp);
}
public void visitEnd () {
av.visitEnd();
}
}
/***
* ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000,2002,2003 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.objectweb.asm.optimizer;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.Attribute;
import org.objectweb.asm.ClassAdapter;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
/**
* A {@link ClassVisitor} that collects the {@link Constant}s of the classes
* it visits.
*
* @author Eric Bruneton
*/
public class ClassConstantsCollector extends ClassAdapter {
private ConstantPool cp;
public ClassConstantsCollector (
final ClassVisitor cv,
final ConstantPool cp)
{
super(cv);
this.cp = cp;
}
public void visit (
final int version,
final int access,
final String name,
final String signature,
final String superName,
final String[] interfaces)
{
if ((access & Opcodes.ACC_DEPRECATED) != 0) {
cp.newUTF8("Deprecated");
}
if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
cp.newUTF8("Synthetic");
}
cp.newClass(name);
if (signature != null) {
cp.newUTF8("Signature");
cp.newUTF8(signature);
}
if (superName != null) {
cp.newClass(superName);
}
if (interfaces != null) {
for (int i = 0; i < interfaces.length; ++i) {
cp.newClass(interfaces[i]);
}
}
cv.visit(version, access, name, signature, superName, interfaces);
}
public void visitSource (final String source, final String debug) {
if (source != null) {
cp.newUTF8("SourceFile");
cp.newUTF8(source);
}
if (debug != null) {
cp.newUTF8("SourceDebugExtension");
}
cv.visitSource(source, debug);
}
public void visitOuterClass (
final String owner,
final String name,
final String desc)
{
cp.newUTF8("EnclosingMethod");
cp.newClass(owner);
if (name != null && desc != null) {
cp.newNameType(name, desc);
}
cv.visitOuterClass(owner, name, desc);
}
public AnnotationVisitor visitAnnotation (
final String desc,
final boolean visible)
{
cp.newUTF8(desc);
if (visible) {
cp.newUTF8("RuntimeVisibleAnnotations");
} else {
cp.newUTF8("RuntimeInvisibleAnnotations");
}
return new AnnotationConstantsCollector(cv.visitAnnotation(desc, visible), cp);
}
public void visitAttribute (final Attribute attr) {
// can do nothing
cv.visitAttribute(attr);
}
public void visitInnerClass (
final String name,
final String outerName,
final String innerName,
final int access)
{
cp.newUTF8("InnerClasses");
if (name != null) {
cp.newClass(name);
}
if (outerName != null) {
cp.newClass(outerName);
}
if (innerName != null) {
cp.newClass(innerName);
}
cv.visitInnerClass(name, outerName, innerName, access);
}
public FieldVisitor visitField (
final int access,
final String name,
final String desc,
final String signature,
final Object value)
{
if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
cp.newUTF8("Synthetic");
}
if ((access & Opcodes.ACC_DEPRECATED) != 0) {
cp.newUTF8("Deprecated");
}
cp.newUTF8(name);
cp.newUTF8(desc);
if (signature != null) {
cp.newUTF8("Signature");
cp.newUTF8(signature);
}
if (value != null) {
cp.newConst(value);
}
return new FieldConstantsCollector(cv.visitField(access, name, desc, signature, value), cp);
}
public MethodVisitor visitMethod (
final int access,
final String name,
final String desc,
final String signature,
final String[] exceptions)
{
if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
cp.newUTF8("Synthetic");
}
if ((access & Opcodes.ACC_DEPRECATED) != 0) {
cp.newUTF8("Deprecated");
}
cp.newUTF8(name);
cp.newUTF8(desc);
if (signature != null) {
cp.newUTF8("Signature");
cp.newUTF8(signature);
}
if (exceptions != null) {
cp.newUTF8("Exceptions");
for (int i = 0; i < exceptions.length; ++i) {
cp.newClass(exceptions[i]);
}
}
return new MethodConstantsCollector(
cv.visitMethod(access, name, desc, signature, exceptions), cp);
}
public void visitEnd () {
cv.visitEnd();
}
}
/***
* ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000,2002,2003 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.objectweb.asm.optimizer;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.Attribute;
import org.objectweb.asm.ClassAdapter;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
/**
* A {@link ClassAdapter} that renames fields and methods, and removes debug
* info.
*
* @author Eric Bruneton
*/
public class ClassOptimizer extends ClassAdapter {
private NameMapping mapping;
private String className;
public ClassOptimizer (final ClassVisitor cv, final NameMapping mapping) {
super(cv);
this.mapping = mapping;
}
public String getClassName () {
return className;
}
// --------------------------------------------------------------------------
// Overriden methods
// --------------------------------------------------------------------------
public void visit (
final int version,
final int access,
final String name,
final String signature,
final String superName,
final String[] interfaces)
{
className = name;
cv.visit(
version,
access,
mapping.map(name),
null,
mapping.map(superName),
interfaces);
}
public void visitSource (final String source, final String debug) {
// remove debug info
}
public void visitOuterClass (
final String owner,
final String name,
final String desc)
{
// remove debug info
}
public AnnotationVisitor visitAnnotation (
final String desc,
final boolean visible)
{
throw new UnsupportedOperationException();
}
public void visitAttribute (final Attribute attr) {
// remove non standard attribute
}
public void visitInnerClass (
final String name,
final String outerName,
final String innerName,
final int access)
{
// remove debug info
}
public FieldVisitor visitField (
final int access,
final String name,
final String desc,
final String signature,
final Object value)
{
if ((access & (Opcodes.ACC_PUBLIC | Opcodes.ACC_PROTECTED)) == 0) {
if ((access & Opcodes.ACC_FINAL) != 0 &&
(access & Opcodes.ACC_STATIC) != 0 &&
desc.equals("I"))
{
return null;
}
cv.visitField(
access,
mapping.map(className + "." + name),
mapping.fix(desc),
null,
value);
} else {
cv.visitField(access, name, desc, null, value);
}
return null; // remove debug info
}
public MethodVisitor visitMethod (
final int access,
final String name,
final String desc,
final String signature,
final String[] exceptions)
{
if ((access & (Opcodes.ACC_PUBLIC | Opcodes.ACC_PROTECTED)) == 0) {
return new MethodOptimizer(
cv.visitMethod(
access,
mapping.map(className + "." + name + desc),
mapping.fix(desc),
null,
exceptions), mapping);
} else {
return new MethodOptimizer(
cv.visitMethod(
access,
name,
desc,
null,
exceptions), mapping);
}
}
}