Package org.apache.bcel.generic

Examples of org.apache.bcel.generic.InstructionHandle


    public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
  final InstructionList il = methodGen.getInstructionList();

  _left.translate(classGen, methodGen);
  final InstructionHandle gotot = il.append(new GOTO(null));
  il.append(methodGen.loadContextNode());
  _right.translate(classGen, methodGen);

  _left._trueList.backPatch(gotot);
  _left._falseList.backPatch(gotot.getNext());

  _trueList.append(_right._trueList.add(gotot));
  _falseList.append(_right._falseList);
    }
View Full Code Here


  {
      _left.translate(classGen, methodGen);
  }
  else {
      il.append(DUP);
      InstructionHandle storeInst = il.append(storeLocal);

            if (local.getStart() == null) {
                local.setStart(storeInst);
            }
      _left.translate(classGen, methodGen);
View Full Code Here

     * @param offset the position in the byte code
     * @return <code>true</code> if and only if the specified variable is in
     * use at the particular byte code offset.
     */
    boolean offsetInLocalVariableGenRange(LocalVariableGen lvg, int offset) {
        InstructionHandle lvgStart = lvg.getStart();
        InstructionHandle lvgEnd = lvg.getEnd();

        // If no start handle is recorded for the LocalVariableGen, it is
        // assumed to be in use from the beginning of the method.
        if (lvgStart == null) {
            lvgStart = getInstructionList().getStart();
        }

        // If no end handle is recorded for the LocalVariableGen, it is assumed
        // to be in use to the end of the method.
        if (lvgEnd == null) {
            lvgEnd = getInstructionList().getEnd();
        }

        // Does the range of the instruction include the specified offset?
        // Note that the InstructionHandle.getPosition method returns the
        // offset of the beginning of an instruction.  A LocalVariableGen's
        // range includes the end instruction itself, so that instruction's
        // length must be taken into consideration in computing whether the
        // varible is in range at a particular offset.
        return ((lvgStart.getPosition() <= offset)
                    && (lvgEnd.getPosition()
                            + lvgEnd.getInstruction().getLength() >= offset));
    }
View Full Code Here

        ArrayList currLevelChunks = new ArrayList();
        Stack subChunkStack = new Stack();
        boolean openChunkAtCurrLevel = false;
        boolean firstInstruction = true;

        InstructionHandle currentHandle;

        if (m_openChunks != 0) {
            String msg =
                (new ErrorMsg(ErrorMsg.OUTLINE_ERR_UNBALANCED_MARKERS))
                    .toString();
            throw new InternalError(msg);
        }

        // Scan instructions in the method, keeping track of the nesting level
        // of outlineable chunks.
        //
        // currLevelChunks
        //     keeps track of the child chunks of a chunk.  For each chunk,
        //     there will be a pair of entries:  the InstructionHandles for the
        //     start and for the end of the chunk
        // subChunkStack
        //     a stack containing the partially accumulated currLevelChunks for
        //     each chunk that's still open at the current position in the
        //     InstructionList.
        // candidateChunks
        //     the list of chunks which have been accepted as candidates chunks
        //     for outlining
        do {
            // Get the next instruction.  The loop will perform one extra
            // iteration after it reaches the end of the InstructionList, with
            // currentHandle set to null.
            currentHandle = instructions.hasNext()
                                    ? (InstructionHandle) instructions.next()
                                    : null;
            Instruction inst =
                    (currentHandle != null) ? currentHandle.getInstruction()
                                            : null;

            // At the first iteration, create a chunk representing all the
            // code in the method.  This is done just to simplify the logic -
            // this chunk can never be outlined because it will be too big.
            if (firstInstruction) {
                openChunkAtCurrLevel = true;
                currLevelChunks.add(currentHandle);
                firstInstruction = false;
            }

            // Found a new chunk
            if (inst instanceof OutlineableChunkStart) {
                // If last MarkerInstruction encountered was an
                // OutlineableChunkStart, this represents the first chunk
                // nested within that previous chunk - push the list of chunks
                // from the outer level onto the stack
                if (openChunkAtCurrLevel) {
                    subChunkStack.push(currLevelChunks);
                    currLevelChunks = new ArrayList();
                }

                openChunkAtCurrLevel = true;
                currLevelChunks.add(currentHandle);
            // Close off an open chunk
            } else if (currentHandle == null
                           || inst instanceof OutlineableChunkEnd) {
                ArrayList nestedSubChunks = null;

                // If the last MarkerInstruction encountered was an
                // OutlineableChunkEnd, it means that the current instruction
                // marks the end of a chunk that contained child chunks.
                // Those children might need to be examined below in case they
                // are better candidates for outlining than the current chunk.
                if (!openChunkAtCurrLevel) {
                    nestedSubChunks = currLevelChunks;
                    currLevelChunks = (ArrayList)subChunkStack.pop();
                }

                // Get the handle for the start of this chunk (the last entry
                // in currLevelChunks)
                InstructionHandle chunkStart =
                        (InstructionHandle) currLevelChunks.get(
                                                      currLevelChunks.size()-1);

                int chunkEndPosition =
                        (currentHandle != null) ? currentHandle.getPosition()
                                                : totalMethodSize;
                int chunkSize = chunkEndPosition - chunkStart.getPosition();

                // Two ranges of chunk size to consider:
                //
                // 1. [0,TARGET_METHOD_SIZE]
                //      Keep this chunk in consideration as a candidate,
                //      and ignore its subchunks, if any - there's nothing to be
                //      gained by outlining both the current chunk and its
                //      children!
                //
                // 2. (TARGET_METHOD_SIZE,+infinity)
                //      Ignore this chunk - it's too big.  Add its subchunks
                //      as candidates, after merging adjacent chunks to produce
                //      chunks that are as large as possible
                if (chunkSize <= TARGET_METHOD_SIZE) {
                    currLevelChunks.add(currentHandle);
                } else {
                    if (!openChunkAtCurrLevel) {
                        int childChunkCount = nestedSubChunks.size() / 2;
                        if (childChunkCount > 0) {
                            Chunk[] childChunks = new Chunk[childChunkCount];

                            // Gather all the child chunks of the current chunk
                            for (int i = 0; i < childChunkCount; i++) {
                                InstructionHandle start =
                                    (InstructionHandle) nestedSubChunks
                                                            .get(i*2);
                                InstructionHandle end =
                                    (InstructionHandle) nestedSubChunks
                                                            .get(i*2+1);

                                childChunks[i] = new Chunk(start, end);
                            }
View Full Code Here

  if (count == 0) {
      return (_start = getTemplateHandle(_default));
  }

  // Init handle to jump when all patterns failed
  InstructionHandle fail = (_default == null) ? continuation
      : getTemplateHandle(_default);
 
  // Compile all patterns in reverse order
  for (int n = count - 1; n >= 0; n--) {
      final LocationPathPattern pattern = getPattern(n);
      final Template template = pattern.getTemplate();
      final InstructionList il = new InstructionList();

      // Patterns expect current node on top of stack
      il.append(methodGen.loadCurrentNode());

      // Apply the test-code compiled for the pattern
      InstructionList ilist = methodGen.getInstructionList(pattern);
      if (ilist == null) {
    ilist = pattern.compile(classGen, methodGen);
    methodGen.addInstructionList(pattern, ilist);
      }

      // Make a copy of the instruction list for backpatching
      InstructionList copyOfilist = ilist.copy();

      FlowList trueList = pattern.getTrueList();
      if (trueList != null) {
    trueList = trueList.copyAndRedirect(ilist, copyOfilist);
      }
      FlowList falseList = pattern.getFalseList();
      if (falseList != null) {
    falseList = falseList.copyAndRedirect(ilist, copyOfilist);
      }

      il.append(copyOfilist);

      // On success branch to the template code
      final InstructionHandle gtmpl = getTemplateHandle(template);
      final InstructionHandle success = il.append(new GOTO_W(gtmpl));

      if (trueList != null) {
    trueList.backPatch(success);
      }
      if (falseList != null) {
View Full Code Here

                                            classGen));
                outlinedCount++;
                moreMethodsOutlined = true;

                InstructionList il = getInstructionList();
                InstructionHandle lastInst = il.getEnd();
                il.setPositions();

                // Check the size of the method now
                currentMethodSize =
                        lastInst.getPosition()
                                + lastInst.getInstruction().getLength();
            }
        } while (moreMethodsOutlined && currentMethodSize > TARGET_METHOD_SIZE);

        // Outlining failed to reduce the size of the current method
        // sufficiently.  Throw an internal error.
View Full Code Here

        // The handle for the instruction after the last one to be outlined.
        // Note that this should never end up being null.  An outlineable chunk
        // won't contain a RETURN instruction or other branch out of the chunk,
        // and the JVM specification prohibits code in a method from just
        // "falling off the end" so this should always point to a valid handle.
        InstructionHandle limit = last.getNext();

        // InstructionLists for copying values into and out of an instance of
        // CopyLocals:
        //      oldMethCoypInIL  - from locals in old method into an instance
        //                         of the CopyLocals class (oldMethCopyInIL)
        //      oldMethCopyOutIL - from CopyLocals back into locals in the old
        //                         method
        //      newMethCopyInIL  - from CopyLocals into locals in the new
        //                         method
        //      newMethCopyOutIL - from locals in new method into the instance
        //                         of the CopyLocals class
        InstructionList oldMethCopyInIL  = new InstructionList();
        InstructionList oldMethCopyOutIL = new InstructionList();
        InstructionList newMethCopyInIL  = new InstructionList();
        InstructionList newMethCopyOutIL = new InstructionList();

        // Allocate instance of class in which we'll copy in or copy out locals
        // and make two copies:  last copy is used to invoke constructor;
        // other two are used for references to fields in the CopyLocals object
        InstructionHandle outlinedMethodCallSetup =
            oldMethCopyInIL.append(new NEW(cpg.addClass(argTypeName)));
        oldMethCopyInIL.append(InstructionConstants.DUP);
        oldMethCopyInIL.append(InstructionConstants.DUP);
        oldMethCopyInIL.append(
            new INVOKESPECIAL(cpg.addMethodref(argTypeName, "<init>", "()V")));

        // Generate code to invoke the new outlined method, and place the code
        // on oldMethCopyOutIL
        InstructionHandle outlinedMethodRef;

        if (isStaticMethod) {
            outlinedMethodRef =
                oldMethCopyOutIL.append(
                    new INVOKESTATIC(cpg.addMethodref(
                                          classGen.getClassName(),
                                          outlinedMethodName,
                                          outlinedMethodGen.getSignature())));
        } else {
            oldMethCopyOutIL.append(InstructionConstants.THIS);
            oldMethCopyOutIL.append(InstructionConstants.SWAP);
            outlinedMethodRef =
                oldMethCopyOutIL.append(
                    new INVOKEVIRTUAL(cpg.addMethodref(
                                          classGen.getClassName(),
                                          outlinedMethodName,
                                          outlinedMethodGen.getSignature())));
        }

        // Used to keep track of the first in a sequence of
        // OutlineableChunkStart instructions
        boolean chunkStartTargetMappingsPending = false;
        InstructionHandle pendingTargetMappingHandle = null;

        // Used to keep track of the last instruction that was copied
        InstructionHandle lastCopyHandle = null;

        // Keeps track of the mapping from instruction handles in the old
        // method to instruction handles in the outlined method.  Only need
        // to track instructions that are targeted by something else in the
        // generated BCEL
        HashMap targetMap   = new HashMap();

        // Keeps track of the mapping from local variables in the old method
        // to local variables in the outlined method.
        HashMap localVarMap = new HashMap();

        HashMap revisedLocalVarStart = new HashMap();
        HashMap revisedLocalVarEnd = new HashMap();

        // Pass 1: Make copies of all instructions, append them to the new list
        // and associate old instruction references with the new ones, i.e.,
        // a 1:1 mapping.  The special marker instructions are not copied.
        // Also, identify local variables whose values need to be copied into or
        // out of the new outlined method, and builds up targetMap and
        // localVarMap as described above.  The code identifies those local
        // variables first so that they can have fixed slots in the stack
        // frame for the outlined method assigned them ahead of all those
        // variables that don't need to exist for the entirety of the outlined
        // method invocation.
        for (InstructionHandle ih = first; ih != limit; ih = ih.getNext()) {
            Instruction inst = ih.getInstruction();

            // MarkerInstructions are not copied, so if something else targets
            // one, the targetMap will point to the nearest copied sibling
            // InstructionHandle:  for an OutlineableChunkEnd, the nearest
            // preceding sibling; for an OutlineableChunkStart, the nearest
            // following sibling.
            if (inst instanceof MarkerInstruction) {
                if (ih.hasTargeters()) {
                    if (inst instanceof OutlineableChunkEnd) {
                        targetMap.put(ih, lastCopyHandle);
                    } else {
                        if (!chunkStartTargetMappingsPending)  {
                            chunkStartTargetMappingsPending = true;
                            pendingTargetMappingHandle = ih;
                        }
                    }
                }
            } else {
                // Copy the instruction and append it to the outlined method's
                // InstructionList.
                Instruction c = inst.copy(); // Use clone for shallow copy

                if (c instanceof BranchInstruction) {
                    lastCopyHandle = newIL.append((BranchInstruction)c);
                } else {
                    lastCopyHandle = newIL.append(c);
                }

                if (c instanceof LocalVariableInstruction
                        || c instanceof RET) {
                    // For any instruction that touches a local variable,
                    // check whether the local variable's value needs to be
                    // copied into or out of the outlined method.  If so,
                    // generate the code to perform the necessary copying, and
                    // use localVarMap to map the variable in the original
                    // method to the variable in the new method.
                    IndexedInstruction lvi = (IndexedInstruction)c;
                    int oldLocalVarIndex = lvi.getIndex();
                    LocalVariableGen oldLVG =
                            getLocalVariableRegistry()
                                .lookupRegisteredLocalVariable(oldLocalVarIndex,
                                                              ih.getPosition());
                    LocalVariableGen newLVG =
                            (LocalVariableGen)localVarMap.get(oldLVG);

                    // Has the code already mapped this local variable to a
                    // local in the new method?
                    if (localVarMap.get(oldLVG) == null) {
                        // Determine whether the local variable needs to be
                        // copied into or out of the outlined by checking
                        // whether the range of instructions in which the
                        // variable is accessible is outside the range of
                        // instructions in the outlineable chunk.
                        // Special case a chunk start offset of zero:  a local
                        // variable live at that position must be a method
                        // parameter, so the code doesn't need to check whether
                        // the variable is live before that point; being live
                        // at offset zero is sufficient to know that the value
                        // must be copied in to the outlined method.
                        boolean copyInLocalValue =
                            offsetInLocalVariableGenRange(oldLVG,
                                                (outlineChunkStartOffset != 0)
                                                    ? outlineChunkStartOffset-1
                                                    : 0);
                        boolean copyOutLocalValue =
                            offsetInLocalVariableGenRange(oldLVG,
                                                outlineChunkEndOffset+1);

                        // For any variable that needs to be copied into or out
                        // of the outlined method, create a field in the
                        // CopyLocals class, and generate the necessary code for
                        // copying the value.
                        if (copyInLocalValue || copyOutLocalValue) {
                            String varName = oldLVG.getName();
                            Type varType = oldLVG.getType();
                            newLVG = outlinedMethodGen.addLocalVariable(varName,
                                                                        varType,
                                                                        null,
                                                                        null);
                            int newLocalVarIndex = newLVG.getIndex();
                            String varSignature = varType.getSignature();

                            // Record the mapping from the old local to the new
                            localVarMap.put(oldLVG, newLVG);

                            copyAreaFieldCount++;
                            String copyAreaFieldName =
                                           "field" + copyAreaFieldCount;
                            copyAreaCG.addField(
                                new Field(ACC_PUBLIC,
                                        copyAreaCPG.addUtf8(copyAreaFieldName),
                                        copyAreaCPG.addUtf8(varSignature),
                                        null, copyAreaCPG.getConstantPool()));

                            int fieldRef = cpg.addFieldref(argTypeName,
                                                           copyAreaFieldName,
                                                           varSignature);

                            if (copyInLocalValue) {
                                // Generate code for the old method to store the
                                // value of the local into the correct field in
                                // CopyLocals prior to invocation of the
                                // outlined method.
                                oldMethCopyInIL.append(
                                        InstructionConstants.DUP);
                                InstructionHandle copyInLoad =
                                    oldMethCopyInIL.append(
                                        loadLocal(oldLocalVarIndex, varType));
                                oldMethCopyInIL.append(new PUTFIELD(fieldRef));

                                // If the end of the live range of the old
                                // variable was in the middle of the outlined
                                // chunk.  Make the load of its value the new
                                // end of its range.
                                if (!copyOutLocalValue) {
                                    revisedLocalVarEnd.put(oldLVG, copyInLoad);
                                }

                                // Generate code for start of the outlined
                                // method to copy the value from a field in
                                // CopyLocals to the new local in the outlined
                                // method
                                newMethCopyInIL.append(
                                        InstructionConstants.ALOAD_1);
                                newMethCopyInIL.append(new GETFIELD(fieldRef));
                                newMethCopyInIL.append(
                                        storeLocal(newLocalVarIndex, varType));
                            }

                            if (copyOutLocalValue) {
                                // Generate code for the end of the outlined
                                // method to copy the value from the new local
                                // variable into a field in CopyLocals
                                // method
                                newMethCopyOutIL.append(
                                        InstructionConstants.ALOAD_1);
                                newMethCopyOutIL.append(
                                        loadLocal(newLocalVarIndex, varType));
                                newMethCopyOutIL.append(new PUTFIELD(fieldRef));

                                // Generate code to copy the value from a field
                                // in CopyLocals into a local in the original
                                // method following invocation of the outlined
                                // method.
                                oldMethCopyOutIL.append(
                                        InstructionConstants.DUP);
                                oldMethCopyOutIL.append(new GETFIELD(fieldRef));
                                InstructionHandle copyOutStore =
                                    oldMethCopyOutIL.append(
                                        storeLocal(oldLocalVarIndex, varType));

                                // If the start of the live range of the old
                                // variable was in the middle of the outlined
                                // chunk.  Make this store into it the new start
                                // of its range.
                                if (!copyInLocalValue) {
                                    revisedLocalVarStart.put(oldLVG,
                                                             copyOutStore);
                                }
                            }
                        }
                    }
                }

                if (ih.hasTargeters()) {
                    targetMap.put(ih, lastCopyHandle);
                }

                // If this is the first instruction copied following a sequence
                // of OutlineableChunkStart instructions, indicate that the
                // sequence of old instruction all map to this newly created
                // instruction
                if (chunkStartTargetMappingsPending) {
                    do {
                         targetMap.put(pendingTargetMappingHandle,
                                       lastCopyHandle);
                         pendingTargetMappingHandle =
                                 pendingTargetMappingHandle.getNext();
                    } while(pendingTargetMappingHandle != ih);

                    chunkStartTargetMappingsPending = false;
                }
            }
        }

        // Pass 2: Walk old and new instruction lists, updating branch targets
        // and local variable references in the new list
        InstructionHandle ih = first;
        InstructionHandle ch = newIL.getStart();

        while (ch != null) {
            // i == old instruction; c == copied instruction
            Instruction i = ih.getInstruction();
            Instruction c = ch.getInstruction();

            if (i instanceof BranchInstruction) {
                BranchInstruction bc      = (BranchInstruction)c;
                BranchInstruction bi      = (BranchInstruction)i;
                InstructionHandle itarget = bi.getTarget(); // old target

                // New target must be in targetMap
                InstructionHandle newTarget =
                    (InstructionHandle)targetMap.get(itarget);

                bc.setTarget(newTarget);

                // Handle LOOKUPSWITCH or TABLESWITCH which may have many
                // target instructions
                if (bi instanceof Select) {
                    InstructionHandle[] itargets = ((Select)bi).getTargets();
                    InstructionHandle[] ctargets = ((Select)bc).getTargets();

                    // Update all targets
                    for (int j=0; j < itargets.length; j++) {
                        ctargets[j] =
                            (InstructionHandle)targetMap.get(itargets[j]);
                    }
                }
            }  else if (i instanceof LocalVariableInstruction
                            || i instanceof RET) {
                // For any instruction that touches a local variable,
                // map the location of the variable in the original
                // method to its location in the new method.
                IndexedInstruction lvi = (IndexedInstruction)c;
                int oldLocalVarIndex = lvi.getIndex();
                LocalVariableGen oldLVG =
                        getLocalVariableRegistry()
                                .lookupRegisteredLocalVariable(oldLocalVarIndex,
                                                              ih.getPosition());
                LocalVariableGen newLVG =
                        (LocalVariableGen)localVarMap.get(oldLVG);
                int newLocalVarIndex;

                if (newLVG == null) {
                    // Create new variable based on old variable - use same
                    // name and type, but we will let the variable be active
                    // for the entire outlined method.
                    // LocalVariableGen oldLocal = oldLocals[oldLocalVarIndex];
                    String varName = oldLVG.getName();
                    Type varType = oldLVG.getType();
                    newLVG = outlinedMethodGen.addLocalVariable(varName,
                                                                varType,
                                                                null,
                                                                null);
                    newLocalVarIndex = newLVG.getIndex();
                    localVarMap.put(oldLVG, newLVG);

                    // The old variable's live range was wholly contained in
                    // the outlined chunk.  There should no longer be stores
                    // of values into it or loads of its value, so we can just
                    // mark its live range as the reference to the outlined
                    // method.
                    revisedLocalVarStart.put(oldLVG, outlinedMethodRef);
                    revisedLocalVarEnd.put(oldLVG, outlinedMethodRef);
                } else {
                    newLocalVarIndex = newLVG.getIndex();
                }
                lvi.setIndex(newLocalVarIndex);
            }

            // If the old instruction marks the end of the range of a local
            // variable, make sure that any slots on the stack reserved for
            // local variables are made available for reuse by calling
            // MethodGenerator.removeLocalVariable
            if (ih.hasTargeters()) {
                InstructionTargeter[] targeters = ih.getTargeters();

                for (int idx = 0; idx < targeters.length; idx++) {
                    InstructionTargeter targeter = targeters[idx];

                    if (targeter instanceof LocalVariableGen
                            && ((LocalVariableGen)targeter).getEnd()==ih) {
                        Object newLVG = localVarMap.get(targeter);
                        if (newLVG != null) {
                            outlinedMethodGen.removeLocalVariable(
                                                  (LocalVariableGen)newLVG);
                        }
                    }
                }
            }

            // If the current instruction in the original list was a marker,
            // it wasn't copied, so don't advance through the list of copied
            // instructions yet.
            if (!(i instanceof MarkerInstruction)) {
                ch = ch.getNext();
            }
            ih = ih.getNext();

        }

        // POP the reference to the CopyLocals object from the stack
        oldMethCopyOutIL.append(InstructionConstants.POP);

        // Now that the generation of the outlined code is complete, update
        // the old local variables with new start and end ranges, as required.
        Iterator revisedLocalVarStartPairIter = revisedLocalVarStart.entrySet()
                                                                    .iterator();
        while (revisedLocalVarStartPairIter.hasNext()) {
            Map.Entry lvgRangeStartPair =
                    (Map.Entry)revisedLocalVarStartPairIter.next();
            LocalVariableGen lvg = (LocalVariableGen)lvgRangeStartPair.getKey();
            InstructionHandle startInst =
                    (InstructionHandle)lvgRangeStartPair.getValue();

            lvg.setStart(startInst);
           
        }

        Iterator revisedLocalVarEndPairIter = revisedLocalVarEnd.entrySet()
                                                                .iterator();
        while (revisedLocalVarEndPairIter.hasNext()) {
            Map.Entry lvgRangeEndPair =
                    (Map.Entry)revisedLocalVarEndPairIter.next();
            LocalVariableGen lvg = (LocalVariableGen)lvgRangeEndPair.getKey();
            InstructionHandle endInst =
                    (InstructionHandle)lvgRangeEndPair.getValue();

            lvg.setEnd(endInst);
        }

        xsltc.dumpClass(copyAreaCG.getJavaClass());

        // Assemble the instruction lists so that the old method invokes the
        // new outlined method
        InstructionList oldMethodIL = getInstructionList();

        oldMethodIL.insert(first, oldMethCopyInIL);
        oldMethodIL.insert(first, oldMethCopyOutIL);

        // Insert the copying code into the outlined method
        newIL.insert(newMethCopyInIL);
        newIL.append(newMethCopyOutIL);
        newIL.append(InstructionConstants.RETURN);

        // Discard instructions in outlineable chunk from old method
        try {
            oldMethodIL.delete(first, last);
        } catch (TargetLostException e) {
            InstructionHandle[] targets = e.getTargets();
            // If there were still references to old instructions lingering,
            // clean those up.  The only instructions targetting the deleted
            // instructions should have been part of the chunk that was just
            // deleted, except that instructions might branch to the start of
            // the outlined chunk; similarly, all the live ranges of local
            // variables should have been adjusted, except for unreferenced
            // variables.
            for (int i = 0; i < targets.length; i++) {
                InstructionHandle lostTarget = targets[i];
                InstructionTargeter[] targeters = lostTarget.getTargeters();
                for (int j = 0; j < targeters.length; j++) {
                    if (targeters[j] instanceof LocalVariableGen) {
                        LocalVariableGen lvgTargeter =
                                             (LocalVariableGen) targeters[j];
                        // In the case of any lingering variable references,
View Full Code Here

     * @return an array of all the <code>Method</code>s generated
     */
    Method[] getGeneratedMethods(ClassGenerator classGen) {
        Method[] generatedMethods;
        InstructionList il = getInstructionList();
        InstructionHandle last = il.getEnd();

        il.setPositions();

        int instructionListSize =
                    last.getPosition() + last.getInstruction().getLength();

        // Need to look for any branch target offsets that exceed the range
        // [-32768,32767]
        if (instructionListSize > MAX_BRANCH_TARGET_OFFSET) {
            boolean ilChanged = widenConditionalBranchTargetOffsets();

            // If any branch instructions needed widening, recompute the size
            // of the byte code for the method
            if (ilChanged) {
                il.setPositions();
                last = il.getEnd();
                instructionListSize =
                        last.getPosition() + last.getInstruction().getLength();
            }
        }

        if (instructionListSize > MAX_METHOD_SIZE) {
            generatedMethods = outlineChunks(classGen, instructionListSize);
View Full Code Here

            Instruction inst = ih.getInstruction();

            if (inst instanceof IfInstruction) {
                IfInstruction oldIfInst = (IfInstruction)inst;
                BranchHandle oldIfHandle = (BranchHandle)ih;
                InstructionHandle target = oldIfInst.getTarget();
                int relativeTargetOffset = target.getPosition()
                                               - oldIfHandle.getPosition();

                // Consider the worst case scenario in which the conditional
                // branch and its target are separated by all the instructions
                // in the method that might increase in size.  If that results
                // in a relative offset that cannot be represented as a 32-bit
                // signed quantity, rewrite the instruction as described above.
                if ((relativeTargetOffset - maxOffsetChange
                             < MIN_BRANCH_TARGET_OFFSET)
                        || (relativeTargetOffset + maxOffsetChange
                                    > MAX_BRANCH_TARGET_OFFSET)) {
                    // Invert the logic of the IF instruction, and append
                    // that to the InstructionList following the original IF
                    // instruction
                    InstructionHandle nextHandle = oldIfHandle.getNext();
                    IfInstruction invertedIfInst = oldIfInst.negate();
                    BranchHandle invertedIfHandle = il.append(oldIfHandle,
                                                              invertedIfInst);

                    // Append an unconditional branch to the target of the
View Full Code Here

      _trueList.append(exp._trueList);
      _falseList.append(exp._falseList);
  }

  // Backpatch true list and restore current iterator/node
  InstructionHandle restore;
  restore = il.append(methodGen.storeCurrentNode());
  backPatchTrueList(restore);
  BranchHandle skipFalse = il.append(new GOTO(null));

  // Backpatch false list and restore current iterator/node
View Full Code Here

TOP

Related Classes of org.apache.bcel.generic.InstructionHandle

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.