Search in sources :

Example 1 with CodeIterator

use of org.hotswap.agent.javassist.bytecode.CodeIterator in project HotswapAgent by HotswapProjects.

the class SubroutineScanner method scan.

public Subroutine[] scan(MethodInfo method) throws BadBytecode {
    CodeAttribute code = method.getCodeAttribute();
    CodeIterator iter = code.iterator();
    subroutines = new Subroutine[code.getCodeLength()];
    subTable.clear();
    done.clear();
    scan(0, iter, null);
    ExceptionTable exceptions = code.getExceptionTable();
    for (int i = 0; i < exceptions.size(); i++) {
        int handler = exceptions.handlerPc(i);
        // If an exception is thrown in subroutine, the handler
        // is part of the same subroutine.
        scan(handler, iter, subroutines[exceptions.startPc(i)]);
    }
    return subroutines;
}
Also used : CodeAttribute(org.hotswap.agent.javassist.bytecode.CodeAttribute) CodeIterator(org.hotswap.agent.javassist.bytecode.CodeIterator) ExceptionTable(org.hotswap.agent.javassist.bytecode.ExceptionTable)

Example 2 with CodeIterator

use of org.hotswap.agent.javassist.bytecode.CodeIterator in project HotswapAgent by HotswapProjects.

the class Analyzer method mergeRet.

private void mergeRet(IntQueue queue, CodeIterator iter, int pos, Frame frame, Subroutine subroutine) throws BadBytecode {
    if (subroutine == null)
        throw new BadBytecode("Ret on no subroutine! [pos = " + pos + "]");
    Iterator callerIter = subroutine.callers().iterator();
    while (callerIter.hasNext()) {
        int caller = ((Integer) callerIter.next()).intValue();
        int returnLoc = getNext(iter, caller, pos);
        boolean changed = false;
        Frame old = frames[returnLoc];
        if (old == null) {
            old = frames[returnLoc] = frame.copyStack();
            changed = true;
        } else {
            changed = old.mergeStack(frame);
        }
        for (Iterator i = subroutine.accessed().iterator(); i.hasNext(); ) {
            int index = ((Integer) i.next()).intValue();
            Type oldType = old.getLocal(index);
            Type newType = frame.getLocal(index);
            if (oldType != newType) {
                old.setLocal(index, newType);
                changed = true;
            }
        }
        if (!old.isRetMerged()) {
            old.setRetMerged(true);
            changed = true;
        }
        if (changed && old.isJsrMerged())
            queue.add(returnLoc);
    }
}
Also used : Iterator(java.util.Iterator) CodeIterator(org.hotswap.agent.javassist.bytecode.CodeIterator) BadBytecode(org.hotswap.agent.javassist.bytecode.BadBytecode)

Example 3 with CodeIterator

use of org.hotswap.agent.javassist.bytecode.CodeIterator in project HotswapAgent by HotswapProjects.

the class FieldInitLink method modifyClassConstructor.

private void modifyClassConstructor(ClassFile cf, Bytecode code, int stacksize, int localsize) throws CannotCompileException {
    MethodInfo m = cf.getStaticInitializer();
    if (m == null) {
        code.add(Bytecode.RETURN);
        code.setMaxStack(stacksize);
        code.setMaxLocals(localsize);
        m = new MethodInfo(cf.getConstPool(), "<clinit>", "()V");
        m.setAccessFlags(AccessFlag.STATIC);
        m.setCodeAttribute(code.toCodeAttribute());
        cf.addMethod(m);
        CtMember.Cache cache = hasMemberCache();
        if (cache != null)
            cache.addConstructor(new CtConstructor(m, this));
    } else {
        CodeAttribute codeAttr = m.getCodeAttribute();
        if (codeAttr == null)
            throw new CannotCompileException("empty <clinit>");
        try {
            CodeIterator it = codeAttr.iterator();
            int pos = it.insertEx(code.get());
            it.insert(code.getExceptionTable(), pos);
            int maxstack = codeAttr.getMaxStack();
            if (maxstack < stacksize)
                codeAttr.setMaxStack(stacksize);
            int maxlocals = codeAttr.getMaxLocals();
            if (maxlocals < localsize)
                codeAttr.setMaxLocals(localsize);
        } catch (BadBytecode e) {
            throw new CannotCompileException(e);
        }
    }
    try {
        m.rebuildStackMapIf6(classPool, cf);
    } catch (BadBytecode e) {
        throw new CannotCompileException(e);
    }
}
Also used : CodeAttribute(org.hotswap.agent.javassist.bytecode.CodeAttribute) CodeIterator(org.hotswap.agent.javassist.bytecode.CodeIterator) MethodInfo(org.hotswap.agent.javassist.bytecode.MethodInfo) BadBytecode(org.hotswap.agent.javassist.bytecode.BadBytecode)

