diff --git a/base/src/main/java/proguard/classfile/editor/CodeAttributeComposer.java b/base/src/main/java/proguard/classfile/editor/CodeAttributeComposer.java index 80256550..ec5ed05d 100644 --- a/base/src/main/java/proguard/classfile/editor/CodeAttributeComposer.java +++ b/base/src/main/java/proguard/classfile/editor/CodeAttributeComposer.java @@ -291,6 +291,7 @@ public void appendInstruction(int oldInstructionOffset, Instruction instruction) int newCodeLength = codeLength + instruction.length(codeLength); ensureCodeLength(newCodeLength); + ensureFragmentLength(oldInstructionOffset + 1); // Remember the old offset of the appended instruction. oldInstructionOffsets[codeLength] = oldInstructionOffset; @@ -325,6 +326,7 @@ public void appendLabel(int oldInstructionOffset) { // Make sure the code and offset arrays are large enough. ensureCodeLength(codeLength + 1); + ensureFragmentLength(oldInstructionOffset + 1); // Remember the old offset of the following instruction. oldInstructionOffsets[codeLength] = oldInstructionOffset; @@ -1067,6 +1069,22 @@ private void ensureCodeLength(int newCodeLength) { } } + /** Make sure the code fragment offset array have at least the given size. */ + private void ensureFragmentLength(int newFragmentLength) { + if (codeFragmentLengths[level] < newFragmentLength) { + codeFragmentLengths[level] = newFragmentLength; + + int oldFragmentLength = instructionOffsetMap[level].length; + if (newFragmentLength > oldFragmentLength) { + // Add 20% to avoid extending the arrays too often. + newFragmentLength = newFragmentLength * 6 / 5; + instructionOffsetMap[level] = + ArrayUtil.extendArray(instructionOffsetMap[level], newFragmentLength); + Arrays.fill(instructionOffsetMap[level], oldFragmentLength, newFragmentLength, INVALID); + } + } + } + /** Adjusts the given jump offsets for the instruction at the given offset. */ private void updateJumpOffsets(int offset, int[] jumpOffsets) { for (int index = 0; index < jumpOffsets.length; index++) {