Java Code Examples for com.sun.org.apache.bcel.internal.generic.InstructionList#getEnd()

The following examples show how to use com.sun.org.apache.bcel.internal.generic.InstructionList#getEnd() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: MethodGenerator.java    From openjdk-jdk9 with GNU General Public License v2.0 5 votes vote down vote up
/**
 * <p>Get all {@link Method}s generated by this {@link MethodGenerator}.
 * The {@link MethodGen#getMethod()} only returns a single
 * <code>Method</code> object.  This method takes into account the Java
 * Virtual Machine Specification limit of 64KB on the size of a method, and
 * may return more than one <code>Method</code>.</p>
 * <p>If the code associated with the <code>MethodGenerator</code> would
 * exceed the 64KB limit, this method will attempt to split the code in
 * the {@link InstructionList} associated with this
 * <code>MethodGenerator</code> into several methods.</p>
 * @param classGen the {@link ClassGenerator} of which these methods are
 *                 members
 * @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);
    } else {
        generatedMethods = new Method[] {getThisMethod()};
    }
    return generatedMethods;
}
 
Example 2
Source File: MethodGenerator.java    From Bytecoder with Apache License 2.0 5 votes vote down vote up
/**
 * <p>Get all {@link Method}s generated by this {@link MethodGenerator}.
 * The {@link MethodGen#getMethod()} only returns a single
 * <code>Method</code> object.  This method takes into account the Java
 * Virtual Machine Specification limit of 64KB on the size of a method, and
 * may return more than one <code>Method</code>.</p>
 * <p>If the code associated with the <code>MethodGenerator</code> would
 * exceed the 64KB limit, this method will attempt to split the code in
 * the {@link InstructionList} associated with this
 * <code>MethodGenerator</code> into several methods.</p>
 * @param classGen the {@link ClassGenerator} of which these methods are
 *                 members
 * @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);
    } else {
        generatedMethods = new Method[] {getThisMethod()};
    }
    return generatedMethods;
}
 
Example 3
Source File: MethodGenerator.java    From openjdk-jdk8u-backup with GNU General Public License v2.0 5 votes vote down vote up
/**
 * <p>Get all {@link Method}s generated by this {@link MethodGenerator}.
 * The {@link MethodGen#getMethod()} only returns a single
 * <code>Method</code> object.  This method takes into account the Java
 * Virtual Machine Specification limit of 64KB on the size of a method, and
 * may return more than one <code>Method</code>.</p>
 * <p>If the code associated with the <code>MethodGenerator</code> would
 * exceed the 64KB limit, this method will attempt to split the code in
 * the {@link InstructionList} associated with this
 * <code>MethodGenerator</code> into several methods.</p>
 * @param classGen the {@link ClassGenerator} of which these methods are
 *                 members
 * @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);
    } else {
        generatedMethods = new Method[] {getThisMethod()};
    }
    return generatedMethods;
}
 
Example 4
Source File: If.java    From openjdk-8-source with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Translate the "test" expression and contents of this element.
 * The contents will be ignored if we know the test will always fail.
 */
public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
    final InstructionList il = methodGen.getInstructionList();
    _test.translateDesynthesized(classGen, methodGen);
    // remember end of condition
    final InstructionHandle truec = il.getEnd();
    if (!_ignore) {
        translateContents(classGen, methodGen);
    }
    _test.backPatchFalseList(il.append(NOP));
    _test.backPatchTrueList(truec.getNext());
}
 
Example 5
Source File: MethodGenerator.java    From openjdk-8 with GNU General Public License v2.0 5 votes vote down vote up
/**
 * <p>Get all {@link Method}s generated by this {@link MethodGenerator}.
 * The {@link MethodGen#getMethod()} only returns a single
 * <code>Method</code> object.  This method takes into account the Java
 * Virtual Machine Specification limit of 64KB on the size of a method, and
 * may return more than one <code>Method</code>.</p>
 * <p>If the code associated with the <code>MethodGenerator</code> would
 * exceed the 64KB limit, this method will attempt to split the code in
 * the {@link InstructionList} associated with this
 * <code>MethodGenerator</code> into several methods.</p>
 * @param classGen the {@link ClassGenerator} of which these methods are
 *                 members
 * @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);
    } else {
        generatedMethods = new Method[] {getThisMethod()};
    }
    return generatedMethods;
}
 
Example 6
Source File: If.java    From openjdk-jdk8u with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Translate the "test" expression and contents of this element.
 * The contents will be ignored if we know the test will always fail.
 */
