Skip to content

Commit

Permalink
optimized code for ASMSerializerFactory
Browse files Browse the repository at this point in the history
  • Loading branch information
wenshao committed May 2, 2016
1 parent 1b4b1cc commit 4cdf425
Showing 1 changed file with 50 additions and 46 deletions.
Expand Up @@ -39,11 +39,15 @@ public class ASMSerializerFactory implements Opcodes {

private final AtomicLong seed = new AtomicLong();

static final String JSONSerializer = type(JSONSerializer.class);
static final String SerializeWriter = type(SerializeWriter.class);
static final String JavaBeanSerializer = type(JavaBeanSerializer.class);
static final String JavaBeanSerializer_desc = "L" + type(JavaBeanSerializer.class) + ";";
static final String SerialContext_desc = desc(SerialContext.class);
static final String JSONSerializer = type(JSONSerializer.class);
static final String ObjectSerializer = type(ObjectSerializer.class);
static final String ObjectSerializer_desc = "L" + ObjectSerializer + ";";
static final String SerializeWriter = type(SerializeWriter.class);
static final String SerializeWriter_desc = "L" + SerializeWriter + ";";
static final String JavaBeanSerializer = type(JavaBeanSerializer.class);
static final String JavaBeanSerializer_desc = "L" + type(JavaBeanSerializer.class) + ";";
static final String SerialContext_desc = desc(SerialContext.class);
static final String SerializeFilterable_desc = desc(SerializeFilterable.class);

static class Context {

Expand Down Expand Up @@ -174,8 +178,8 @@ public ObjectSerializer createJavaBeanSerializer(Class<?> clazz, Map<String, Str
cw.visit(V1_5 //
, ACC_PUBLIC + ACC_SUPER //
, classNameType //
, type(JavaBeanSerializer.class) //
, new String[] { type(ObjectSerializer.class) } //
, JavaBeanSerializer //
, new String[] { ObjectSerializer } //
);

for (FieldInfo fieldInfo : getters) {
Expand All @@ -190,18 +194,18 @@ public ObjectSerializer createJavaBeanSerializer(Class<?> clazz, Map<String, Str

if (List.class.isAssignableFrom(fieldInfo.fieldClass)) {
new FieldWriter(cw, ACC_PUBLIC, fieldInfo.name + "_asm_list_item_ser_",
desc(ObjectSerializer.class)) //
.visitEnd();
ObjectSerializer_desc) //
.visitEnd();
}

new FieldWriter(cw, ACC_PUBLIC, fieldInfo.name + "_asm_ser_", desc(ObjectSerializer.class)) //
new FieldWriter(cw, ACC_PUBLIC, fieldInfo.name + "_asm_ser_", ObjectSerializer_desc) //
.visitEnd();
}

MethodVisitor mw = new MethodWriter(cw, ACC_PUBLIC, "<init>", "()V", null, null);
mw.visitVarInsn(ALOAD, 0);
mw.visitLdcInsn(com.alibaba.fastjson.asm.Type.getType(desc(clazz)));
mw.visitMethodInsn(INVOKESPECIAL, type(JavaBeanSerializer.class), "<init>", "(Ljava/lang/Class;)V");
mw.visitMethodInsn(INVOKESPECIAL, JavaBeanSerializer, "<init>", "(Ljava/lang/Class;)V");

// init _asm_fieldType
for (int i = 0; i < getters.size(); ++i) {
Expand Down Expand Up @@ -274,7 +278,7 @@ public ObjectSerializer createJavaBeanSerializer(Class<?> clazz, Map<String, Str
);

mw.visitVarInsn(ALOAD, Context.serializer);
mw.visitFieldInsn(GETFIELD, JSONSerializer, "out", desc(SerializeWriter.class));
mw.visitFieldInsn(GETFIELD, JSONSerializer, "out", SerializeWriter_desc);
mw.visitVarInsn(ASTORE, context.var("out"));

if ((!nativeSorted) //
Expand Down Expand Up @@ -361,7 +365,7 @@ public ObjectSerializer createJavaBeanSerializer(Class<?> clazz, Map<String, Str
null, new String[] { "java/io/IOException" });

mw.visitVarInsn(ALOAD, Context.serializer);
mw.visitFieldInsn(GETFIELD, JSONSerializer, "out", desc(SerializeWriter.class));
mw.visitFieldInsn(GETFIELD, JSONSerializer, "out", SerializeWriter_desc);
mw.visitVarInsn(ASTORE, context.var("out"));

mw.visitVarInsn(ALOAD, Context.obj); // obj
Expand Down Expand Up @@ -401,7 +405,7 @@ public ObjectSerializer createJavaBeanSerializer(Class<?> clazz, Map<String, Str
null, new String[] { "java/io/IOException" });

mw.visitVarInsn(ALOAD, Context.serializer);
mw.visitFieldInsn(GETFIELD, JSONSerializer, "out", desc(SerializeWriter.class));
mw.visitFieldInsn(GETFIELD, JSONSerializer, "out", SerializeWriter_desc);
mw.visitVarInsn(ASTORE, context.var("out"));

mw.visitVarInsn(ALOAD, Context.obj); // obj
Expand Down Expand Up @@ -618,11 +622,11 @@ private void generateWriteAsArray(Class<?> clazz, MethodVisitor mw, List<FieldIn

if (context.writeDirect) {
mw.visitVarInsn(ALOAD, context.var("list_item_desc"));
mw.visitTypeInsn(INSTANCEOF, type(JavaBeanSerializer.class));
mw.visitTypeInsn(INSTANCEOF, JavaBeanSerializer);
mw.visitJumpInsn(IFEQ, instanceOfElse_);

mw.visitVarInsn(ALOAD, context.var("list_item_desc"));
mw.visitTypeInsn(CHECKCAST, type(JavaBeanSerializer.class)); // cast
mw.visitTypeInsn(CHECKCAST, JavaBeanSerializer); // cast
mw.visitVarInsn(ALOAD, Context.serializer);
mw.visitVarInsn(ALOAD, context.var("list_item")); // object
if (context.nonContext) { // fieldName
Expand Down Expand Up @@ -652,7 +656,7 @@ private void generateWriteAsArray(Class<?> clazz, MethodVisitor mw, List<FieldIn
}
mw.visitLdcInsn(com.alibaba.fastjson.asm.Type.getType(desc(elementClass))); // fieldType
mw.visitLdcInsn(fieldInfo.serialzeFeatures); // features
mw.visitMethodInsn(INVOKEINTERFACE, type(ObjectSerializer.class), "write", //
mw.visitMethodInsn(INVOKEINTERFACE, ObjectSerializer, "write", //
"(L" + JSONSerializer + ";Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/reflect/Type;I)V");
mw.visitLabel(instanceOfEnd_);
mw.visitJumpInsn(GOTO, forItemClassIfEnd_);
Expand Down Expand Up @@ -720,11 +724,11 @@ private void generateWriteAsArray(Class<?> clazz, MethodVisitor mw, List<FieldIn
Label instanceOfElse_ = new Label(), instanceOfEnd_ = new Label();
if (context.writeDirect && Modifier.isPublic(fieldClass.getModifiers())) {
mw.visitVarInsn(ALOAD, context.var("fied_ser"));
mw.visitTypeInsn(INSTANCEOF, type(JavaBeanSerializer.class));
mw.visitTypeInsn(INSTANCEOF, JavaBeanSerializer);
mw.visitJumpInsn(IFEQ, instanceOfElse_);

mw.visitVarInsn(ALOAD, context.var("fied_ser"));
mw.visitTypeInsn(CHECKCAST, type(JavaBeanSerializer.class)); // cast
mw.visitTypeInsn(CHECKCAST, JavaBeanSerializer); // cast
mw.visitVarInsn(ALOAD, Context.serializer);
mw.visitVarInsn(ALOAD, context.var("field_" + fieldInfo.fieldClass.getName()));
mw.visitVarInsn(ALOAD, Context.fieldName);
Expand All @@ -742,7 +746,7 @@ private void generateWriteAsArray(Class<?> clazz, MethodVisitor mw, List<FieldIn
mw.visitVarInsn(ALOAD, Context.fieldName);
mw.visitLdcInsn(com.alibaba.fastjson.asm.Type.getType(desc(fieldClass))); // fieldType
mw.visitLdcInsn(fieldInfo.serialzeFeatures); // features
mw.visitMethodInsn(INVOKEINTERFACE, type(ObjectSerializer.class), "write", //
mw.visitMethodInsn(INVOKEINTERFACE, ObjectSerializer, "write", //
"(L" + JSONSerializer + ";Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/reflect/Type;I)V");
mw.visitLabel(instanceOfEnd_);
mw.visitJumpInsn(GOTO, classIfEnd_);
Expand Down Expand Up @@ -966,14 +970,12 @@ private void generateWriteMethod(Class<?> clazz, MethodVisitor mw, List<FieldInf

mw.visitVarInsn(ALOAD, Context.serializer);
mw.visitVarInsn(ALOAD, 0);
mw.visitMethodInsn(INVOKEVIRTUAL, JSONSerializer, "checkValue",
"(" + desc(SerializeFilterable.class) + ")Z");
mw.visitMethodInsn(INVOKEVIRTUAL, JSONSerializer, "checkValue", "(" + SerializeFilterable_desc + ")Z");
mw.visitVarInsn(ISTORE, context.var("checkValue"));

mw.visitVarInsn(ALOAD, Context.serializer);
mw.visitVarInsn(ALOAD, 0);
mw.visitMethodInsn(INVOKEVIRTUAL, JSONSerializer, "hasNameFilters",
"(" + desc(SerializeFilterable.class) + ")Z");
mw.visitMethodInsn(INVOKEVIRTUAL, JSONSerializer, "hasNameFilters", "(" + SerializeFilterable_desc + ")Z");
mw.visitVarInsn(ISTORE, context.var("hasNameFilters"));
}

Expand Down Expand Up @@ -1417,11 +1419,11 @@ private void _list(Class<?> clazz, MethodVisitor mw, FieldInfo fieldInfo, Contex
"writeDirectNonContext" //
: "write";
mw.visitVarInsn(ALOAD, context.var("list_item_desc"));
mw.visitTypeInsn(INSTANCEOF, type(JavaBeanSerializer.class));
mw.visitTypeInsn(INSTANCEOF, JavaBeanSerializer);
mw.visitJumpInsn(IFEQ, instanceOfElse_);

mw.visitVarInsn(ALOAD, context.var("list_item_desc"));
mw.visitTypeInsn(CHECKCAST, type(JavaBeanSerializer.class)); // cast
mw.visitTypeInsn(CHECKCAST, JavaBeanSerializer); // cast
mw.visitVarInsn(ALOAD, Context.serializer);
mw.visitVarInsn(ALOAD, context.var("list_item")); // object
if (context.nonContext) { // fieldName
Expand Down Expand Up @@ -1449,7 +1451,7 @@ private void _list(Class<?> clazz, MethodVisitor mw, FieldInfo fieldInfo, Contex
}
mw.visitLdcInsn(com.alibaba.fastjson.asm.Type.getType(desc(elementClass))); // fieldType
mw.visitLdcInsn(fieldInfo.serialzeFeatures); // features
mw.visitMethodInsn(INVOKEINTERFACE, type(ObjectSerializer.class), "write", //
mw.visitMethodInsn(INVOKEINTERFACE, ObjectSerializer, "write", //
"(L" + JSONSerializer + ";Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/reflect/Type;I)V");

mw.visitLabel(instanceOfEnd_);
Expand Down Expand Up @@ -1535,7 +1537,7 @@ private void _nameApply(MethodVisitor mw, FieldInfo property, Context context, L
mw.visitVarInsn(ALOAD, Context.obj);
mw.visitVarInsn(ALOAD, Context.fieldName);
mw.visitMethodInsn(INVOKEVIRTUAL, JSONSerializer, "applyName",
"(" + desc(SerializeFilterable.class) + "Ljava/lang/Object;Ljava/lang/String;)Z");
"(" + SerializeFilterable_desc + "Ljava/lang/Object;Ljava/lang/String;)Z");
mw.visitJumpInsn(IFEQ, _end);

_labelApply(mw, property, context, _end);
Expand All @@ -1556,7 +1558,7 @@ private void _labelApply(MethodVisitor mw, FieldInfo property, Context context,
mw.visitVarInsn(ALOAD, 0); // this
mw.visitLdcInsn(property.label);
mw.visitMethodInsn(INVOKEVIRTUAL, JSONSerializer, "applyLabel",
"(" + desc(SerializeFilterable.class) + "Ljava/lang/String;)Z");
"(" + SerializeFilterable_desc + "Ljava/lang/String;)Z");
mw.visitJumpInsn(IFEQ, _end);
}

Expand Down Expand Up @@ -1587,7 +1589,9 @@ private void _writeObject(MethodVisitor mw, FieldInfo fieldInfo, Context context
_writeFieldName(mw, context);

Label classIfEnd_ = new Label(), classIfElse_ = new Label();
if (Modifier.isPublic(fieldClass.getModifiers()) && !ParserConfig.isPrimitive(fieldClass)) {
if (Modifier.isPublic(fieldClass.getModifiers()) //
&& !ParserConfig.isPrimitive(fieldClass) //
) {
mw.visitVarInsn(ALOAD, context.var("object"));
mw.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;");
mw.visitLdcInsn(com.alibaba.fastjson.asm.Type.getType(desc(fieldClass)));
Expand All @@ -1598,15 +1602,15 @@ private void _writeObject(MethodVisitor mw, FieldInfo fieldInfo, Context context

Label instanceOfElse_ = new Label(), instanceOfEnd_ = new Label();
mw.visitVarInsn(ALOAD, context.var("fied_ser"));
mw.visitTypeInsn(INSTANCEOF, type(JavaBeanSerializer.class));
mw.visitTypeInsn(INSTANCEOF, JavaBeanSerializer);
mw.visitJumpInsn(IFEQ, instanceOfElse_);

String writeMethodName = context.nonContext && context.writeDirect ? //
"writeDirectNonContext" //
: "write";

mw.visitVarInsn(ALOAD, context.var("fied_ser"));
mw.visitTypeInsn(CHECKCAST, type(JavaBeanSerializer.class)); // cast
mw.visitTypeInsn(CHECKCAST, JavaBeanSerializer); // cast
mw.visitVarInsn(ALOAD, Context.serializer);
mw.visitVarInsn(ALOAD, context.var("object"));
mw.visitVarInsn(ALOAD, Context.fieldName);
Expand All @@ -1628,7 +1632,7 @@ private void _writeObject(MethodVisitor mw, FieldInfo fieldInfo, Context context
mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_fieldType",
"Ljava/lang/reflect/Type;");
mw.visitLdcInsn(fieldInfo.serialzeFeatures); // features
mw.visitMethodInsn(INVOKEINTERFACE, type(ObjectSerializer.class), "write", //
mw.visitMethodInsn(INVOKEINTERFACE, ObjectSerializer, "write", //
"(L" + JSONSerializer + ";Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/reflect/Type;I)V");

mw.visitLabel(instanceOfEnd_);
Expand Down Expand Up @@ -1678,7 +1682,7 @@ private void _before(MethodVisitor mw, Context context) {
mw.visitVarInsn(ALOAD, Context.obj);
mw.visitVarInsn(ILOAD, context.var("seperator"));
mw.visitMethodInsn(INVOKEVIRTUAL, JSONSerializer, "writeBefore",
"(" + desc(SerializeFilterable.class) + "Ljava/lang/Object;C)C");
"(" + SerializeFilterable_desc + "Ljava/lang/Object;C)C");
mw.visitVarInsn(ISTORE, context.var("seperator"));
}

Expand All @@ -1688,7 +1692,7 @@ private void _after(MethodVisitor mw, Context context) {
mw.visitVarInsn(ALOAD, 2); // obj
mw.visitVarInsn(ILOAD, context.var("seperator"));
mw.visitMethodInsn(INVOKEVIRTUAL, JSONSerializer, "writeAfter",
"(" + desc(SerializeFilterable.class) + "Ljava/lang/Object;C)C");
"(" + SerializeFilterable_desc + "Ljava/lang/Object;C)C");
mw.visitVarInsn(ISTORE, context.var("seperator"));
}

Expand Down Expand Up @@ -1779,7 +1783,7 @@ private void _apply(MethodVisitor mw, FieldInfo property, Context context) {
mw.visitVarInsn(ALOAD, context.var("object"));
}
mw.visitMethodInsn(INVOKEVIRTUAL, JSONSerializer,
"apply", "(" + desc(SerializeFilterable.class)
"apply", "(" + SerializeFilterable_desc
+ "Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)Z");
}

Expand Down Expand Up @@ -1874,7 +1878,7 @@ private void _processValue(MethodVisitor mw, FieldInfo fieldInfo, Context contex
}

mw.visitMethodInsn(INVOKEVIRTUAL, JSONSerializer, "processValue",
"(" + desc(SerializeFilterable.class) //
"(" + SerializeFilterable_desc //
+ desc(BeanContext.class) //
+ "Ljava/lang/Object;Ljava/lang/String;" //
+ valueDesc + ")Ljava/lang/Object;");
Expand Down Expand Up @@ -1940,7 +1944,7 @@ private void _processKey(MethodVisitor mw, FieldInfo property, Context context)
}

mw.visitMethodInsn(INVOKEVIRTUAL, JSONSerializer,
"processKey", "(" + desc(SerializeFilterable.class)
"processKey", "(" + SerializeFilterable_desc
+ "Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/String;");

mw.visitVarInsn(ASTORE, Context.fieldName);
Expand Down Expand Up @@ -2029,42 +2033,42 @@ private void _getListFieldItemSer(Context context, MethodVisitor mw, FieldInfo f
Label notNull_ = new Label();
mw.visitVarInsn(ALOAD, 0);
mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_list_item_ser_",
desc(ObjectSerializer.class));
ObjectSerializer_desc);
mw.visitJumpInsn(IFNONNULL, notNull_);

mw.visitVarInsn(ALOAD, 0); // this
mw.visitVarInsn(ALOAD, Context.serializer);
mw.visitLdcInsn(com.alibaba.fastjson.asm.Type.getType(desc(itemType)));
mw.visitMethodInsn(INVOKEVIRTUAL, JSONSerializer, "getObjectWriter",
"(Ljava/lang/Class;)" + desc(ObjectSerializer.class));
"(Ljava/lang/Class;)" + ObjectSerializer_desc);

mw.visitFieldInsn(PUTFIELD, context.className, fieldInfo.name + "_asm_list_item_ser_",
desc(ObjectSerializer.class));
ObjectSerializer_desc);

mw.visitLabel(notNull_);

mw.visitVarInsn(ALOAD, 0);
mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_list_item_ser_",
desc(ObjectSerializer.class));
ObjectSerializer_desc);
}

private void _getFieldSer(Context context, MethodVisitor mw, FieldInfo fieldInfo) {
Label notNull_ = new Label();
mw.visitVarInsn(ALOAD, 0);
mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_ser_", desc(ObjectSerializer.class));
mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_ser_", ObjectSerializer_desc);
mw.visitJumpInsn(IFNONNULL, notNull_);

mw.visitVarInsn(ALOAD, 0); // this
mw.visitVarInsn(ALOAD, Context.serializer);
mw.visitLdcInsn(com.alibaba.fastjson.asm.Type.getType(desc(fieldInfo.fieldClass)));
mw.visitMethodInsn(INVOKEVIRTUAL, JSONSerializer, "getObjectWriter",
"(Ljava/lang/Class;)" + desc(ObjectSerializer.class));
"(Ljava/lang/Class;)" + ObjectSerializer_desc);

mw.visitFieldInsn(PUTFIELD, context.className, fieldInfo.name + "_asm_ser_", desc(ObjectSerializer.class));
mw.visitFieldInsn(PUTFIELD, context.className, fieldInfo.name + "_asm_ser_", ObjectSerializer_desc);

mw.visitLabel(notNull_);

mw.visitVarInsn(ALOAD, 0);
mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_ser_", desc(ObjectSerializer.class));
mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_ser_", ObjectSerializer_desc);
}
}

0 comments on commit 4cdf425

Please sign in to comment.