예제 #1
0
  public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute) {
    //        DEBUG =
    //            clazz.getName().equals("abc/Def") &&
    //            method.getName(clazz).equals("abc");

    // The minimum variable size is determined by the arguments.
    codeAttribute.u2maxLocals =
        ClassUtil.internalMethodParameterSize(method.getDescriptor(clazz), method.getAccessFlags());

    if (DEBUG) {
      System.out.println(
          "VariableSizeUpdater: "
              + clazz.getName()
              + "."
              + method.getName(clazz)
              + method.getDescriptor(clazz));
      System.out.println("  Max locals: " + codeAttribute.u2maxLocals + " <- parameters");
    }

    // Go over all instructions.
    codeAttribute.instructionsAccept(clazz, method, this);

    // Remove the unused variables of the attributes.
    codeAttribute.attributesAccept(clazz, method, variableCleaner);
  }
예제 #2
0
  /** Appends the specified subroutine. */
  private void inlineSubroutine(
      Clazz clazz,
      Method method,
      CodeAttribute codeAttribute,
      int subroutineInvocationOffset,
      int subroutineStart) {
    int subroutineEnd = branchTargetFinder.subroutineEnd(subroutineStart);

    if (DEBUG) {
      System.out.println(
          "  Inlining subroutine ["
              + subroutineStart
              + " -> "
              + subroutineEnd
              + "] at ["
              + subroutineInvocationOffset
              + "]");
    }

    // Don't go inlining exceptions that are already applicable to this
    // subroutine invocation.
    ExceptionInfoVisitor oldSubroutineExceptionInliner = subroutineExceptionInliner;
    int oldClipStart = clipStart;
    int oldClipEnd = clipEnd;

    subroutineExceptionInliner =
        new ExceptionExcludedOffsetFilter(subroutineInvocationOffset, subroutineExceptionInliner);
    clipStart = subroutineStart;
    clipEnd = subroutineEnd;

    codeAttributeComposer.beginCodeFragment(codeAttribute.u4codeLength);

    // Copy the subroutine instructions, inlining any subroutine calls
    // recursively.
    codeAttribute.instructionsAccept(clazz, method, subroutineStart, subroutineEnd, this);

    if (DEBUG) {
      System.out.println("    Appending label after inlined subroutine at [" + subroutineEnd + "]");
    }

    // Append a label just after the code.
    codeAttributeComposer.appendLabel(subroutineEnd);

    // Inline the subroutine exceptions.
    codeAttribute.exceptionsAccept(
        clazz, method, subroutineStart, subroutineEnd, subroutineExceptionInliner);

    // We can again inline exceptions that are applicable to this
    // subroutine invocation.
    subroutineExceptionInliner = oldSubroutineExceptionInliner;
    clipStart = oldClipStart;
    clipEnd = oldClipEnd;

    codeAttributeComposer.endCodeFragment();
  }
예제 #3
0
  public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute) {
    markAsUsed(codeAttribute);

    markConstant(clazz, codeAttribute.u2attributeNameIndex);

    // Mark the constant pool entries referenced by the instructions,
    // by the exceptions, and by the attributes.
    codeAttribute.instructionsAccept(clazz, method, this);
    codeAttribute.exceptionsAccept(clazz, method, this);
    codeAttribute.attributesAccept(clazz, method, this);
  }
  public void visitCodeAttribute0(Clazz clazz, Method method, CodeAttribute codeAttribute) {
    if (DEBUG) {
      System.out.println(
          "StackSizeComputer: "
              + clazz.getName()
              + "."
              + method.getName(clazz)
              + method.getDescriptor(clazz));
    }

    // Try to reuse the previous array.
    int codeLength = codeAttribute.u4codeLength;
    if (evaluated.length < codeLength) {
      evaluated = new boolean[codeLength];
      stackSizes = new int[codeLength];
    } else {
      Arrays.fill(evaluated, 0, codeLength, false);
    }

    // The initial stack is always empty.
    stackSize = 0;
    maxStackSize = 0;

    // Evaluate the instruction block starting at the entry point of the method.
    evaluateInstructionBlock(clazz, method, codeAttribute, 0);

    // Evaluate the exception handlers.
    codeAttribute.exceptionsAccept(clazz, method, this);
  }
  public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute) {
    // Set up the code attribute editor.
    codeAttributeEditor.reset(codeAttribute.u4codeLength);

    // Find the peephole changes.
    codeAttribute.instructionsAccept(clazz, method, instructionSequenceReplacer);

    // Apply the peephole changes.
    codeAttributeEditor.visitCodeAttribute(clazz, method, codeAttribute);
  }
예제 #6
0
 /** Deletes the specified attribute from the target. */
 public void deleteAttribute(String attributeName) {
   // What's the target?
   if (targetAttribute != null) {
     targetAttribute.u2attributesCount =
         deleteAttribute(
             targetAttribute.u2attributesCount, targetAttribute.attributes, attributeName);
   } else if (targetMember != null) {
     targetMember.u2attributesCount =
         deleteAttribute(targetMember.u2attributesCount, targetMember.attributes, attributeName);
   } else {
     targetClass.u2attributesCount =
         deleteAttribute(targetClass.u2attributesCount, targetClass.attributes, attributeName);
   }
 }
