improve Immutable Object support using asm

This commit is contained in:
高铁
2016-01-08 13:31:44 +08:00
parent a4f9f629d8
commit 8a01882bda
3 changed files with 34 additions and 30 deletions
@@ -438,7 +438,10 @@ public class ParserConfig {
public ObjectDeserializer createJavaBeanDeserializer(Class<?> clazz, Type type) {
boolean asmEnable = this.asmEnable;
if (asmEnable) {
Class<?> superClass = clazz;
Class<?> superClass = DeserializeBeanInfo.getBuilderClass(clazz);
if (superClass == null) {
superClass = clazz;
}
for (;;) {
if (!Modifier.isPublic(superClass.getModifiers())) {
@@ -471,9 +474,6 @@ public class ParserConfig {
}
DeserializeBeanInfo beanInfo = DeserializeBeanInfo.computeSetters(clazz, type);
if (beanInfo.getBuilderClass() != null) {
asmEnable = false;
}
if (asmEnable && beanInfo.getFieldList().size() > 200) {
asmEnable = false;
@@ -539,9 +539,11 @@ public class ParserConfig {
boolean asmEnable = this.asmEnable;
Class<?> clazz = beanInfo.getClazz();
Class<?> builderClass = beanInfo.getBuilderClass();
if (asmEnable) {
Class<?> superClass = clazz;
Class<?> superClass = beanInfo.getBuilderClass();
if (superClass == null) {
superClass = clazz;
}
for (;;) {
if (!Modifier.isPublic(superClass.getModifiers())) {
@@ -556,22 +558,6 @@ public class ParserConfig {
}
}
if (asmEnable && builderClass != null) {
Class<?> superClass = builderClass;
for (;;) {
if (!Modifier.isPublic(superClass.getModifiers())) {
asmEnable = false;
break;
}
superClass = superClass.getSuperclass();
if (superClass == Object.class || superClass == null) {
break;
}
}
}
if (fieldInfo.getFieldClass() == Class.class) {
asmEnable = false;
}
@@ -604,6 +604,13 @@ public class ASMDeserializerFactory implements Opcodes {
_setContext(context, mw);
mw.visitVarInsn(ALOAD, context.var("instance"));
Method buildMethod = context.getBeanInfo().getBuildMethod();
if (buildMethod != null) {
mw.visitMethodInsn(INVOKEVIRTUAL, getType(context.getInstClass()), buildMethod.getName(),
"()" + getDesc(buildMethod.getReturnType()));
}
mw.visitInsn(ARETURN);
mw.visitLabel(reset_);
@@ -646,11 +653,13 @@ public class ASMDeserializerFactory implements Opcodes {
}
private void _createInstance(Context context, MethodVisitor mw) {
Constructor<?> defaultConstructor = context.getBeanInfo().getDefaultConstructor();
DeserializeBeanInfo beanInfo = context.getBeanInfo();
Constructor<?> defaultConstructor = beanInfo.getDefaultConstructor();
if (Modifier.isPublic(defaultConstructor.getModifiers())) {
mw.visitTypeInsn(NEW, getType(context.getClazz()));
mw.visitTypeInsn(NEW, getType(context.getInstClass()));
mw.visitInsn(DUP);
mw.visitMethodInsn(INVOKESPECIAL, getType(context.getClazz()), "<init>", "()V");
mw.visitMethodInsn(INVOKESPECIAL, getType(defaultConstructor.getDeclaringClass()), "<init>", "()V");
mw.visitVarInsn(ASTORE, context.var("instance"));
} else {
@@ -658,7 +667,7 @@ public class ASMDeserializerFactory implements Opcodes {
mw.visitVarInsn(ALOAD, 1);
mw.visitMethodInsn(INVOKESPECIAL, "com/alibaba/fastjson/parser/deserializer/ASMJavaBeanDeserializer", "createInstance",
"(Lcom/alibaba/fastjson/parser/DefaultJSONParser;)Ljava/lang/Object;");
mw.visitTypeInsn(CHECKCAST, getType(context.getClazz())); // cast
mw.visitTypeInsn(CHECKCAST, getType(context.getInstClass())); // cast
mw.visitVarInsn(ASTORE, context.var("instance"));
}
}
@@ -703,7 +712,7 @@ public class ASMDeserializerFactory implements Opcodes {
mw.visitVarInsn(ALOAD, context.var("instance"));
mw.visitVarInsn(LLOAD, context.var(fieldInfo.getName() + "_asm", 2));
if (fieldInfo.getMethod() != null) {
mw.visitMethodInsn(INVOKEVIRTUAL, getType(context.getClazz()), fieldInfo.getMethod().getName(),
mw.visitMethodInsn(INVOKEVIRTUAL, getType(context.getInstClass()), fieldInfo.getMethod().getName(),
getDesc(fieldInfo.getMethod()));
if (!fieldInfo.getMethod().getReturnType().equals(Void.TYPE)) {
mw.visitInsn(POP);
@@ -1245,6 +1254,15 @@ public class ASMDeserializerFactory implements Opcodes {
public Class<?> getClazz() {
return clazz;
}
public Class<?> getInstClass() {
Class<?> instClass = beanInfo.getBuilderClass();
if (instClass == null) {
instClass = clazz;
}
return instClass;
}
public int getVariantCount() {
return variantIndex;
@@ -1338,9 +1356,9 @@ public class ASMDeserializerFactory implements Opcodes {
, "(Lcom/alibaba/fastjson/parser/DefaultJSONParser;Ljava/lang/reflect/Type;)Ljava/lang/Object;",
null, null);
mw.visitTypeInsn(NEW, getType(context.getClazz()));
mw.visitTypeInsn(NEW, getType(context.getInstClass()));
mw.visitInsn(DUP);
mw.visitMethodInsn(INVOKESPECIAL, getType(context.getClazz()), "<init>", "()V");
mw.visitMethodInsn(INVOKESPECIAL, getType(context.getInstClass()), "<init>", "()V");
mw.visitInsn(ARETURN);
mw.visitMaxs(3, 3);
@@ -557,7 +557,7 @@ public class DeserializeBeanInfo {
return parserFeatures;
}
private static Class<?> getBuilderClass(Class<?> clazz) {
public static Class<?> getBuilderClass(Class<?> clazz) {
JSONType type = clazz.getAnnotation(JSONType.class);
if (type == null) {
return null;