/*
  * and as a public service to ClassEntry...
  */
 ClassInfo findClassInfo(String cname) {
   InputStream fin = finder.findClassFile(cname);
   if (fin == null) return null;
   ClassFile cfile = new ClassFile(cname, fin, false);
   if (!cfile.readClassFile()) {
     cfile.dump(System.err);
     return null;
   }
   return cfile.cinfo;
 }
예제 #2
0
  public static void load(ClassData k) throws ClassNotFoundException, IOException {
    ClassData kp;
    String sname;

    sname = k.supername; // name of superclass

    if (k.superclass == null && sname != null) {

      // there is a superclass and it has not been linked in

      for (kp = previous; kp != null; kp = kp.superclass) if (kp.name.equals(sname)) break;

      if (kp != null) k.superclass = kp; // found in existing chain
      else {
        // not found; find and load superclass from file
        ClassFile cf = ClassFile.find(sname);
        k.superclass = ClassData.forStream(null, cf, false);
        //            System.out.println (sname + " from " + cf.dir);

        /* Resulting class has to have the right name. */
        if (!sname.equals(k.superclass.name)) {
          throw new ClassNotFoundException(sname);
        }
        load(k.superclass); // load superclass's superclasses
      }
    }

    k.state = ClassData.RES_SUPERCLASSES;

    k.buildTables(); // fill in method table
    IHash.mark(null, k); // mark interfaces
    previous = k; // remember class just loaded
  }
 /**
  * @see
  *     org.eclipse.jdt.internal.core.builder.AbstractImageBuilder#writeClassFileContents(org.eclipse.jdt.internal.compiler.ClassFile,
  *     org.eclipse.core.resources.IFile, java.lang.String, boolean,
  *     org.eclipse.jdt.internal.core.builder.SourceFile)
  */
 protected void writeClassFileContents(
     ClassFile classfile,
     IFile file,
     String qualifiedFileName,
     boolean isTopLevelType,
     SourceFile compilationUnit)
     throws CoreException {
   // Before writing out the class file, compare it to the previous file
   // If structural changes occurred then add dependent source files
   byte[] bytes = classfile.getBytes();
   if (file.exists()) {
     if (writeClassFileCheck(file, qualifiedFileName, bytes)
         || compilationUnit.updateClassFile) { // see 46093
       if (JavaBuilder.DEBUG)
         System.out.println("Writing changed class file " + file.getName()); // $NON-NLS-1$
       if (!file.isDerived()) file.setDerived(true, null);
       file.setContents(new ByteArrayInputStream(bytes), true, false, null);
     } else if (JavaBuilder.DEBUG) {
       System.out.println("Skipped over unchanged class file " + file.getName()); // $NON-NLS-1$
     }
   } else {
     if (isTopLevelType) addDependentsOf(new Path(qualifiedFileName), true); // new type
     if (JavaBuilder.DEBUG)
       System.out.println("Writing new class file " + file.getName()); // $NON-NLS-1$
     try {
       file.create(new ByteArrayInputStream(bytes), IResource.FORCE | IResource.DERIVED, null);
     } catch (CoreException e) {
       if (e.getStatus().getCode() == IResourceStatus.CASE_VARIANT_EXISTS) {
         IStatus status = e.getStatus();
         if (status instanceof IResourceStatus) {
           IPath oldFilePath = ((IResourceStatus) status).getPath();
           char[] oldTypeName = oldFilePath.removeFileExtension().lastSegment().toCharArray();
           char[][] previousTypeNames =
               this.newState.getDefinedTypeNamesFor(compilationUnit.typeLocator());
           boolean fromSameFile = false;
           if (previousTypeNames == null) {
             fromSameFile = CharOperation.equals(compilationUnit.getMainTypeName(), oldTypeName);
           } else {
             for (int i = 0, l = previousTypeNames.length; i < l; i++) {
               if (CharOperation.equals(previousTypeNames[i], oldTypeName)) {
                 fromSameFile = true;
                 break;
               }
             }
           }
           if (fromSameFile) {
             // file is defined by the same compilationUnit, but won't be deleted until later so do
             // it now
             IFile collision = file.getParent().getFile(new Path(oldFilePath.lastSegment()));
             collision.delete(true, false, null);
             boolean success = false;
             try {
               file.create(
                   new ByteArrayInputStream(bytes), IResource.FORCE | IResource.DERIVED, null);
               success = true;
             } catch (CoreException ignored) {
               // ignore the second exception
             }
             if (success) return;
           }
         }
         // catch the case that a type has been renamed and collides on disk with an
         // as-yet-to-be-deleted type
         throw new AbortCompilation(true, new AbortIncrementalBuildException(qualifiedFileName));
       }
       throw e; // rethrow
     }
   }
 }