Example 4 with CodeIterator

use of org.hotswap.agent.javassist.bytecode.CodeIterator in project HotswapAgent by HotswapProjects.

the class TransformAccessArrayField method initialize.

public void initialize(ConstPool cp, CtClass clazz, MethodInfo minfo) throws CannotCompileException {
    /*
         * This transformer must be isolated from other transformers, since some
         * of them affect the local variable and stack maximums without updating
         * the code attribute to reflect the changes. This screws up the
         * data-flow analyzer, since it relies on consistent code state. Even
         * if the attribute values were updated correctly, we would have to
         * detect it, and redo analysis, which is not cheap. Instead, we are
         * better off doing all changes in initialize() before everyone else has
         * a chance to muck things up.
         */
    CodeIterator iterator = minfo.getCodeAttribute().iterator();
    while (iterator.hasNext()) {
        try {
            int pos = iterator.next();
            int c = iterator.byteAt(pos);
            if (c == AALOAD)
                initFrames(clazz, minfo);
            if (c == AALOAD || c == BALOAD || c == CALOAD || c == DALOAD || c == FALOAD || c == IALOAD || c == LALOAD || c == SALOAD) {
                pos = replace(cp, iterator, pos, c, getLoadReplacementSignature(c));
            } else if (c == AASTORE || c == BASTORE || c == CASTORE || c == DASTORE || c == FASTORE || c == IASTORE || c == LASTORE || c == SASTORE) {
                pos = replace(cp, iterator, pos, c, getStoreReplacementSignature(c));
            }
        } catch (Exception e) {
            throw new CannotCompileException(e);
        }
    }
}
Also used : CodeIterator(org.hotswap.agent.javassist.bytecode.CodeIterator) CannotCompileException(org.hotswap.agent.javassist.CannotCompileException) NotFoundException(org.hotswap.agent.javassist.NotFoundException) CannotCompileException(org.hotswap.agent.javassist.CannotCompileException)

Example 5 with CodeIterator

use of org.hotswap.agent.javassist.bytecode.CodeIterator in project HotswapAgent by HotswapProjects.

the class Analyzer method analyze.

/**
 * Performs data-flow analysis on a method and returns an array, indexed by
 * instruction position, containing the starting frame state of all reachable
 * instructions. Non-reachable code, and illegal code offsets are represented
 * as a null in the frame state array. This can be used to detect dead code.
 *
 * If the method does not contain code (it is either native or abstract), null
 * is returned.
 *
 * @param clazz the declaring class of the method
 * @param method the method to analyze
 * @return an array, indexed by instruction position, of the starting frame state,
 *         or null if this method doesn't have code
 * @throws BadBytecode if the bytecode does not comply with the JVM specification
 */
public Frame[] analyze(CtClass clazz, MethodInfo method) throws BadBytecode {
    this.clazz = clazz;
    CodeAttribute codeAttribute = method.getCodeAttribute();
    // Native or Abstract
    if (codeAttribute == null)
        return null;
    int maxLocals = codeAttribute.getMaxLocals();
    int maxStack = codeAttribute.getMaxStack();
    int codeLength = codeAttribute.getCodeLength();
    CodeIterator iter = codeAttribute.iterator();
    IntQueue queue = new IntQueue();
    exceptions = buildExceptionInfo(method);
    subroutines = scanner.scan(method);
    Executor executor = new Executor(clazz.getClassPool(), method.getConstPool());
    frames = new Frame[codeLength];
    frames[iter.lookAhead()] = firstFrame(method, maxLocals, maxStack);
    queue.add(iter.next());
    while (!queue.isEmpty()) {
        analyzeNextEntry(method, iter, queue, executor);
    }
    return frames;
}
Also used : CodeAttribute(org.hotswap.agent.javassist.bytecode.CodeAttribute) CodeIterator(org.hotswap.agent.javassist.bytecode.CodeIterator)

Aggregations

CodeIterator (org.hotswap.agent.javassist.bytecode.CodeIterator)7 CodeAttribute (org.hotswap.agent.javassist.bytecode.CodeAttribute)4 BadBytecode (org.hotswap.agent.javassist.bytecode.BadBytecode)3 MethodInfo (org.hotswap.agent.javassist.bytecode.MethodInfo)2 Iterator (java.util.Iterator)1 CannotCompileException (org.hotswap.agent.javassist.CannotCompileException)1 NotFoundException (org.hotswap.agent.javassist.NotFoundException)1 ConstPool (org.hotswap.agent.javassist.bytecode.ConstPool)1 ExceptionTable (org.hotswap.agent.javassist.bytecode.ExceptionTable)1