public InstrumentationResult instrument ( byte [ ] input , InstrumentationSettings settings ) { Validate . notNull ( input ) ; Validate . notNull ( settings ) ; Validate . isTrue ( input . length > 0 ) ; // Read class as tree model -- because we're using SimpleClassNode, JSR blocks get inlined ClassReader cr = new ClassReader ( input ) ; ClassNode classNode = new SimpleClassNode ( ) ; cr . accept ( classNode , 0 ) ; // Recompute stackmap frames. classNode = reconstructStackMapFrames ( classNode ) ; // Apply passes. InstrumentationPass [ ] passes = new InstrumentationPass [ ] { new IdentifyInstrumentationPass ( ) , // identify methods for instrumentation new AnalyzeInstrumentationPass ( ) , // analyze methods for instrumentation new SerializationPreInstrumentationPass ( ) , // create .coroutinesinfo files for methods to be instrumented new PerformInstrumentationPass ( ) , // perform instrumentation of methods new SerializationPostInstrumentationPass ( ) , // add fields needed for serializer/deserializer to identify versioning info new AutoSerializableInstrumentationPass ( ) // make class serializable + give serializationuid } ; InstrumentationState passState = new InstrumentationState ( settings , classRepo ) ; for ( InstrumentationPass pass : passes ) { pass . pass ( classNode , passState ) ; ControlFlag controlFlag = passState . control ( ) ; switch ( controlFlag ) { case CONTINUE_INSTRUMENT : break ; case NO_INSTRUMENT : return new InstrumentationResult ( input ) ; // class should not be instrumented -- return original data. default : throw new IllegalStateException ( ) ; // should never happen } } // Write tree model back out as class -- NOTE: If we get a NegativeArraySizeException on classNode.accept(), it likely means that // we're doing bad things with the stack. So, before writing the class out and returning // it, we call verifyClassIntegrity() to check and make sure everything is okay. // RE-ENABLE ONLY IF JVM COMPLAINS ABOUT INSTRUMENTED CLASSES AND YOU NEED TO DEBUG, KEEP COMMENTED OUT FOR PRODUCTION // verifyClassIntegrity(classNode); ClassWriter cw = new SimpleClassWriter ( ClassWriter . COMPUTE_MAXS | ClassWriter . COMPUTE_FRAMES , classRepo ) ; classNode . accept ( cw ) ; byte [ ] classData = cw . toByteArray ( ) ; Map < String , byte [ ] > extraFiles = passState . extraFiles ( ) ; return new InstrumentationResult ( classData , extraFiles ) ; }
Instruments a class .