Search in sources :

Example 26 with Type

use of org.apache.bcel.generic.Type in project jop by jop-devel.

the class MethodCacheAnalysis method getMissCost.

/**
 * Get miss cost for an edge accessing the method cache
 * @param accessEdge either a SuperInvoke or SuperReturn edge, or an entry edge of the segment analyzed
 * @return maximum miss penalty (in cycles)
 */
private long getMissCost(SuperGraphEdge accessEdge) {
    SuperGraphNode accessed = accessEdge.getTarget();
    ControlFlowGraph cfg = accessed.getCfg();
    if (accessEdge instanceof SuperReturnEdge) {
        /* return edge: return cost */
        Type returnType = accessEdge.getSource().getCfg().getMethodInfo().getType();
        return methodCache.getMissPenaltyOnReturn(cfg.getNumberOfWords(), returnType);
    } else if (accessEdge instanceof SuperInvokeEdge) {
        InstructionHandle invokeIns = ((SuperInvokeEdge) accessEdge).getInvokeNode().getInvokeSite().getInstructionHandle();
        return methodCache.getMissPenaltyOnInvoke(cfg.getNumberOfWords(), invokeIns.getInstruction());
    } else {
        /* entry edge of the segment: can be invoke or return cost */
        return methodCache.getMissPenalty(cfg.getNumberOfWords(), false);
    }
}
Also used : Type(org.apache.bcel.generic.Type) ControlFlowGraph(com.jopdesign.common.code.ControlFlowGraph) SuperReturnEdge(com.jopdesign.common.code.SuperGraph.SuperReturnEdge) SuperGraphNode(com.jopdesign.common.code.SuperGraph.SuperGraphNode) InstructionHandle(org.apache.bcel.generic.InstructionHandle) SuperInvokeEdge(com.jopdesign.common.code.SuperGraph.SuperInvokeEdge)

Example 27 with Type

use of org.apache.bcel.generic.Type in project qpid-broker-j by apache.

the class LDAPSSLSocketFactoryGenerator method createGetDefaultStaticMethod.

/**
 * Create a static method 'getDefault' returning {@link SocketFactory}
 * that creates a new instance of the sub-class and calls its no-argument
 * constructor, the newly created is returned to the caller.
 *
 * @param classGen
 * @param constantPoolGen
 * @param instructionFactory
 */
private static void createGetDefaultStaticMethod(ClassGen classGen, ConstantPoolGen constantPoolGen, InstructionFactory instructionFactory) {
    InstructionList il = new InstructionList();
    String methodName = "getDefault";
    MethodGen mg = new // access flags
    MethodGen(// access flags
    ACC_STATIC | ACC_PUBLIC, // return type
    Type.getType(SSLSocketFactory.class), // argument types - no args
    new Type[0], // arg names - no args
    new String[0], methodName, // method, class
    classGen.getClassName(), il, constantPoolGen);
    il.append(instructionFactory.createNew(classGen.getClassName()));
    il.append(InstructionConst.DUP);
    il.append(instructionFactory.createInvoke(classGen.getClassName(), "<init>", Type.VOID, new Type[] {}, INVOKESPECIAL));
    il.append(InstructionConst.ARETURN);
    mg.setMaxStack();
    classGen.addMethod(mg.getMethod());
    il.dispose();
}
Also used : Type(org.apache.bcel.generic.Type) InstructionList(org.apache.bcel.generic.InstructionList) SSLSocketFactory(javax.net.ssl.SSLSocketFactory) MethodGen(org.apache.bcel.generic.MethodGen)

Example 28 with Type

use of org.apache.bcel.generic.Type in project jop by jop-devel.

the class ValueMapAnalysis method loadParameters.

public void loadParameters() {
    values.clear();
    if (!methodInfo.isStatic()) {
        values.addLocalValue(new ValueInfo(methodInfo));
    }
    int i = 0;
    for (Type type : methodInfo.getArgumentTypes()) {
        values.addLocalValue(new ValueInfo(type, i++));
    }
}
Also used : Type(org.apache.bcel.generic.Type) ArrayType(org.apache.bcel.generic.ArrayType) ValueInfo(com.jopdesign.common.type.ValueInfo)

Example 29 with Type

