Search in sources :

Example 1 with ValueHolderReplacementVisitor

use of org.apache.drill.exec.compile.bytecode.ValueHolderReplacementVisitor in project drill by apache.

the class MergeAdapter method getMergedClass.

public static MergedClassResult getMergedClass(final ClassSet set, final byte[] precompiledClass, ClassNode generatedClass, final boolean scalarReplace) {
    if (verifyBytecode) {
        if (!AsmUtil.isClassBytesOk(logger, "precompiledClass", precompiledClass)) {
            throw new IllegalStateException("Problem found in precompiledClass");
        }
        if ((generatedClass != null) && !AsmUtil.isClassOk(logger, "generatedClass", generatedClass)) {
            throw new IllegalStateException("Problem found in generatedClass");
        }
    }
    /*
     * Setup adapters for merging, remapping class names and class writing. This is done in
     * reverse order of how they will be evaluated.
     */
    final RemapClasses re = new RemapClasses(set);
    try {
        if (scalarReplace && generatedClass != null) {
            if (logger.isDebugEnabled()) {
                AsmUtil.logClass(logger, "generated " + set.generated.dot, generatedClass);
            }
            final ClassNode generatedMerged = new ClassNode();
            ClassVisitor mergeGenerator = generatedMerged;
            if (verifyBytecode) {
                mergeGenerator = new DrillCheckClassAdapter(CompilationConfig.ASM_API_VERSION, new CheckClassVisitorFsm(CompilationConfig.ASM_API_VERSION, generatedMerged), true);
            }
            /*
         * Even though we're effectively transforming-creating a new class in mergeGenerator,
         * there's no way to pass in ClassWriter.COMPUTE_MAXS, which would save us from having
         * to figure out stack size increases on our own. That gets handled by the
         * InstructionModifier (from inside ValueHolderReplacement > ScalarReplacementNode).
         */
            generatedClass.accept(new ValueHolderReplacementVisitor(mergeGenerator, verifyBytecode));
            if (verifyBytecode) {
                if (!AsmUtil.isClassOk(logger, "generatedMerged", generatedMerged)) {
                    throw new IllegalStateException("Problem found with generatedMerged");
                }
            }
            generatedClass = generatedMerged;
        }
        final ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
        ClassVisitor writerVisitor = writer;
        if (verifyBytecode) {
            writerVisitor = new DrillCheckClassAdapter(CompilationConfig.ASM_API_VERSION, new CheckClassVisitorFsm(CompilationConfig.ASM_API_VERSION, writerVisitor), true);
        }
        ClassVisitor remappingAdapter = new RemappingClassAdapter(writerVisitor, re);
        if (verifyBytecode) {
            remappingAdapter = new DrillCheckClassAdapter(CompilationConfig.ASM_API_VERSION, new CheckClassVisitorFsm(CompilationConfig.ASM_API_VERSION, remappingAdapter), true);
        }
        ClassVisitor visitor = remappingAdapter;
        if (generatedClass != null) {
            visitor = new MergeAdapter(set, remappingAdapter, generatedClass);
        }
        ClassReader tReader = new ClassReader(precompiledClass);
        tReader.accept(visitor, ClassReader.SKIP_FRAMES);
        byte[] outputClass = writer.toByteArray();
        if (logger.isDebugEnabled()) {
            AsmUtil.logClassFromBytes(logger, "merged " + set.generated.dot, outputClass);
        }
        return new MergedClassResult(outputClass, re.getInnerClasses());
    } catch (Error | RuntimeException e) {
        logger.error("Failure while merging classes.", e);
        AsmUtil.logClass(logger, "generatedClass", generatedClass);
        throw e;
    }
}
Also used : ClassNode(org.objectweb.asm.tree.ClassNode) ClassVisitor(org.objectweb.asm.ClassVisitor) ValueHolderReplacementVisitor(org.apache.drill.exec.compile.bytecode.ValueHolderReplacementVisitor) ClassWriter(org.objectweb.asm.ClassWriter) RemappingClassAdapter(org.objectweb.asm.commons.RemappingClassAdapter) ClassReader(org.objectweb.asm.ClassReader)

Aggregations

ValueHolderReplacementVisitor (org.apache.drill.exec.compile.bytecode.ValueHolderReplacementVisitor)1 ClassReader (org.objectweb.asm.ClassReader)1 ClassVisitor (org.objectweb.asm.ClassVisitor)1 ClassWriter (org.objectweb.asm.ClassWriter)1 RemappingClassAdapter (org.objectweb.asm.commons.RemappingClassAdapter)1 ClassNode (org.objectweb.asm.tree.ClassNode)1