Reduces code size for class literal instantiations by using static factory methods. Class and package names are now separately interned again. Patch by: mmastrac Review by: me git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@1535 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JArrayType.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JArrayType.java index 7732c06..82261db 100644 --- a/dev/core/src/com/google/gwt/dev/jjs/ast/JArrayType.java +++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JArrayType.java
@@ -40,6 +40,11 @@ this.dims = dims; } + @Override + public String getClassLiteralFactoryMethod() { + return "Class.createForArray"; + } + public int getDims() { return dims; }
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JClassLiteral.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JClassLiteral.java index 25f07a6..ba4fd33 100644 --- a/dev/core/src/com/google/gwt/dev/jjs/ast/JClassLiteral.java +++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JClassLiteral.java
@@ -15,19 +15,10 @@ */ package com.google.gwt.dev.jjs.ast; -import com.google.gwt.dev.jjs.InternalCompilerException; - /** * Java class literal expression. */ public class JClassLiteral extends JLiteral { - - // Matches constants in our java.lang.Class - private static final int PRIMITIVE = 0x00000001; - private static final int INTERFACE = 0x00000002; - private static final int ARRAY = 0x00000004; - private static final int ENUM = 0x00000008; - private static String getClassName(String fullName) { int pos = fullName.lastIndexOf("."); return fullName.substring(pos + 1); @@ -38,26 +29,7 @@ return fullName.substring(0, pos + 1); } - private static JIntLiteral getTypeBitsLit(JProgram program, JType type) { - int bits; - if (type instanceof JArrayType) { - bits = ARRAY; - } else if (type instanceof JEnumType) { - bits = ENUM; - } else if (type instanceof JClassType) { - bits = 0; - } else if (type instanceof JInterfaceType) { - bits = INTERFACE; - } else if (type instanceof JPrimitiveType) { - bits = PRIMITIVE; - } else { - throw new InternalCompilerException("Unknown kind of type"); - } - return program.getLiteralInt(bits); - } - - private static JExpression getTypeNameLit(JProgram program, JType type) { - JExpression typeNameLit; + private static String getTypeName(JType type) { String typeName; if (type instanceof JArrayType) { typeName = type.getJsniSignatureName().replace('/', '.'); @@ -65,21 +37,7 @@ typeName = type.getName(); } - // Split the full class name into package + class so package strings - // can be merged. - String className = getClassName(typeName); - String packageName = getPackageName(typeName); - if (packageName.length() > 0) { - // use "com.example.foo." + "Foo" - typeNameLit = new JBinaryOperation(program, null, - program.getTypeJavaLangString(), JBinaryOperator.ADD, - program.getLiteralString(packageName), - program.getLiteralString(className)); - } else { - // no package name could be split, just use the full name - typeNameLit = program.getLiteralString(typeName); - } - return typeNameLit; + return typeName; } private JExpression classObjectAllocation; @@ -92,15 +50,15 @@ super(program); refType = type; - JNewInstance classAlloc = new JNewInstance(program, null, - program.getTypeJavaLangClass()); - JMethodCall call = new JMethodCall(program, null, classAlloc, - program.getIndexedMethod("Class.Class")); + String typeName = getTypeName(type); - call.getArgs().add(getTypeNameLit(program, type)); - call.getArgs().add(getTypeBitsLit(program, type)); - - // TODO: enums + JMethod method = program.getIndexedMethod(type.getClassLiteralFactoryMethod()); + assert method != null; + + JMethodCall call = new JMethodCall(program, null, null, + method); + call.getArgs().add(program.getLiteralString(getPackageName(typeName))); + call.getArgs().add(program.getLiteralString(getClassName(typeName))); classObjectAllocation = call; }
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JClassType.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JClassType.java index 210939f..b023c9a 100644 --- a/dev/core/src/com/google/gwt/dev/jjs/ast/JClassType.java +++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JClassType.java
@@ -32,6 +32,11 @@ this.isFinal = isFinal; } + @Override + public String getClassLiteralFactoryMethod() { + return "Class.createForClass"; + } + public boolean isAbstract() { return isAbstract; }
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JEnumType.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JEnumType.java index efce503..ee929e4 100644 --- a/dev/core/src/com/google/gwt/dev/jjs/ast/JEnumType.java +++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JEnumType.java
@@ -34,4 +34,8 @@ // TODO: implement traverse? + @Override + public String getClassLiteralFactoryMethod() { + return "Class.createForEnum"; + } }
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JInterfaceType.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JInterfaceType.java index 328b53e..5a7c9da 100644 --- a/dev/core/src/com/google/gwt/dev/jjs/ast/JInterfaceType.java +++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JInterfaceType.java
@@ -26,6 +26,11 @@ super(program, info, name); } + @Override + public String getClassLiteralFactoryMethod() { + return "Class.createForInterface"; + } + public boolean isAbstract() { return true; }
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JNullType.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JNullType.java index aad4937..bc52521 100644 --- a/dev/core/src/com/google/gwt/dev/jjs/ast/JNullType.java +++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JNullType.java
@@ -15,6 +15,8 @@ */ package com.google.gwt.dev.jjs.ast; +import com.google.gwt.dev.jjs.InternalCompilerException; + /** * Java null reference type. */ @@ -24,6 +26,11 @@ super(program, null, "<null>"); } + @Override + public String getClassLiteralFactoryMethod() { + throw new InternalCompilerException("Cannot get class literal for null type"); + } + public String getJavahSignatureName() { return "N"; }
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JPrimitiveType.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JPrimitiveType.java index 30a1c7e..d6e9aef 100644 --- a/dev/core/src/com/google/gwt/dev/jjs/ast/JPrimitiveType.java +++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JPrimitiveType.java
@@ -33,6 +33,11 @@ this.wrapperTypeName = wrapperTypeName; } + @Override + public String getClassLiteralFactoryMethod() { + return "Class.createForPrimitive"; + } + public String getJavahSignatureName() { return signatureName; }
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JType.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JType.java index c69cc6f..e6232d7 100644 --- a/dev/core/src/com/google/gwt/dev/jjs/ast/JType.java +++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JType.java
@@ -32,6 +32,8 @@ this.defaultValue = defaultValue; } + public abstract String getClassLiteralFactoryMethod(); + public JLiteral getDefaultValue() { return defaultValue; }
diff --git a/user/super/com/google/gwt/emul/java/lang/Class.java b/user/super/com/google/gwt/emul/java/lang/Class.java index 1e4f83b..b0630aa 100644 --- a/user/super/com/google/gwt/emul/java/lang/Class.java +++ b/user/super/com/google/gwt/emul/java/lang/Class.java
@@ -28,17 +28,80 @@ private static final int ARRAY = 0x00000004; private static final int ENUM = 0x00000008; - private final String typeName; - private final int modifiers; + /** + * Create a Class object for an array. + * + * @skip + */ + static Class<?> createForArray(String packageName, String className) { + // Initialize here to avoid method inliner + Class<?> clazz = new Class(); + clazz.typeName = packageName + className; + clazz.modifiers = ARRAY; + return clazz; + } + + /** + * Create a Class object for a class. + * + * @skip + */ + static Class<?> createForClass(String packageName, String className) { + // Initialize here to avoid method inliner + Class<?> clazz = new Class<Object>(); + clazz.typeName = packageName + className; + return clazz; + } + + /** + * Create a Class object for an enum. + * + * @skip + */ + static Class<?> createForEnum(String packageName, String className) { + // Initialize here to avoid method inliner + Class<?> clazz = new Class<Object>(); + clazz.typeName = packageName + className; + clazz.modifiers = ENUM; + return clazz; + } + + /** + * Create a Class object for an interface. + * + * @skip + */ + static Class<?> createForInterface(String packageName, String className) { + // Initialize here to avoid method inliner + Class<?> clazz = new Class<Object>(); + clazz.typeName = packageName + className; + clazz.modifiers = INTERFACE; + return clazz; + } + + /** + * Create a Class object for a primitive. + * + * @skip + */ + static Class<?> createForPrimitive(String packageName, String className) { + // Initialize here to avoid method inliner + Class<?> clazz = new Class<Object>(); + clazz.typeName = packageName + className; + clazz.modifiers = PRIMITIVE; + return clazz; + } + + private int modifiers; + + private String typeName; /** * Not publicly instantiable. * * @skip */ - Class(String typeName, int modifiers) { - this.typeName = typeName; - this.modifiers = modifiers; + private Class() { } public T[] getEnumConstants() {