/**
   * Insert the list of <code>newPasses</code> into <code>passes</code> immediately after the pass
   * named <code>id</code>.
   */
  public void afterPass(List passes, Pass.ID id, List newPasses) {
    for (ListIterator i = passes.listIterator(); i.hasNext(); ) {
      Pass p = (Pass) i.next();

      if (p.id() == id) {
        for (Iterator j = newPasses.iterator(); j.hasNext(); ) {
          i.add(j.next());
        }

        return;
      }
    }

    throw new InternalCompilerError("Pass " + id + " not found.");
  }
  /**
   * Insert the list of <code>newPasses</code> into <code>passes</code> immediately before the pass
   * named <code>id</code>.
   */
  public void beforePass(List passes, Pass.ID id, List newPasses) {
    for (ListIterator i = passes.listIterator(); i.hasNext(); ) {
      Pass p = (Pass) i.next();

      if (p.id() == id) {
        // Backup one position.
        i.previous();

        for (Iterator j = newPasses.iterator(); j.hasNext(); ) {
          i.add(j.next());
        }

        return;
      }
    }

    throw new InternalCompilerError("Pass " + id + " not found.");
  }
  /**
   * Replace the pass named <code>id</code> in <code>passes</code> with the list of <code>newPasses
   * </code>.
   */
  public void replacePass(List passes, Pass.ID id, List newPasses) {
    for (ListIterator i = passes.listIterator(); i.hasNext(); ) {
      Pass p = (Pass) i.next();

      if (p.id() == id) {
        if (p instanceof BarrierPass) {
          throw new InternalCompilerError("Cannot replace a barrier pass.");
        }

        i.remove();

        for (Iterator j = newPasses.iterator(); j.hasNext(); ) {
          i.add(j.next());
        }

        return;
      }
    }

    throw new InternalCompilerError("Pass " + id + " not found.");
  }
Example #4
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);
          }
        }
      }
    }
  }