public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
    final InstructionList il = methodGen.getInstructionList();
    _test.translateDesynthesized(classGen, methodGen);
    // remember end of condition
    final InstructionHandle truec = il.getEnd();
    if (!_ignore) {
        translateContents(classGen, methodGen);
    }
    _test.backPatchFalseList(il.append(NOP));
    _test.backPatchTrueList(truec.getNext());
}
 
Example 7
Source File: MethodGenerator.java    From JDKSourceCode1.8 with MIT License 5 votes vote down vote up
/**
 * <p>Get all {@link Method}s generated by this {@link MethodGenerator}.
 * The {@link MethodGen#getMethod()} only returns a single
 * <code>Method</code> object.  This method takes into account the Java
 * Virtual Machine Specification limit of 64KB on the size of a method, and
 * may return more than one <code>Method</code>.</p>
 * <p>If the code associated with the <code>MethodGenerator</code> would
 * exceed the 64KB limit, this method will attempt to split the code in
 * the {@link InstructionList} associated with this
 * <code>MethodGenerator</code> into several methods.</p>
 * @param classGen the {@link ClassGenerator} of which these methods are
 *                 members
 * @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);
    } else {
        generatedMethods = new Method[] {getThisMethod()};
    }
    return generatedMethods;
}
 
Example 8
Source File: If.java    From openjdk-jdk9 with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Translate the "test" expression and contents of this element.
 * The contents will be ignored if we know the test will always fail.
 */
public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
    final InstructionList il = methodGen.getInstructionList();
    _test.translateDesynthesized(classGen, methodGen);
    // remember end of condition
    final InstructionHandle truec = il.getEnd();
    if (!_ignore) {
        translateContents(classGen, methodGen);
    }
    _test.backPatchFalseList(il.append(NOP));
    _test.backPatchTrueList(truec.getNext());
}
 
Example 9
Source File: If.java    From JDKSourceCode1.8 with MIT License 5 votes vote down vote up
/**
 * Translate the "test" expression and contents of this element.
 * The contents will be ignored if we know the test will always fail.
 */
public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
    final InstructionList il = methodGen.getInstructionList();
    _test.translateDesynthesized(classGen, methodGen);
    // remember end of condition
    final InstructionHandle truec = il.getEnd();
    if (!_ignore) {
        translateContents(classGen, methodGen);
    }
    _test.backPatchFalseList(il.append(NOP));
    _test.backPatchTrueList(truec.getNext());
}
 
Example 10
Source File: MethodGenerator.java    From jdk8u60 with GNU General Public License v2.0 5 votes vote down vote up
/**
 * <p>Get all {@link Method}s generated by this {@link MethodGenerator}.
 * The {@link MethodGen#getMethod()} only returns a single
 * <code>Method</code> object.  This method takes into account the Java
 * Virtual Machine Specification limit of 64KB on the size of a method, and
 * may return more than one <code>Method</code>.</p>
 * <p>If the code associated with the <code>MethodGenerator</code> would
 * exceed the 64KB limit, this method will attempt to split the code in
 * the {@link InstructionList} associated with this
 * <code>MethodGenerator</code> into several methods.</p>
 * @param classGen the {@link ClassGenerator} of which these methods are
 *                 members
 * @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);
    } else {
        generatedMethods = new Method[] {getThisMethod()};
    }
    return generatedMethods;
}
 
Example 11
Source File: If.java    From openjdk-8 with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Translate the "test" expression and contents of this element.
 * The contents will be ignored if we know the test will always fail.
 */
public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
    final InstructionList il = methodGen.getInstructionList();
    _test.translateDesynthesized(classGen, methodGen);
    // remember end of condition
    final InstructionHandle truec = il.getEnd();
    if (!_ignore) {
        translateContents(classGen, methodGen);
    }
    _test.backPatchFalseList(il.append(NOP));
    _test.backPatchTrueList(truec.getNext());
}
 