예제 #4
0
  /**
   * Performs the actual editing of a class. Does a whole mess of stuff including reading in the
   * classfile, building data structures to represent the class file, converting the CFG for each
   * method in the class into SSA form, perform some anlayses and optimizations on the method, and
   * finally committing it back to the class file. Phew.
   */
  private static void editClass(final String className) {
    ClassFile classFile; // Holds info about a class (implements
    // ClassInfo)

    // Get information about the class className
    try {
      classFile = (ClassFile) Main.context.loadClass(className);
    } catch (final ClassNotFoundException ex) {
      System.err.println("** Couldn't find class: " + ex.getMessage());
      return;
    }

    if (!Main.FORCE) {
      // Check to see if the file is up-to-date (i.e. has been
      // recompiled since it was last optimized). If so, do nothing
      // because the FORCE flag is false.

      final File source = classFile.file();
      final File target = classFile.outputFile();

      if ((source != null)
          && (target != null)
          && source.exists()
          && target.exists()
          && (source.lastModified() < target.lastModified())) {

        if (Main.VERBOSE) {
          System.out.println(classFile.name() + " is up to date");
        }

        return;
      }
    }

    if (Main.DEBUG) {
      // Print the contents of the class file to System.out
      classFile.print(System.out);
    }

    final ClassEditor c = Main.context.editClass(classFile);

    boolean skip = false;

    final String name = c.type().className();
    final String qual = c.type().qualifier() + "/*";

    // Edit only classes explicitly mentioned.
    if (Main.ONLY.size() > 0) {
      skip = true;

      // Only edit classes we explicitly don't name.
      for (int i = 0; i < Main.ONLY.size(); i++) {
        final String pkg = (String) Main.ONLY.get(i);

        if (name.equals(pkg) || qual.equals(pkg)) {
          skip = false;
          break;
        }
      }
    }

    // Don't edit classes we explicitly skip.
    if (!skip) {
      for (int i = 0; i < Main.SKIP.size(); i++) {
        final String pkg = (String) Main.SKIP.get(i);

        if (name.equals(pkg) || qual.equals(pkg)) {
          skip = true;
          break;
        }
      }
    }

    if (skip) {
      if (Main.VERBOSE) {
        System.out.println("Skipping " + c.type().className());
      }

      // We're done with this class file, decrement its reference count
      Main.context.release(classFile);
      return;
    }

    // Touch the output file first. That is, create the file, but make
    // it empty, just to make sure we can create it.

    try {
      final File f = classFile.outputFile();

      if (f.exists()) {
        f.delete();
      }

      final File dir = new File(f.getParent());
      dir.mkdirs();

      if (!dir.exists()) {
        throw new RuntimeException("Couldn't create directory: " + dir);
      }

      final DataOutputStream out = new DataOutputStream(new FileOutputStream(f));
      new PrintStream(out).println();
      out.close();
    } catch (final IOException e) {
      e.printStackTrace();
      System.exit(1);
    }

    if (Main.VERBOSE) {
      System.out.println("Optimizing " + c.type().className());
    }

    // Finally, we can start playing with the methods...
    final MethodInfo[] methods = c.methods();

    final int numMethods = methods.length + 1;
    ;
    int whichMethod = 0;

    for (int j = 0; j < methods.length; j++) {
      final MethodEditor m;

      try {
        m = Main.context.editMethod(methods[j]);
      } catch (final ClassFormatException ex) {
        System.err.println(ex.getMessage());
        continue;
      }

      if (Main.TRACE) {
        whichMethod++;
        System.out.println(
            "Optimizing "
                + name
                + "."
                + m.name()
                + " (method "
                + whichMethod
                + " of "
                + numMethods
                + ")");
      }

      if (Main.METHOD != null) {
        // A method name has been specified on the command line using
        // -only-method.
        boolean pass = true;

        String t = m.name() + m.type();

        if (t.equals(Main.METHOD)) {
          pass = false;
        }

        t = m.name();

        if (t.equals(Main.METHOD)) {
          pass = false;
        }

        if (pass) {
          // This isn't the method we're looking for.
          // Decrement its reference count.
          Main.context.release(methods[j]);
          continue;
        }
      }

      if (Main.DEBUG) {
        m.print(System.out);
      }

      if (m.isNative() || m.isAbstract()) {
        // We can't edit native or abstract methods
        Main.context.release(methods[j]);
        continue;
      }

      Main.bloatMethod(m, Main.context);
    }

    if (Main.ANNO) {
      String s = "Optimized with: EDU.purdue.cs.bloat.optimize.Main";

      for (int i = 0; i < Main.ARGS.length; i++) {
        if ((Main.ARGS[i].indexOf(' ') >= 0)
            || (Main.ARGS[i].indexOf('\t') >= 0)
            || (Main.ARGS[i].indexOf('\r') >= 0)
            || (Main.ARGS[i].indexOf('\n') >= 0)) {
          s += " '" + Main.ARGS[i] + "'";
        } else {
          s += " " + Main.ARGS[i];
        }
      }

      System.out.println(s);
      // c.constants().addConstant(Constant.UTF8, s);
    }

    Main.context.commit(classFile);
    Main.context.release(classFile);

    if (Main.TRACE) {
      System.out.println(Main.context.toString());
    }
  }
