Search in sources :

Example 26 with ConstantPoolGen

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

the class ReplaceAtomicAnnotation method visitJavaClass.

public void visitJavaClass(JavaClass clazz) {
    super.visitJavaClass(clazz);
    Method[] methods = clazz.getMethods();
    for (int i = 0; i < methods.length; i++) {
        for (Attribute a : methods[i].getAttributes()) {
            if (a instanceof AnnotationAttribute) {
                if (((AnnotationAttribute) a).hasAtomicAnnotation()) {
                    ConstantPoolGen cpoolgen = new ConstantPoolGen(clazz.getConstantPool());
                    Method nm = transform(methods[i], clazz, cpoolgen);
                    OldMethodInfo mi = getCli().getMethodInfo(nm.getName() + nm.getSignature());
                    // set new method also in MethodInfo
                    mi.setMethod(nm);
                    methods[i] = nm;
                    clazz.setConstantPool(cpoolgen.getFinalConstantPool());
                    System.out.println("RTTM: transformed atomic method " + clazz.getClassName() + "." + nm.getName() + nm.getSignature());
                }
            }
        }
    }
}
Also used : ConstantPoolGen(org.apache.bcel.generic.ConstantPoolGen) Attribute(org.apache.bcel.classfile.Attribute) AnnotationAttribute(com.jopdesign.common.bcel.AnnotationAttribute) Method(org.apache.bcel.classfile.Method) AnnotationAttribute(com.jopdesign.common.bcel.AnnotationAttribute)

Example 27 with ConstantPoolGen

use of org.apache.bcel.generic.ConstantPoolGen 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)

Example 28 with ConstantPoolGen

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

the class ObjectCacheAnalysis method getFieldIndex.

/**
	 * @return the index of the field accessed by the instruction, or 0 if the instruction
	 * does not access a field
	 */
private static int getFieldIndex(WCETTool p, ControlFlowGraph cfg, InstructionHandle ih) {
    ConstantPoolGen constPool = cfg.getMethodInfo().getConstantPoolGen();
    Instruction instr = ih.getInstruction();
    if (instr instanceof FieldInstruction) {
        FieldInstruction fieldInstr = (FieldInstruction) instr;
        ReferenceType refType = fieldInstr.getReferenceType(constPool);
        if (!(refType instanceof ObjectType)) {
            throw new RuntimeException("getFieldIndex(): Unsupported object kind: " + refType.getClass());
        }
        ObjectType objType = (ObjectType) refType;
        String klassName = objType.getClassName();
        String fieldName = fieldInstr.getFieldName(constPool);
        String fieldSig = fieldInstr.getSignature(constPool);
        return p.getLinkerInfo().getFieldIndex(klassName, fieldName + fieldSig);
    } else {
        return 0;
    }
}
Also used : ConstantPoolGen(org.apache.bcel.generic.ConstantPoolGen) ObjectType(org.apache.bcel.generic.ObjectType) FieldInstruction(org.apache.bcel.generic.FieldInstruction) CallString(com.jopdesign.common.code.CallString) Instruction(org.apache.bcel.generic.Instruction) FieldInstruction(org.apache.bcel.generic.FieldInstruction) ArrayInstruction(org.apache.bcel.generic.ArrayInstruction) ReferenceType(org.apache.bcel.generic.ReferenceType)

Aggregations

ConstantPoolGen (org.apache.bcel.generic.ConstantPoolGen)28 Instruction (org.apache.bcel.generic.Instruction)6 InstructionHandle (org.apache.bcel.generic.InstructionHandle)6 FieldInstruction (org.apache.bcel.generic.FieldInstruction)5 InstructionList (org.apache.bcel.generic.InstructionList)5 CallString (com.jopdesign.common.code.CallString)4 Constant (org.apache.bcel.classfile.Constant)4 Method (org.apache.bcel.classfile.Method)4 ObjectType (org.apache.bcel.generic.ObjectType)4 Type (org.apache.bcel.generic.Type)4 MethodInfo (com.jopdesign.common.MethodInfo)3 AnnotationAttribute (com.jopdesign.common.bcel.AnnotationAttribute)3 ClassRef (com.jopdesign.common.type.ClassRef)3 HashSet (java.util.HashSet)3 Iterator (java.util.Iterator)3 ArrayInstruction (org.apache.bcel.generic.ArrayInstruction)3 BranchInstruction (org.apache.bcel.generic.BranchInstruction)3 MethodGen (org.apache.bcel.generic.MethodGen)3 ClassInfo (com.jopdesign.common.ClassInfo)2 HashedString (com.jopdesign.common.misc.HashedString)2