Example 12
Source File: MethodGenerator.java    From openjdk-8-source with GNU General Public License v2.0 5 votes vote down vote up
/**
 * <p>Get all {@link Method}s generated by this {@link MethodGenerator}.
 * The {@link MethodGen#getMethod()} only returns a single
 * <code>Method</code> object.  This method takes into account the Java
 * Virtual Machine Specification limit of 64KB on the size of a method, and
 * may return more than one <code>Method</code>.</p>
 * <p>If the code associated with the <code>MethodGenerator</code> would
 * exceed the 64KB limit, this method will attempt to split the code in
 * the {@link InstructionList} associated with this
 * <code>MethodGenerator</code> into several methods.</p>
 * @param classGen the {@link ClassGenerator} of which these methods are
 *                 members
 * @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);
    } else {
        generatedMethods = new Method[] {getThisMethod()};
    }
    return generatedMethods;
}
 
Example 13
Source File: MethodGenerator.java    From TencentKona-8 with GNU General Public License v2.0 5 votes vote down vote up
/**
 * <p>Get all {@link Method}s generated by this {@link MethodGenerator}.
 * The {@link MethodGen#getMethod()} only returns a single
 * <code>Method</code> object.  This method takes into account the Java
 * Virtual Machine Specification limit of 64KB on the size of a method, and
 * may return more than one <code>Method</code>.</p>
 * <p>If the code associated with the <code>MethodGenerator</code> would
 * exceed the 64KB limit, this method will attempt to split the code in
 * the {@link InstructionList} associated with this
 * <code>MethodGenerator</code> into several methods.</p>
 * @param classGen the {@link ClassGenerator} of which these methods are
 *                 members
 * @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);
    } else {
        generatedMethods = new Method[] {getThisMethod()};
    }
    return generatedMethods;
}
 
Example 14
Source File: If.java    From TencentKona-8 with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Translate the "test" expression and contents of this element.
 * The contents will be ignored if we know the test will always fail.
 */
public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
    final InstructionList il = methodGen.getInstructionList();
    _test.translateDesynthesized(classGen, methodGen);
    // remember end of condition
    final InstructionHandle truec = il.getEnd();
    if (!_ignore) {
        translateContents(classGen, methodGen);
    }
    _test.backPatchFalseList(il.append(NOP));
    _test.backPatchTrueList(truec.getNext());
}
 
Example 15
Source File: MethodGenerator.java    From jdk1.8-source-analysis with Apache License 2.0 5 votes vote down vote up
/**
 * <p>Get all {@link Method}s generated by this {@link MethodGenerator}.
 * The {@link MethodGen#getMethod()} only returns a single
 * <code>Method</code> object.  This method takes into account the Java
 * Virtual Machine Specification limit of 64KB on the size of a method, and
 * may return more than one <code>Method</code>.</p>
 * <p>If the code associated with the <code>MethodGenerator</code> would
 * exceed the 64KB limit, this method will attempt to split the code in
 * the {@link InstructionList} associated with this
 * <code>MethodGenerator</code> into several methods.</p>
 * @param classGen the {@link ClassGenerator} of which these methods are
 *                 members
 * @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);
    } else {
        generatedMethods = new Method[] {getThisMethod()};
    }
    return generatedMethods;
}
 
Example 16
Source File: If.java    From jdk1.8-source-analysis with Apache License 2.0 5 votes vote down vote up
/**
 * Translate the "test" expression and contents of this element.
 * The contents will be ignored if we know the test will always fail.
 */
public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
    final InstructionList il = methodGen.getInstructionList();
    _test.translateDesynthesized(classGen, methodGen);
    // remember end of condition
    final InstructionHandle truec = il.getEnd();
    if (!_ignore) {
        translateContents(classGen, methodGen);
    }
    _test.backPatchFalseList(il.append(NOP));
    _test.backPatchTrueList(truec.getNext());
}
 
Example 17
Source File: MethodGenerator.java    From TencentKona-8 with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Breaks up the IL for this {@link MethodGenerator} into separate
 * outlined methods so that no method exceeds the 64KB limit on the length
 * of the byte code associated with a method.
 * @param classGen The {@link ClassGen} with which the generated methods
 *                 will be associated
 * @param originalMethodSize The number of bytes of bytecode represented by
 *                 the {@link InstructionList} of this method
 * @return an array of the outlined <code>Method</code>s and the original
 *         method itself
 */
