Java Code Examples for com.sun.org.apache.bcel.internal.generic.InstructionHandle#getPosition()

The following examples show how to use com.sun.org.apache.bcel.internal.generic.InstructionHandle#getPosition() . 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-jdk8u 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 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 3
Source File: MethodGenerator.java    From TencentKona-8 with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Determines whether a particular variable is in use at a particular offset
 * in the byte code for this method.
 * <p><b>Preconditions:</b>
 * <ul>
 * <li>The {@link InstructionList#setPositions()} has been called for the
 * {@link InstructionList} associated with this {@link MethodGenerator}.
 * </li></ul></p>
 * @param lvg the {@link LocalVariableGen} for the variable
 * @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));
}
 
Example 4
Source File: MethodGenerator.java    From openjdk-jdk8u with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Determines whether a particular variable is in use at a particular offset
 * in the byte code for this method.
 * <p><b>Preconditions:</b>
 * <ul>
 * <li>The {@link InstructionList#setPositions()} has been called for the
 * {@link InstructionList} associated with this {@link MethodGenerator}.
 * </li></ul></p>
 * @param lvg the {@link LocalVariableGen} for the variable
 * @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));
}
 
Example 5
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 6
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 7
Source File: MethodGenerator.java    From jdk8u60 with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Determines whether a particular variable is in use at a particular offset
 * in the byte code for this method.
 * <p><b>Preconditions:</b>
 * <ul>
 * <li>The {@link InstructionList#setPositions()} has been called for the
 * {@link InstructionList} associated with this {@link MethodGenerator}.
 * </li></ul></p>
 * @param lvg the {@link LocalVariableGen} for the variable
 * @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));
}
 
Example 8
Source File: MethodGenerator.java    From jdk1.8-source-analysis with Apache License 2.0 5 votes vote down vote up
/**
 * Determines whether a particular variable is in use at a particular offset
 * in the byte code for this method.
 * <p><b>Preconditions:</b>
 * <ul>
 * <li>The {@link InstructionList#setPositions()} has been called for the
 * {@link InstructionList} associated with this {@link MethodGenerator}.
 * </li></ul></p>
 * @param lvg the {@link LocalVariableGen} for the variable
 * @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));
}
 
Example 9
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 10
Source File: MethodGenerator.java    From JDKSourceCode1.8 with MIT License 5 votes vote down vote up
/**
 * Determines whether a particular variable is in use at a particular offset
 * in the byte code for this method.
 * <p><b>Preconditions:</b>
 * <ul>
 * <li>The {@link InstructionList#setPositions()} has been called for the
 * {@link InstructionList} associated with this {@link MethodGenerator}.
 * </li></ul></p>
 * @param lvg the {@link LocalVariableGen} for the variable
 * @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));
}
 
Example 11
Source File: MethodGenerator.java    From jdk8u60 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 12
Source File: MethodGenerator.java    From openjdk-jdk8u 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 13
Source File: MethodGenerator.java    From JDKSourceCode1.8 with MIT License 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 14
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 15
Source File: MethodGenerator.java    From jdk1.8-source-analysis 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) {
    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 16
Source File: MethodGenerator.java    From JDKSourceCode1.8 with MIT License 2 votes vote down vote up
/**
 * <p>Constructor for an outlineable {@link MethodGenerator.Chunk}.</p>
 * <p><b>Preconditions:</b>
 * <ul>
 * <li>The {@link InstructionList#setPositions()} has been called for
 * the {@link InstructionList} associated with this
 * {@link MethodGenerator}.</li>
 * </ul></p>
 * @param start The {@link InstructionHandle} of the first
 *              instruction in the outlineable chunk.
 * @param end The {@link InstructionHandle} of the last
 *            instruction in the outlineable chunk.
 */
Chunk(InstructionHandle start, InstructionHandle end) {
    m_start = start;
    m_end = end;
    m_size = end.getPosition() - start.getPosition();
}
 
Example 17
Source File: MethodGenerator.java    From jdk8u60 with GNU General Public License v2.0 2 votes vote down vote up
/**
 * <p>Constructor for an outlineable {@link MethodGenerator.Chunk}.</p>
 * <p><b>Preconditions:</b>
 * <ul>
 * <li>The {@link InstructionList#setPositions()} has been called for
 * the {@link InstructionList} associated with this
 * {@link MethodGenerator}.</li>
 * </ul></p>
 * @param start The {@link InstructionHandle} of the first
 *              instruction in the outlineable chunk.
 * @param end The {@link InstructionHandle} of the last
 *            instruction in the outlineable chunk.
 */
Chunk(InstructionHandle start, InstructionHandle end) {
    m_start = start;
    m_end = end;
    m_size = end.getPosition() - start.getPosition();
}
 
Example 18
Source File: MethodGenerator.java    From TencentKona-8 with GNU General Public License v2.0 2 votes vote down vote up
/**
 * <p>Constructor for an outlineable {@link MethodGenerator.Chunk}.</p>
 * <p><b>Preconditions:</b>
 * <ul>
 * <li>The {@link InstructionList#setPositions()} has been called for
 * the {@link InstructionList} associated with this
 * {@link MethodGenerator}.</li>
 * </ul></p>
 * @param start The {@link InstructionHandle} of the first
 *              instruction in the outlineable chunk.
 * @param end The {@link InstructionHandle} of the last
 *            instruction in the outlineable chunk.
 */
Chunk(InstructionHandle start, InstructionHandle end) {
    m_start = start;
    m_end = end;
    m_size = end.getPosition() - start.getPosition();
}
 
Example 19
Source File: MethodGenerator.java    From openjdk-jdk8u with GNU General Public License v2.0 2 votes vote down vote up
/**
 * <p>Constructor for an outlineable {@link MethodGenerator.Chunk}.</p>
 * <p><b>Preconditions:</b>
 * <ul>
 * <li>The {@link InstructionList#setPositions()} has been called for
 * the {@link InstructionList} associated with this
 * {@link MethodGenerator}.</li>
 * </ul></p>
 * @param start The {@link InstructionHandle} of the first
 *              instruction in the outlineable chunk.
 * @param end The {@link InstructionHandle} of the last
 *            instruction in the outlineable chunk.
 */
Chunk(InstructionHandle start, InstructionHandle end) {
    m_start = start;
    m_end = end;
    m_size = end.getPosition() - start.getPosition();
}
 
Example 20
Source File: MethodGenerator.java    From jdk1.8-source-analysis with Apache License 2.0 2 votes vote down vote up
/**
 * <p>Constructor for an outlineable {@link MethodGenerator.Chunk}.</p>
 * <p><b>Preconditions:</b>
 * <ul>
 * <li>The {@link InstructionList#setPositions()} has been called for
 * the {@link InstructionList} associated with this
 * {@link MethodGenerator}.</li>
 * </ul></p>
 * @param start The {@link InstructionHandle} of the first
 *              instruction in the outlineable chunk.
 * @param end The {@link InstructionHandle} of the last
 *            instruction in the outlineable chunk.
 */
Chunk(InstructionHandle start, InstructionHandle end) {
    m_start = start;
    m_end = end;
    m_size = end.getPosition() - start.getPosition();
}