Example #1
0
  /** Instrument the specified method to replace mapped calls. */
  public void instrument_method(Method m, MethodGen mg) {

    // Loop through each instruction, making substitutions
    InstructionList il = mg.getInstructionList();
    for (InstructionHandle ih = il.getStart(); ih != null; ) {
      if (debug_instrument_inst.enabled()) {
        debug_instrument_inst.log("instrumenting instruction %s%n", ih);
        // ih.getInstruction().toString(pool.getConstantPool()));
      }
      InstructionList new_il = null;

      // Remember the next instruction to process
      InstructionHandle next_ih = ih.getNext();

      // Get the translation for this instruction (if any)
      new_il = xform_inst(mg, ih.getInstruction());
      if (debug_instrument_inst.enabled()) debug_instrument_inst.log("  new inst: %s%n", new_il);

      // If this instruction was modified, replace it with the new
      // instruction list. If this instruction was the target of any
      // jumps or line numbers , replace them with the first
      // instruction in the new list
      replace_instructions(il, ih, new_il);

      ih = next_ih;
    }
  }
Example #2
0
  /**
   * Replace instruction ih in list il with the instructions in new_il. If new_il is null, do
   * nothing
   */
  protected static void replace_instructions(
      InstructionList il, InstructionHandle ih, InstructionList new_il) {

    if ((new_il == null) || new_il.isEmpty()) return;

    // If there is only one new instruction, just replace it in the handle
    if (new_il.getLength() == 1) {
      ih.setInstruction(new_il.getEnd().getInstruction());
      return;
    }

    // Get the start and end instruction of the new instructions
    InstructionHandle new_end = new_il.getEnd();
    InstructionHandle new_start = il.insert(ih, new_il);

    // Move all of the branches from the old instruction to the new start
    il.redirectBranches(ih, new_start);

    // Move other targets to the new instuctions.
    if (ih.hasTargeters()) {
      for (InstructionTargeter it : ih.getTargeters()) {
        if (it instanceof LineNumberGen) {
          it.updateTarget(ih, new_start);
        } else if (it instanceof LocalVariableGen) {
          it.updateTarget(ih, new_end);
        } else if (it instanceof CodeExceptionGen) {
          CodeExceptionGen exc = (CodeExceptionGen) it;
          if (exc.getStartPC() == ih) exc.updateTarget(ih, new_start);
          else if (exc.getEndPC() == ih) exc.updateTarget(ih, new_end);
          else if (exc.getHandlerPC() == ih) exc.setHandlerPC(new_start);
          else System.out.printf("Malformed CodeException: %s%n", exc);
        } else {
          System.out.printf("unexpected target %s%n", it);
        }
      }
    }

    // Remove the old handle.  There should be no targeters left to it.
    try {
      il.delete(ih);
    } catch (Exception e) {
      throw new Error("Can't delete instruction", e);
    }
  }
  /**
   * Long output format:
   *
   * <p>&lt;position in byte code&gt; &lt;name of opcode&gt; "["&lt;opcode number&gt;"]"
   * "("&lt;length of instruction&gt;")" "&lt;"&lt;target instruction&gt;"&gt;" "@"&lt;branch target
   * offset&gt;
   *
   * @param verbose long/short format switch
   * @return mnemonic for instruction
   */
  public String toString(boolean verbose) {
    String s = super.toString(verbose);
    String t = "null";

    if (verbose) {
      if (target != null) {
        if (target.getInstruction() == this) t = "<points to itself>";
        else if (target.getInstruction() == null) t = "<null instruction!!!?>";
        else t = target.getInstruction().toString(false); // Avoid circles
      }
    } else {
      if (target != null) {
        index = getTargetOffset();
        t = "" + (index + position);
      }
    }

    return s + " -> " + t;
  }
  /**
   * @param target branch target
   * @return the offset to `target' relative to this instruction
   */
  protected int getTargetOffset(InstructionHandle target) {
    if (target == null)
      throw new ClassGenException("Target of " + super.toString(true) + " is invalid null handle");

    int t = target.getPosition();

    if (t < 0)
      throw new ClassGenException(
          "Invalid branch target position offset for "
              + super.toString(true)
              + ":"
              + t
              + ":"
              + target);

    return t - position;
  }
 /** Used by BranchInstruction, LocalVariableGen, CodeExceptionGen */
 static final void notifyTarget(
     InstructionHandle old_ih, InstructionHandle new_ih, InstructionTargeter t) {
   if (old_ih != null) old_ih.removeTargeter(t);
   if (new_ih != null) new_ih.addTargeter(t);
 }