use of org.apache.bcel.generic.Type in project jop by jop-devel.

the class SimpleInliner method analyzeInvokee.

/**
 * @param cs the callstring from the invoker to the invoke to inline (if recursive). Used to check DFA results.
 * @param invokee the invoked method to analyze
 * @param inlineData the map to populate with the parameters and the instructions to inline.
 * @return true if inlining is possible
 */
private boolean analyzeInvokee(CallString cs, MethodInfo invokee, InlineData inlineData) {
    // we allow loading of parameters, loading of constants, some instruction, and a return
    ValueMapAnalysis values = new ValueMapAnalysis(invokee);
    values.loadParameters();
    InstructionList il = invokee.getCode().getInstructionList(true, false);
    InstructionHandle ih = il.getStart();
    // we should at least have a return instruction, so even for empty methods we should fall through
    // generate the parameter mapping
    int count = 0;
    while (true) {
        Instruction instruction = ih.getInstruction();
        if (instruction instanceof PushInstruction || instruction instanceof NOP) {
            values.transfer(instruction);
            ih = ih.getNext();
            count++;
        } else {
            break;
        }
    }
    // store the mapping
    for (ValueInfo value : values.getValueTable().getStack()) {
        inlineData.addParam(value);
    }
    inlineData.setInlineStart(count);
    // if we do not need an NP check, we can also inline code which does not throw an exception in the same way
    boolean needsNPCheck = helper.needsNullpointerCheck(cs, invokee, false);
    boolean hasNPCheck = false;
    // we allow up to 5 instructions and one return before assuming that the resulting code will be too large
    for (int i = 0; i < 6; i++) {
        // now lets see what we have here as non-push instructions
        Instruction instruction = ih.getInstruction();
        if (instruction instanceof InvokeInstruction) {
            if (inlineData.getInvokeSite() != null) {
                // only inline at most one invoke
                return false;
            }
            InvokeSite is = invokee.getCode().getInvokeSite(ih);
            inlineData.setInvokeSite(is);
            hasNPCheck |= !is.isInvokeStatic();
        } else if (instruction instanceof FieldInstruction) {
            if (instruction instanceof GETFIELD) {
                hasNPCheck |= values.getValueTable().top().isThisReference();
            }
            if (instruction instanceof PUTFIELD) {
                int down = values.getValueTable().top().isContinued() ? 2 : 1;
                hasNPCheck |= values.getValueTable().top(down).isThisReference();
            }
        } else if (instruction instanceof ArithmeticInstruction || instruction instanceof ConversionInstruction || instruction instanceof StackInstruction || instruction instanceof LDC || instruction instanceof LDC2_W || instruction instanceof ARRAYLENGTH || instruction instanceof CHECKCAST || instruction instanceof NOP) {
        // nothing to do, just copy them
        } else if (instruction instanceof ReturnInstruction) {
            if (needsNPCheck && !hasNPCheck) {
                // We were nearly finished.. but NP check test failed
                this.requiresNPCheck++;
                if (logger.isTraceEnabled()) {
                    logger.trace("Not inlining " + invokee + " because it requires a NP check.");
                }
                return false;
            }
            // else we need to add pop instructions
            if (instruction instanceof RETURN) {
                // we do not return anything, so we must empty the stack
                while (values.getValueTable().getStackSize() > 0) {
                    Instruction pop;
                    if (values.getValueTable().top().isContinued()) {
                        pop = new POP2();
                    } else {
                        pop = new POP();
                    }
                    inlineData.addEpilogue(pop);
                    values.transfer(pop);
                }
                return true;
            } else {
                Type type = ((ReturnInstruction) instruction).getType();
                // javac anyway)
                return values.getValueTable().getStackSize() == type.getSize();
            }
        } else {
            // if we encounter an instruction which we do not handle, we do not inline
            unhandledInstructions++;
            if (logger.isTraceEnabled()) {
                logger.trace("Not inlining " + invokee + " because of unhandled instruction " + instruction.toString(invokee.getClassInfo().getConstantPoolGen().getConstantPool()));
            }
            return false;
        }
        // update the stack map since we need it to handle RETURN
        values.transfer(instruction);
        ih = ih.getNext();
    }
    // too many instructions, do not inline
    return false;
}
Also used : ArithmeticInstruction(org.apache.bcel.generic.ArithmeticInstruction) ValueMapAnalysis(com.jopdesign.jcopter.analysis.ValueMapAnalysis) ARRAYLENGTH(org.apache.bcel.generic.ARRAYLENGTH) POP2(org.apache.bcel.generic.POP2) InstructionList(org.apache.bcel.generic.InstructionList) CHECKCAST(org.apache.bcel.generic.CHECKCAST) StackInstruction(org.apache.bcel.generic.StackInstruction) ConversionInstruction(org.apache.bcel.generic.ConversionInstruction) LDC(org.apache.bcel.generic.LDC) InvokeInstruction(org.apache.bcel.generic.InvokeInstruction) StackInstruction(org.apache.bcel.generic.StackInstruction) Instruction(org.apache.bcel.generic.Instruction) FieldInstruction(org.apache.bcel.generic.FieldInstruction) ArithmeticInstruction(org.apache.bcel.generic.ArithmeticInstruction) ConversionInstruction(org.apache.bcel.generic.ConversionInstruction) ReturnInstruction(org.apache.bcel.generic.ReturnInstruction) PushInstruction(org.apache.bcel.generic.PushInstruction) InstructionHandle(org.apache.bcel.generic.InstructionHandle) ReturnInstruction(org.apache.bcel.generic.ReturnInstruction) RETURN(org.apache.bcel.generic.RETURN) LDC2_W(org.apache.bcel.generic.LDC2_W) ValueInfo(com.jopdesign.common.type.ValueInfo) PUTFIELD(org.apache.bcel.generic.PUTFIELD) PushInstruction(org.apache.bcel.generic.PushInstruction) NOP(org.apache.bcel.generic.NOP) POP(org.apache.bcel.generic.POP) InvokeInstruction(org.apache.bcel.generic.InvokeInstruction) GETFIELD(org.apache.bcel.generic.GETFIELD) Type(org.apache.bcel.generic.Type) InvokeSite(com.jopdesign.common.code.InvokeSite) FieldInstruction(org.apache.bcel.generic.FieldInstruction)