예제 #5
0
  /**
   * Adds residency/update/swizzle checks to all of the methods in a given class.
   *
   * @param context Information about all the classes we're dealing with
   * @param info Information about the class we're decorating
   */
  private static void decorateClass(final EditorContext context, final ClassInfo info) {
    final ClassFile classFile = (ClassFile) info;

    // Check to see if the class file is up-to-date
    if (!Main.FORCE) {
      final File source = classFile.file();
      final File target = classFile.outputFile();

      if ((source != null)
          && (target != null)
          && source.exists()
          && target.exists()
          && (source.lastModified() < target.lastModified())) {

        if (Main.VERBOSE > 1) {
          System.out.println(classFile.name() + " is up to date");
        }

        return;
      }
    }

    if (Main.VERBOSE > 2) {
      classFile.print(System.out);
    }

    final ClassEditor c = context.editClass(info);

    boolean skip = false;

    final String name = c.type().className();
    final String qual = c.type().qualifier() + "/*";

    // Edit only classes explicitly mentioned.
    if (Main.ONLY.size() > 0) {
      skip = true;

      // Only edit classes we explicitly don't name.
      for (int i = 0; i < Main.ONLY.size(); i++) {
        final String pkg = (String) Main.ONLY.get(i);

        if (name.equals(pkg) || qual.equals(pkg)) {
          skip = false;
          break;
        }
      }
    }

    // Don't edit classes we explicitly skip.
    if (!skip) {
      for (int i = 0; i < Main.SKIP.size(); i++) {
        final String pkg = (String) Main.SKIP.get(i);

        if (name.equals(pkg) || qual.equals(pkg)) {
          skip = true;
          break;
        }
      }
    }

    if (skip) {
      if (Main.VERBOSE > 0) {
        System.out.println("Skipping " + c.type().className());
      }

      context.release(info);
      return;
    }

    if (Main.VERBOSE > 0) {
      System.out.println("Decorating class " + c.type().className());
    }

    if (Main.VERBOSE > 2) {
      ((ClassFile) info).print(System.out);
    }

    final MethodInfo[] methods = c.methods();

    // Add residency checks (via transform()) to each method in the class
    for (int j = 0; j < methods.length; j++) {
      MethodEditor m;

      try {
        m = context.editMethod(methods[j]);
      } catch (final ClassFormatException ex) {
        System.err.println(ex.getMessage());
        continue;
      }

      Main.transform(m);
      context.commit(methods[j]);
    }

    context.commit(info);
  }
예제 #6
0
  public static void main(String[] args) {
    ArrayList<Modifier> modifiers = new ArrayList<Modifier>();
    modifiers.add(Modifier.ACC_PUBLIC);

    // ================================================================================
    // Create an empty class file
    // ================================================================================
    ClassFile cf =
        new ClassFile(
            49, // Java 1.5 or later
            new JvmType.Clazz("", "HelloWorld"), // class is HelloWorld
            JvmTypes.JAVA_LANG_OBJECT, // superclass is Object
            Collections.EMPTY_LIST, // implements no interfaces
            modifiers); // which is public

    // ================================================================================
    // Create a static void main(String[]) method
    // ================================================================================
    modifiers = new ArrayList<Modifier>(modifiers);
    modifiers.add(Modifier.ACC_STATIC);
    ClassFile.Method method =
        new ClassFile.Method(
            "main", // main method
            new JvmType.Function( // is function
                JvmTypes.T_VOID, // from void
                new JvmType.Array(JvmTypes.JAVA_LANG_STRING) // to array of String
                ),
            modifiers // which is static public
            );

    cf.methods().add(method);

    // ================================================================================
    // Add bytecodes for printing hello world to method
    // ================================================================================
    ArrayList<Bytecode> bytecodes = new ArrayList<Bytecode>();

    bytecodes.add(
        new Bytecode.GetField(
            JAVA_LANG_SYSTEM, "out", JAVA_IO_PRINTSTREAM, Bytecode.FieldMode.STATIC));

    bytecodes.add(new Bytecode.LoadConst("Hello World"));

    bytecodes.add(
        new Bytecode.Invoke(
            JAVA_IO_PRINTSTREAM,
            "println",
            new JvmType.Function(JvmTypes.T_VOID, JvmTypes.JAVA_LANG_STRING),
            Bytecode.InvokeMode.VIRTUAL));

    bytecodes.add(new Bytecode.Return(null));

    method.attributes().add(new Code(bytecodes, Collections.EMPTY_LIST, method));

    // ================================================================================
    // Finally, write the class file to disk
    // ================================================================================
    try {
      FileOutputStream fos = new FileOutputStream("HelloWorld.class");
      ClassFileWriter cfw = new ClassFileWriter(fos);
      cfw.write(cf);
    } catch (IOException e) {
      System.out.println("I/O error --- " + e.getMessage());
    }
  }