예제 #7
0
  public void visitVariableInstruction(
      Clazz clazz,
      Method method,
      CodeAttribute codeAttribute,
      int offset,
      VariableInstruction variableInstruction) {
    int variableSize = variableInstruction.variableIndex + 1;
    if (variableInstruction.isCategory2()) {
      variableSize++;
    }

    if (codeAttribute.u2maxLocals < variableSize) {
      codeAttribute.u2maxLocals = variableSize;

      if (DEBUG) {
        System.out.println(
            "  Max locals: "
                + codeAttribute.u2maxLocals
                + " <- "
                + variableInstruction.toString(offset));
      }
    }
  }
예제 #8
0
  public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute) {
    // Make sure there is a sufficiently large array.
    int codeLength = codeAttribute.u4codeLength;
    if (isReachable.length < codeLength) {
      // Create a new array.
      isReachable = new boolean[codeLength];
    } else {
      // Reset the array.
      for (int index = 0; index < codeLength; index++) {
        isReachable[index] = false;
      }
    }

    // Mark the code, starting at the entry point.
    markCode(clazz, method, codeAttribute, 0);

    // Mark the exception handlers, iterating as long as necessary.
    do {
      evaluateExceptions = false;

      codeAttribute.exceptionsAccept(clazz, method, this);
    } while (evaluateExceptions);
  }
예제 #9
0
  /** Adds the given attribute to the target. */
  public void addAttribute(Attribute attribute) {
    // What's the target?
    if (targetAttribute != null) {
      // Try to replace an existing attribute.
      if (!replaceAttributes
          || !replaceAttribute(
              targetAttribute.u2attributesCount, targetAttribute.attributes, attribute)) {
        // Otherwise append the attribute.
        targetAttribute.attributes =
            addAttribute(targetAttribute.u2attributesCount, targetAttribute.attributes, attribute);

        targetAttribute.u2attributesCount++;
      }
    } else if (targetMember != null) {
      // Try to replace an existing attribute.
      if (!replaceAttributes
          || !replaceAttribute(
              targetMember.u2attributesCount, targetMember.attributes, attribute)) {
        // Otherwise append the attribute.
        targetMember.attributes =
            addAttribute(targetMember.u2attributesCount, targetMember.attributes, attribute);

        targetMember.u2attributesCount++;
      }
    } else {
      // Try to replace an existing attribute.
      if (!replaceAttributes
          || !replaceAttribute(targetClass.u2attributesCount, targetClass.attributes, attribute)) {
        // Otherwise append the attribute.
        targetClass.attributes =
            addAttribute(targetClass.u2attributesCount, targetClass.attributes, attribute);

        targetClass.u2attributesCount++;
      }
    }
  }
예제 #10
0
  public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute) {
    //        DEBUG =
    //            clazz.getName().equals("abc/Def") &&
    //            method.getName(clazz).equals("abc");

    if (DEBUG) {
      method.accept(clazz, new ClassPrinter());
    }

    branchTargetFinder.visitCodeAttribute(clazz, method, codeAttribute);

    // Don't bother if there aren't any subroutines anyway.
    if (!containsSubroutines(codeAttribute)) {
      return;
    }

    if (DEBUG) {
      System.out.println(
          "SubroutineInliner: processing ["
              + clazz.getName()
              + "."
              + method.getName(clazz)
              + method.getDescriptor(clazz)
              + "]");
    }

    // Append the body of the code.
    codeAttributeComposer.reset();
    codeAttributeComposer.beginCodeFragment(codeAttribute.u4codeLength);

    // Copy the non-subroutine instructions.
    int offset = 0;
    while (offset < codeAttribute.u4codeLength) {
      Instruction instruction = InstructionFactory.create(codeAttribute.code, offset);
      int instructionLength = instruction.length(offset);

      // Is this returning subroutine?
      if (branchTargetFinder.isSubroutine(offset)
          && branchTargetFinder.isSubroutineReturning(offset)) {
        // Skip the subroutine.
        if (DEBUG) {
          System.out.println(
              "  Skipping original subroutine instruction " + instruction.toString(offset));
        }

        // Append a label at this offset instead.
        codeAttributeComposer.appendLabel(offset);
      } else {
        // Copy the instruction, inlining any subroutine call recursively.
        instruction.accept(clazz, method, codeAttribute, offset, this);
      }

      offset += instructionLength;
    }

    // Copy the exceptions. Note that exceptions with empty try blocks
    // are automatically removed.
    codeAttribute.exceptionsAccept(clazz, method, subroutineExceptionInliner);

    if (DEBUG) {
      System.out.println("  Appending label after code at [" + offset + "]");
    }

    // Append a label just after the code.
    codeAttributeComposer.appendLabel(codeAttribute.u4codeLength);

    // End and update the code attribute.
    codeAttributeComposer.endCodeFragment();
    codeAttributeComposer.visitCodeAttribute(clazz, method, codeAttribute);

    if (DEBUG) {
      method.accept(clazz, new ClassPrinter());
    }
  }
 public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute) {
   // Visit the attributes of the code attribute.
   codeAttribute.attributesAccept(clazz, method, this);
 }