Example 30 with Type

use of org.apache.bcel.generic.Type in project jop by jop-devel.

the class SimpleInliner method analyzeInvokeSite.

/**
 * Check if the invokesite can be modified in a way so that the parameters are passed in the correct order
 * @param invokeSite the invokesite to inline.
 * @param invokee the invoked method.
 * @param inlineData the map to store the analyzer results
 * @return true if the prologue can be changed to match the expected behaviour
 */
private boolean analyzeInvokeSite(InvokeSite invokeSite, MethodInfo invokee, InlineData inlineData) {
    MethodInfo invoker = invokeSite.getInvoker();
    ConstantPoolGen invokerCpg = invoker.getConstantPoolGen();
    InstructionHandle invoke = invokeSite.getInstructionHandle();
    // Check epilogue
    Type[] ret = StackHelper.produceStack(invokerCpg, invoke.getInstruction());
    // works if the invoked method returns the same (single) type as the replaced instruction..
    boolean match = (ret.length == 1 && TypeHelper.canAssign(invokee.getType(), ret[0]));
    // return something but doesn't then it is a JVM call and throws an exception.
    if (!match && !invokee.getType().equals(Type.VOID)) {
        return false;
    }
    // Check and build prologue
    Type[] args = StackHelper.consumeStack(invokerCpg, invoke.getInstruction());
    List<Instruction> oldPrologue = new LinkedList<Instruction>();
    int cnt = 0;
    InstructionHandle current = invoke;
    while (cnt < args.length) {
        if (current.hasTargeters()) {
            // stay within the basic block
            break;
        }
        current = current.getPrev();
        Instruction instr = current.getInstruction();
        // we only rearrange push-instructions
        if (!(instr instanceof PushInstruction) || (instr instanceof DUP) || (instr instanceof DUP2)) {
            break;
        }
        // we add this instruction to the old prologue to replace
        cnt++;
        oldPrologue.add(0, instr);
    }
    inlineData.setOldPrologueLength(cnt);
    List<ValueInfo> params = inlineData.getParams();
    // other parameters must be used in the order they are pushed on the stack, we do not rearrange them
    int offset = args.length - cnt;
    for (int i = 0; i < offset; i++) {
        if (i >= params.size()) {
            Type t = args[i];
            // unused argument, we cannot remove the push instruction so we pop it
            inlineData.addPrologue(t.getSize() == 2 ? new POP2() : new POP());
        } else {
            ValueInfo value = params.get(i);
            int argNum = value.getParamNr();
            if (!invokee.isStatic()) {
                argNum++;
            }
            if (argNum != i) {
                return false;
            }
        }
    }
    // Now, we create a new prologue using the expected argument values and the old push instructions
    for (int i = offset; i < params.size(); i++) {
        ValueInfo value = params.get(i);
        if (value.isThisReference() || value.isParamReference()) {
            int argNum = value.getParamNr();
            if (!invokee.isStatic()) {
                argNum++;
            }
            if (argNum < offset) {
                // loading a param a second time which we do not duplicate, cannot inline this
                return false;
            }
            // To be on the safe side, copy the instruction in case a param is used more than once
            Instruction instr = oldPrologue.get(argNum - offset).copy();
            inlineData.addPrologue(instr);
        } else if (value.isNullReference()) {
            inlineData.addPrologue(InstructionConstants.ACONST_NULL);
        } else if (value.isConstantValue() || value.isStaticFieldReference()) {
            // We need to push a constant on the stack
            Instruction instr = value.getConstantValue().createPushInstruction(invoker.getConstantPoolGen());
            inlineData.addPrologue(instr);
        } else if (!value.isContinued()) {
            throw new AssertionError("Unhandled value type");
        }
    }
    return true;
}
Also used : POP2(org.apache.bcel.generic.POP2) InvokeInstruction(org.apache.bcel.generic.InvokeInstruction) StackInstruction(org.apache.bcel.generic.StackInstruction) Instruction(org.apache.bcel.generic.Instruction) FieldInstruction(org.apache.bcel.generic.FieldInstruction) ArithmeticInstruction(org.apache.bcel.generic.ArithmeticInstruction) ConversionInstruction(org.apache.bcel.generic.ConversionInstruction) ReturnInstruction(org.apache.bcel.generic.ReturnInstruction) PushInstruction(org.apache.bcel.generic.PushInstruction) PushInstruction(org.apache.bcel.generic.PushInstruction) InstructionHandle(org.apache.bcel.generic.InstructionHandle) LinkedList(java.util.LinkedList) POP(org.apache.bcel.generic.POP) ConstantPoolGen(org.apache.bcel.generic.ConstantPoolGen) Type(org.apache.bcel.generic.Type) DUP2(org.apache.bcel.generic.DUP2) ValueInfo(com.jopdesign.common.type.ValueInfo) MethodInfo(com.jopdesign.common.MethodInfo) DUP(org.apache.bcel.generic.DUP)

