Search in sources :

Example 1 with LocalVariableInstruction

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

the class InlineHelper method needsNullpointerCheck.

/**
 * Check if an exception must be generated if the 'this' reference is null.
 * This test can return false if
 * <ul><li>There is no 'this' reference</li>
 * <li>The DFA analysis showed that the reference is never null</li>
 * <li>The inlined code will always generate an exception anyway</li>
 * <li>Generating checks has been disabled by configuration</li>
 * </ul>
 * <p>
 * The callstring does not need to start or to end at the method to optimize. However since the callstring is
 * used to check the DFA results if available, the callstring must match what the DFA expects, i.e. if
 * the DFA-results and -callstrings are updated during inlining, this callstring must not include inlined
 * invokes. Contrariwise if the DFA results are not updated during inline, the callstring must contain already
 * inlined invokes.
 * </p>
 *
 * @param callString The callstring including the invokesite of the invokee. The top invokesite does not need to
 *                   refer to an invoke instruction, and the referenced invoker method does not need to
 *                   be the method containing the invoke to inline (e.g. if the invoke to inline has
 *                   been inlined itself). However the callstring needs to match what the DFA expects.
 * @param invokee the devirtualized invokee.
 * @param analyzeCode if false, skip checking the code of the invokee.
 * @return true if a nullpointer check code should be generated.
 */
public boolean needsNullpointerCheck(CallString callString, MethodInfo invokee, boolean analyzeCode) {
    if (inlineConfig.skipNullpointerChecks())
        return false;
    InvokeSite invokeSite = callString.top();
    // check if we have a 'this' reference anyway
    if (invokeSite.isInvokeStatic() || invokeSite.isJVMCall()) {
        return false;
    }
    // TODO check the DFA results if available
    if (jcopter.useDFA()) {
    } else if ("<init>".equals(invokee.getShortName())) {
        // the NP check in this case (and hope that compilers for languages other than Java do the same..)
        return false;
    }
    if (!analyzeCode) {
        return true;
    }
    // check if the code will always throw an exception anyway (without producing any side effects before throwing)
    ValueMapAnalysis analysis = new ValueMapAnalysis(invokee);
    analysis.loadParameters();
    InstructionList list = invokee.getCode().getInstructionList(true, false);
    for (InstructionHandle ih : list.getInstructionHandles()) {
        Instruction instr = ih.getInstruction();
        if (instr instanceof ConstantPushInstruction || instr instanceof LocalVariableInstruction) {
            analysis.transfer(instr);
        } else if (instr instanceof GETFIELD || instr instanceof PUTFIELD || instr instanceof INVOKEVIRTUAL || instr instanceof INVOKEINTERFACE || instr instanceof INVOKESPECIAL) {
            int down = instr.consumeStack(invokee.getConstantPoolGen());
            ValueInfo value = analysis.getValueTable().top(down);
            // the same way as the inlined invoke
            if (value.isThisReference()) {
                return false;
            }
            break;
        } else {
            // we ignore all other instructions (for now..)
            break;
        }
    }
    return true;
}
Also used : ValueMapAnalysis(com.jopdesign.jcopter.analysis.ValueMapAnalysis) InstructionList(org.apache.bcel.generic.InstructionList) PUTFIELD(org.apache.bcel.generic.PUTFIELD) InvokeInstruction(org.apache.bcel.generic.InvokeInstruction) ConstantPushInstruction(org.apache.bcel.generic.ConstantPushInstruction) Instruction(org.apache.bcel.generic.Instruction) FieldInstruction(org.apache.bcel.generic.FieldInstruction) LocalVariableInstruction(org.apache.bcel.generic.LocalVariableInstruction) INVOKESPECIAL(org.apache.bcel.generic.INVOKESPECIAL) InstructionHandle(org.apache.bcel.generic.InstructionHandle) GETFIELD(org.apache.bcel.generic.GETFIELD) INVOKEINTERFACE(org.apache.bcel.generic.INVOKEINTERFACE) ValueInfo(com.jopdesign.common.type.ValueInfo) LocalVariableInstruction(org.apache.bcel.generic.LocalVariableInstruction) InvokeSite(com.jopdesign.common.code.InvokeSite) ConstantPushInstruction(org.apache.bcel.generic.ConstantPushInstruction) INVOKEVIRTUAL(org.apache.bcel.generic.INVOKEVIRTUAL)

Aggregations

InvokeSite (com.jopdesign.common.code.InvokeSite)1 ValueInfo (com.jopdesign.common.type.ValueInfo)1 ValueMapAnalysis (com.jopdesign.jcopter.analysis.ValueMapAnalysis)1 ConstantPushInstruction (org.apache.bcel.generic.ConstantPushInstruction)1 FieldInstruction (org.apache.bcel.generic.FieldInstruction)1 GETFIELD (org.apache.bcel.generic.GETFIELD)1 INVOKEINTERFACE (org.apache.bcel.generic.INVOKEINTERFACE)1 INVOKESPECIAL (org.apache.bcel.generic.INVOKESPECIAL)1 INVOKEVIRTUAL (org.apache.bcel.generic.INVOKEVIRTUAL)1 Instruction (org.apache.bcel.generic.Instruction)1 InstructionHandle (org.apache.bcel.generic.InstructionHandle)1 InstructionList (org.apache.bcel.generic.InstructionList)1 InvokeInstruction (org.apache.bcel.generic.InvokeInstruction)1 LocalVariableInstruction (org.apache.bcel.generic.LocalVariableInstruction)1 PUTFIELD (org.apache.bcel.generic.PUTFIELD)1