Beispiel #1
0
  public static void dumpcode(final MethodEditor m) {

    final PrintWriter out = new PrintWriter(System.out, true);
    final StackHeightCounter shc = new StackHeightCounter(m);

    out.println("Code for method " + m.name() + m.type());
    final List instructions = m.code();
    final ListIterator iter = instructions.listIterator();
    while (iter.hasNext()) {
      final Object obj = iter.next();
      if (obj instanceof Label) {
        shc.handle((Label) obj);
      } else if (obj instanceof Instruction) {
        shc.handle((Instruction) obj);
      }

      System.out.println("        " + obj + " (sh: " + shc.height() + ")");
    }
  }
Beispiel #2
0
  /**
   * Inserts residency/update/swizzle checks into a method. Iterates over the bytecodes in the
   * method and inserts the appropriate residency opcode.
   *
   * @param method The method to which to add checks.
   * @see MethodEditor#code
   */
  private static void transform(final MethodEditor method) {
    if (Main.VERBOSE > 1) {
      System.out.println("Decorating method " + method);
    }

    // Optimize initialization of arrays to speed things up.
    CompactArrayInitializer.transform(method);

    final ListIterator iter = method.code().listIterator();

    // Go through the code (Instructions and Labels) in the method
    INST:
    while (iter.hasNext()) {
      final Object ce = iter.next();

      if (Main.VERBOSE > 2) {
        System.out.println("Examining " + ce);
      }

      if (ce instanceof Instruction) {
        final Instruction inst = (Instruction) ce;

        int uctype = Main.NONE; // Type of update check (POINTER or
        // SCALAR)
        boolean insert_sc = false; // Insert swizzle check (aaload
        // only)?

        final int opc = inst.opcodeClass();
        int depth;

        switch (opc) {
          case opcx_arraylength:
          case opcx_athrow:
          case opcx_getfield:
          case opcx_instanceof:
            {
              depth = 0;
              break;
            }
          case opcx_iaload:
          case opcx_laload:
          case opcx_faload:
          case opcx_daload:
          case opcx_baload:
          case opcx_caload:
          case opcx_saload:
            {
              depth = 1;
              break;
            }
          case opcx_aaload:
            {
              depth = 1;
              insert_sc = true;
              break;
            }
          case opcx_iastore:
          case opcx_fastore:
          case opcx_aastore:
          case opcx_bastore:
          case opcx_castore:
          case opcx_sastore:
            {
              depth = 2;
              break;
            }
          case opcx_lastore:
          case opcx_dastore:
            {
              depth = 3;
              break;
            }
          case opcx_putfield:
            {
              final MemberRef ref = (MemberRef) inst.operand();
              depth = ref.type().stackHeight();
              if (ref.type().isReference()) {
                uctype = Main.POINTER;
              } else {
                uctype = Main.SCALAR;
              }
              break;
            }
          case opcx_invokevirtual:
          case opcx_invokespecial:
          case opcx_invokeinterface:
            {
              final MemberRef ref = (MemberRef) inst.operand();
              depth = ref.type().stackHeight();
              break;
            }
          case opcx_rc:
            {
              // Skip any existing residency checks.
              iter.remove();
              continue INST;
            }
          case opcx_aupdate:
            {
              // Skip any existing update checks.
              iter.remove();
              continue INST;
            }
          case opcx_supdate:
            {
              // Skip any existing update checks.
              iter.remove();
              continue INST;
            }
          default:
            {
              continue INST;
            }
        }

        Instruction addInst;

        // Insert a residency check...
        if (Main.RC) {
          Object t;

          // //////////////////////////////////
          // Before...
          // +-----+------+-----------+
          // | ... | inst | afterInst |
          // +-----+------+-----------+
          // ^prev ^next
          //
          // After...
          // +-----+----+------+-----------+
          // | ... | RC | inst | afterInst |
          // +-----+----+------+-----------+
          // ^prev ^next
          // //////////////////////////////////

          // +-----+------+-----------+
          // | ... | inst | afterInst |
          // +-----+------+-----------+
          // ^prev ^next

          t = iter.previous();
          Assert.isTrue(t == inst, t + " != " + inst);

          // +-----+------+-----------+
          // | ... | inst | afterInst |
          // +-----+------+-----------+
          // ^prev ^next

          addInst = new Instruction(Opcode.opcx_rc, new Integer(depth));
          iter.add(addInst);

          // +-----+----+------+-----------+
          // | ... | RC | inst | afterInst |
          // +-----+----+------+-----------+
          // ^prev ^next

          t = iter.previous();
          Assert.isTrue(t == addInst, t + " != " + addInst);

          // +-----+----+------+-----------+
          // | ... | RC | inst | afterInst |
          // +-----+----+------+-----------+
          // ^prev ^next

          t = iter.next();
          Assert.isTrue(t == addInst, t + " != " + addInst);

          // +-----+----+------+-----------+
          // | ... | RC | inst | afterInst |
          // +-----+----+------+-----------+
          // ^prev ^next

          t = iter.next();
          Assert.isTrue(t == inst, t + " != " + inst);

          // +-----+----+------+-----------+
          // | ... | RC | inst | afterInst |
          // +-----+----+------+-----------+
          // ^prev ^next

          if (Main.VERBOSE > 2) {
            System.out.println("Inserting " + addInst + " before " + inst);
          }
        } else {
          if (Main.VERBOSE > 2) {
            System.out.println("Not inserting rc before " + inst);
          }
        }

        // Insert a swizzle check...
        if (insert_sc) {
          if (Main.SC) {
            Object t;

            // ////////////////////////////////////////////
            // Before...
            // +-----+------+-----------+
            // | ... | inst | afterInst |
            // +-----+------+-----------+
            // ^prev ^next
            //
            // After...
            // +-----+------+----------+------+-----------+
            // | ... | dup2 | aswizzle | inst | afterInst |
            // +-----+------+----------+------+-----------+
            // ^prev ^next
            // /////////////////////////////////////////////

            // +-----+------+-----------+
            // | ... | inst | afterInst |
            // +-----+------+-----------+
            // ^prev ^next

            t = iter.previous();
            Assert.isTrue(t == inst, t + " != " + inst);

            // +-----+------+-----------+
            // | ... | inst | afterInst |
            // +-----+------+-----------+
            // ^prev ^next

            addInst = new Instruction(Opcode.opcx_dup2);
            iter.add(addInst);

            // +-----+------+------+-----------+
            // | ... | dup2 | inst | afterInst |
            // +-----+------+------+-----------+
            // ^prev ^next

            t = iter.previous();
            Assert.isTrue(t == addInst, t + " != " + addInst);

            // +-----+------+------+-----------+
            // | ... | dup2 | inst | afterInst |
            // +-----+------+------+-----------+
            // ^prev ^next

            t = iter.next();
            Assert.isTrue(t == addInst, t + " != " + addInst);

            // +-----+------+------+-----------+
            // | ... | dup2 | inst | afterInst |
            // +-----+------+------+-----------+
            // ^prev ^next

            addInst = new Instruction(Opcode.opcx_aswizzle);
            iter.add(addInst);

            // +-----+------+----------+------+-----------+
            // | ... | dup2 | aswizzle | inst | afterInst |
            // +-----+------+----------+------+-----------+
            // ^prev ^next

            t = iter.previous();
            Assert.isTrue(t == addInst, t + " != " + addInst);

            // +-----+------+----------+------+-----------+
            // | ... | dup2 | aswizzle | inst | afterInst |
            // +-----+------+----------+------+-----------+
            // ^prev ^next

            t = iter.next();
            Assert.isTrue(t == addInst, t + " != " + addInst);

            // +-----+------+----------+------+-----------+
            // | ... | dup2 | aswizzle | inst | afterInst |
            // +-----+------+----------+------+-----------+
            // ^prev ^next

            t = iter.next();
            Assert.isTrue(t == inst, t + " != " + inst);

            // +-----+------+----------+------+-----------+
            // | ... | dup2 | aswizzle | inst | afterInst |
            // +-----+------+----------+------+-----------+
            // ^prev ^next

            if (Main.VERBOSE > 2) {
              System.out.println("Inserting dup2,aswizzle before " + inst);
            }
          } else {
            if (Main.VERBOSE > 2) {
              System.out.println("Not inserting aswizzle before " + inst);
            }
          }
        }

        // Insert an update check...
        if (uctype != Main.NONE) {
          if (Main.UC) {
            Object t;

            // ////////////////////////////////////////////
            // Before...
            // +-----+------+-----------+
            // | ... | inst | afterInst |
            // +-----+------+-----------+
            // ^prev ^next
            //
            // After...
            // +-----+---------+------+-----------+
            // | ... | aupdate | inst | afterInst |
            // +-----+---------+------+-----------+
            // ^prev ^next
            // /////////////////////////////////////////////

            // +-----+------+-----------+
            // | ... | inst | afterInst |
            // +-----+------+-----------+
            // ^prev ^next

            t = iter.previous();
            Assert.isTrue(t == inst, t + " != " + inst);

            // +-----+------+-----------+
            // | ... | inst | afterInst |
            // +-----+------+-----------+
            // ^prev ^next

            addInst = new Instruction(Opcode.opcx_aupdate, new Integer(depth));
            /*
             * if (uctype == POINTER) { addInst = new
             * Instruction(opcx_aupdate, new Integer(depth)); } else {
             * addInst = new Instruction(opcx_supdate, new
             * Integer(depth)); }
             */

            iter.add(addInst);

            // +-----+---------+------+-----------+
            // | ... | aupdate | inst | afterInst |
            // +-----+---------+------+-----------+
            // ^prev ^next

            t = iter.previous();
            Assert.isTrue(t == addInst, t + " != " + addInst);

            // +-----+---------+------+-----------+
            // | ... | aupdate | inst | afterInst |
            // +-----+---------+------+-----------+
            // ^prev ^next

            t = iter.next();
            Assert.isTrue(t == addInst, t + " != " + addInst);

            // +-----+---------+------+-----------+
            // | ... | aupdate | inst | afterInst |
            // +-----+---------+------+-----------+
            // ^prev ^next

            t = iter.next();
            Assert.isTrue(t == inst, t + " != " + inst);

            // +-----+---------+------+-----------+
            // | ... | aupdate | inst | afterInst |
            // +-----+---------+------+-----------+
            // ^prev ^next

            if (Main.VERBOSE > 2) {
              System.out.println("Inserting " + addInst + " before " + inst);
            }
          } else if (Main.VERBOSE > 2) {
            System.out.println("Not inserting uc before " + inst);
          }
        }
      }
    }
  }