Aggregations

Type (org.apache.bcel.generic.Type)42 BugType (com.mebigfatguy.fbcontrib.utils.BugType)9 ObjectType (org.apache.bcel.generic.ObjectType)9 FieldInstruction (org.apache.bcel.generic.FieldInstruction)8 InstructionHandle (org.apache.bcel.generic.InstructionHandle)8 InvokeInstruction (org.apache.bcel.generic.InvokeInstruction)8 JavaClass (org.apache.bcel.classfile.JavaClass)7 Instruction (org.apache.bcel.generic.Instruction)7 InstructionList (org.apache.bcel.generic.InstructionList)7 ReferenceType (org.apache.bcel.generic.ReferenceType)7 Method (org.apache.bcel.classfile.Method)6 GETFIELD (org.apache.bcel.generic.GETFIELD)6 PUTFIELD (org.apache.bcel.generic.PUTFIELD)6 ConstantPoolGen (org.apache.bcel.generic.ConstantPoolGen)5 MethodGen (org.apache.bcel.generic.MethodGen)5 BranchInstruction (org.apache.bcel.generic.BranchInstruction)4 GETSTATIC (org.apache.bcel.generic.GETSTATIC)4 LDC (org.apache.bcel.generic.LDC)4 LoadInstruction (org.apache.bcel.generic.LoadInstruction)4 PUTSTATIC (org.apache.bcel.generic.PUTSTATIC)4