Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  package com.fasterxml.jackson.module.afterburner.deser;
  
  import static org.objectweb.asm.Opcodes.*;
  
  
 import  org.objectweb.asm.ClassWriter;
 import  org.objectweb.asm.MethodVisitor;
 import  org.objectweb.asm.Type;
 
Helper class that tries to generate ValueInstantiator class that calls constructors and/or factory methods directly, instead of using Reflection.
 
 public class CreatorOptimizer
 {
     protected final Class<?> _valueClass;
     
     protected final MyClassLoader _classLoader;
     
     protected final StdValueInstantiator _originalInstantiator;
 
     public CreatorOptimizer(Class<?> valueClassMyClassLoader classLoader,
             StdValueInstantiator orig)
     {
          = valueClass;
          = classLoader;
          = orig;
     }
 
     {
         // for now, only consider need to handle default creator
         AnnotatedWithParams defaultCreator = .getDefaultCreator();
         if (defaultCreator != null) {
             AnnotatedElement elem = defaultCreator.getAnnotated();
             if (elem instanceof Constructor<?>) {
                 return createSubclass((Constructor<?>) elemnull);
             }
             if (elem instanceof Method) {
                 Method m = (Methodelem;
                 if (Modifier.isStatic(m.getModifiers())) {
                     return createSubclass(nullm);
                 }
             }
         }
         return null;
     }
 
     protected ValueInstantiator createSubclass(Constructor<?> ctorMethod factory)
     {
         MyClassLoader loader = ( == null) ?
             new MyClassLoader(.getClassLoader(), true) : ;
         String srcName = .getName() + "$Creator4JacksonDeserializer";
         Class<?> impl = null;
         try {
             impl = loader.loadClass(srcName);
         } catch (ClassNotFoundException e) { }
         if (impl == null) {
             byte[] bytecode = generateOptimized(srcNamectorfactory);
             impl = loader.loadAndResolve(srcNamebytecode);
         }
         ValueInstantiator inst;
         try {
             inst = (ValueInstantiatorimpl.newInstance();
         } catch (Exception e) {
             throw new IllegalStateException("Failed to generate accessor class '"+srcName+"': "+e.getMessage(), e);
         }
         return inst;
     }
 
     protected byte[] generateOptimized(String srcNameConstructor<?> ctorMethod factory)
     {
             ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
             String superClass = internalClassName(OptimizedValueInstantiator.class.getName());
             String generatedClass = internalClassName(srcName);
             
             cw.visit(V1_5, ACC_PUBLIC + ACC_SUPER, generatedClassnullsuperClassnull);
             cw.visitSource(srcName + ".java"null);
 
             // First: must define 2 constructors:
             // (a) default constructor, for creating bogus instance (just calls default instance)
             // (b) copy-constructor which takes StdValueInstantiator instance, passes to superclass
             final String optimizedValueInstDesc = Type.getDescriptor(OptimizedValueInstantiator.class);
             final String stdValueInstDesc = Type.getDescriptor(StdValueInstantiator.class);
 
             // default (no-arg) constructor:
             MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "<init>""()V"nullnull);
            mv.visitCode();
            mv.visitVarInsn(ALOAD, 0);
            mv.visitMethodInsn(INVOKESPECIAL, superClass"<init>""()V");
            mv.visitInsn(RETURN);
            mv.visitMaxs(0, 0);
            mv.visitEnd();
            // then single-arg constructor
            mv = cw.visitMethod(ACC_PUBLIC, "<init>""("+stdValueInstDesc+")V"nullnull);
            mv.visitCode();
            mv.visitVarInsn(ALOAD, 0);
            mv.visitVarInsn(ALOAD, 1);
            mv.visitMethodInsn(INVOKESPECIAL, superClass"<init>""("+stdValueInstDesc+")V");
            mv.visitInsn(RETURN);
            mv.visitMaxs(0, 0);
            mv.visitEnd();
            // and then non-static factory method to use second constructor (implements base-class method)
            // protected abstract OptimizedValueInstantiator with(StdValueInstantiator src);
            mv = cw.visitMethod(ACC_PUBLIC, "with""("
                    +stdValueInstDesc+")"+optimizedValueInstDescnullnull);
            mv.visitCode();
            mv.visitTypeInsn(NEW, generatedClass);
            mv.visitInsn(DUP);
            mv.visitVarInsn(ALOAD, 1);
            mv.visitMethodInsn(INVOKESPECIAL, generatedClass"<init>""("+stdValueInstDesc+")V");
            mv.visitInsn(ARETURN);
            mv.visitMaxs(0, 0);
            mv.visitEnd();
            // And then override: public Object createUsingDefault()
            mv = cw.visitMethod(ACC_PUBLIC, "createUsingDefault""()Ljava/lang/Object;"nullnull);
            mv.visitCode();
            
            if (ctor != null) {
                addCreator(mvctor);
            } else {
                addCreator(mvfactory);
            }
            mv.visitInsn(ARETURN);
            mv.visitMaxs(0, 0);
            mv.visitEnd();
            cw.visitEnd();
            return cw.toByteArray();
    }
    protected void addCreator(MethodVisitor mvConstructor<?> ctor)
    {
        String valueClassInternal = Type.getInternalName(ctor.getDeclaringClass());
        mv.visitTypeInsn(NEW, valueClassInternal);
        mv.visitInsn(DUP);
        mv.visitMethodInsn(INVOKESPECIAL, valueClassInternal"<init>""()V");
    }
    protected void addCreator(MethodVisitor mvMethod factory)
    {
        Class<?> valueClass = factory.getReturnType();
        mv.visitMethodInsn(INVOKESTATIC, Type.getInternalName(factory.getDeclaringClass()),
                factory.getName(), "()"+Type.getDescriptor(valueClass));
    }
New to GrepCode? Check out our FAQ X