public Method[] outlineChunks(ClassGenerator classGen,
                              int originalMethodSize) {
    ArrayList methodsOutlined = new ArrayList();
    int currentMethodSize = originalMethodSize;

    int outlinedCount = 0;
    boolean moreMethodsOutlined;
    String originalMethodName = getName();

    // Special handling for initialization methods.  No other methods can
    // include the less than and greater than characters in their names,
    // so we munge the names here.
    if (originalMethodName.equals("<init>")) {
        originalMethodName = "$lt$init$gt$";
    } else if (originalMethodName.equals("<clinit>")) {
        originalMethodName = "$lt$clinit$gt$";
    }

    // Loop until the original method comes in under the JVM limit or
    // the loop was unable to outline any more methods
    do {
        // Get all the best candidates for outlining, and sort them in
        // ascending order of size
        ArrayList candidateChunks = getCandidateChunks(classGen,
                                                       currentMethodSize);
        Collections.sort(candidateChunks);

        moreMethodsOutlined = false;

        // Loop over the candidates for outlining, from the largest to the
        // smallest and outline them one at a time, until the loop has
        // outlined all or the original method comes in under the JVM
        // limit on the size of a method.
        for (int i = candidateChunks.size()-1;
             i >= 0 && currentMethodSize > TARGET_METHOD_SIZE;
             i--) {
            Chunk chunkToOutline = (Chunk)candidateChunks.get(i);

            methodsOutlined.add(outline(chunkToOutline.getChunkStart(),
                                        chunkToOutline.getChunkEnd(),
                                        originalMethodName + "$outline$"
                                                           + outlinedCount,
                                        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.
    if (currentMethodSize > MAX_METHOD_SIZE) {
        String msg = (new ErrorMsg(ErrorMsg.OUTLINE_ERR_METHOD_TOO_BIG))
                              .toString();
        throw new InternalError(msg);
    }

    Method[] methodsArr = new Method[methodsOutlined.size() + 1];
    methodsOutlined.toArray(methodsArr);

    methodsArr[methodsOutlined.size()] = getThisMethod();

    return methodsArr;
}
 
Example 18
Source File: MethodGenerator.java    From hottub with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Breaks up the IL for this {@link MethodGenerator} into separate
 * outlined methods so that no method exceeds the 64KB limit on the length
 * of the byte code associated with a method.
 * @param classGen The {@link ClassGen} with which the generated methods
 *                 will be associated
 * @param originalMethodSize The number of bytes of bytecode represented by
 *                 the {@link InstructionList} of this method
 * @return an array of the outlined <code>Method</code>s and the original
 *         method itself
 */
public Method[] outlineChunks(ClassGenerator classGen,
                              int originalMethodSize) {
    ArrayList methodsOutlined = new ArrayList();
    int currentMethodSize = originalMethodSize;

    int outlinedCount = 0;
    boolean moreMethodsOutlined;
    String originalMethodName = getName();

    // Special handling for initialization methods.  No other methods can
    // include the less than and greater than characters in their names,
    // so we munge the names here.
    if (originalMethodName.equals("<init>")) {
        originalMethodName = "$lt$init$gt$";
    } else if (originalMethodName.equals("<clinit>")) {
        originalMethodName = "$lt$clinit$gt$";
    }

    // Loop until the original method comes in under the JVM limit or
    // the loop was unable to outline any more methods
    do {
        // Get all the best candidates for outlining, and sort them in
        // ascending order of size
        ArrayList candidateChunks = getCandidateChunks(classGen,
                                                       currentMethodSize);
        Collections.sort(candidateChunks);

        moreMethodsOutlined = false;

        // Loop over the candidates for outlining, from the largest to the
        // smallest and outline them one at a time, until the loop has
        // outlined all or the original method comes in under the JVM
        // limit on the size of a method.
        for (int i = candidateChunks.size()-1;
             i >= 0 && currentMethodSize > TARGET_METHOD_SIZE;
             i--) {
            Chunk chunkToOutline = (Chunk)candidateChunks.get(i);

            methodsOutlined.add(outline(chunkToOutline.getChunkStart(),
                                        chunkToOutline.getChunkEnd(),
                                        originalMethodName + "$outline$"
                                                           + outlinedCount,
                                        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.
    if (currentMethodSize > MAX_METHOD_SIZE) {
        String msg = (new ErrorMsg(ErrorMsg.OUTLINE_ERR_METHOD_TOO_BIG))
                              .toString();
        throw new InternalError(msg);
    }

    Method[] methodsArr = new Method[methodsOutlined.size() + 1];
    methodsOutlined.toArray(methodsArr);

    methodsArr[methodsOutlined.size()] = getThisMethod();

    return methodsArr;
}
 
Example 19
Source File: MethodGenerator.java    From openjdk-jdk8u-backup with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Breaks up the IL for this {@link MethodGenerator} into separate
 * outlined methods so that no method exceeds the 64KB limit on the length
 * of the byte code associated with a method.
 * @param classGen The {@link ClassGen} with which the generated methods
 *                 will be associated
 * @param originalMethodSize The number of bytes of bytecode represented by
 *                 the {@link InstructionList} of this method
 * @return an array of the outlined <code>Method</code>s and the original
 *         method itself
 */
public Method[] outlineChunks(ClassGenerator classGen,
                              int originalMethodSize) {
    ArrayList methodsOutlined = new ArrayList();
    int currentMethodSize = originalMethodSize;

    int outlinedCount = 0;
    boolean moreMethodsOutlined;
    String originalMethodName = getName();

    // Special handling for initialization methods.  No other methods can
    // include the less than and greater than characters in their names,
    // so we munge the names here.
    if (originalMethodName.equals("<init>")) {
        originalMethodName = "$lt$init$gt$";
    } else if (originalMethodName.equals("<clinit>")) {
        originalMethodName = "$lt$clinit$gt$";
    }

    // Loop until the original method comes in under the JVM limit or
    // the loop was unable to outline any more methods
    do {
        // Get all the best candidates for outlining, and sort them in
        // ascending order of size
        ArrayList candidateChunks = getCandidateChunks(classGen,
                                                       currentMethodSize);
        Collections.sort(candidateChunks);

        moreMethodsOutlined = false;

        // Loop over the candidates for outlining, from the largest to the
        // smallest and outline them one at a time, until the loop has
        // outlined all or the original method comes in under the JVM
        // limit on the size of a method.
        for (int i = candidateChunks.size()-1;
             i >= 0 && currentMethodSize > TARGET_METHOD_SIZE;
             i--) {
            Chunk chunkToOutline = (Chunk)candidateChunks.get(i);

            methodsOutlined.add(outline(chunkToOutline.getChunkStart(),
                                        chunkToOutline.getChunkEnd(),
                                        originalMethodName + "$outline$"
                                                           + outlinedCount,
                                        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.
    if (currentMethodSize > MAX_METHOD_SIZE) {
        String msg = (new ErrorMsg(ErrorMsg.OUTLINE_ERR_METHOD_TOO_BIG))
                              .toString();
        throw new InternalError(msg);
    }

    Method[] methodsArr = new Method[methodsOutlined.size() + 1];
    methodsOutlined.toArray(methodsArr);

    methodsArr[methodsOutlined.size()] = getThisMethod();

    return methodsArr;
}
 
Example 20
Source File: MethodGenerator.java    From Bytecoder with Apache License 2.0 4 votes vote down vote up
/**
 * Breaks up the IL for this {@link MethodGenerator} into separate
 * outlined methods so that no method exceeds the 64KB limit on the length
 * of the byte code associated with a method.
 * @param classGen The {@link ClassGen} with which the generated methods
 *                 will be associated
 * @param originalMethodSize The number of bytes of bytecode represented by
 *                 the {@link InstructionList} of this method
 * @return an array of the outlined <code>Method</code>s and the original
 *         method itself
 */
public Method[] outlineChunks(ClassGenerator classGen,
                              int originalMethodSize) {
    List<Method> methodsOutlined = new ArrayList<>();
    int currentMethodSize = originalMethodSize;

    int outlinedCount = 0;
    boolean moreMethodsOutlined;
    String originalMethodName = getName();

    // Special handling for initialization methods.  No other methods can
    // include the less than and greater than characters in their names,
    // so we munge the names here.
    if (originalMethodName.equals("<init>")) {
        originalMethodName = "$lt$init$gt$";
    } else if (originalMethodName.equals("<clinit>")) {
        originalMethodName = "$lt$clinit$gt$";
    }

    // Loop until the original method comes in under the JVM limit or
    // the loop was unable to outline any more methods
    do {
        // Get all the best candidates for outlining, and sort them in
        // ascending order of size
        List<Chunk> candidateChunks = getCandidateChunks(classGen,
                                                       currentMethodSize);
        Collections.sort(candidateChunks);

        moreMethodsOutlined = false;

        // Loop over the candidates for outlining, from the largest to the
        // smallest and outline them one at a time, until the loop has
        // outlined all or the original method comes in under the JVM
        // limit on the size of a method.
        for (int i = candidateChunks.size()-1;
             i >= 0 && currentMethodSize > TARGET_METHOD_SIZE;
             i--) {
            Chunk chunkToOutline = candidateChunks.get(i);

            methodsOutlined.add(outline(chunkToOutline.getChunkStart(),
                                        chunkToOutline.getChunkEnd(),
                                        originalMethodName + "$outline$"
                                                           + outlinedCount,
                                        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.
    if (currentMethodSize > MAX_METHOD_SIZE) {
        String msg = (new ErrorMsg(ErrorMsg.OUTLINE_ERR_METHOD_TOO_BIG))
                              .toString();
        throw new InternalError(msg);
    }

    Method[] methodsArr = new Method[methodsOutlined.size() + 1];
    methodsOutlined.toArray(methodsArr);

    methodsArr[methodsOutlined.size()] = getThisMethod();

    return methodsArr;
}