Пример #1
0
  public void write(DataOutputStream stream) throws IOException {
    byte[] bytes = this.stream.toByteArray();

    fixLabels(bytes);

    int n = exceptions.size();
    int length = bytes.length + 12 + 8 * n;
    ;
    if (linenumbers != null) length += linenumbers.length();
    stream.writeShort(att_name);
    stream.writeInt(length);
    stream.writeShort(max_stack);
    stream.writeShort(nlocals);
    stream.writeInt(bytes.length);
    stream.write(bytes);

    // No Exceptions for now
    stream.writeShort(n);
    for (int i = 0; i < n; i++) {
      ExceptionLabel e = (ExceptionLabel) exceptions.elementAt(i);
      stream.writeShort(e.start.getPosition());
      stream.writeShort(e.end.getPosition());
      stream.writeShort(e.handler.getPosition());
      stream.writeShort(e.exc);
    }
    if (linenumbers != null) ClassFile.writeAttributes(stream, new Attribute[] {linenumbers});
    else ClassFile.writeAttributes(stream, new Attribute[0]);
  }
Пример #2
0
  /** {@inheritDoc} */
  public void convert(Klass klass) {
    lastClassNameStack.push(klass.getName());
    int state = klass.getState();
    if (state < Klass.STATE_CONVERTING) {
      if (klass.isArray()) {
        convert(Klass.OBJECT);
        klass.changeState(Klass.STATE_CONVERTED);
      } else {
        traceProgress();

        ClassFile classFile = getClassFile(klass);
        classFile.convertPhase1(this, translationStrategy != BY_METHOD);
        if (klass.hasGlobalStatics()) {
          // record globals now.
          recordGlobalStatics(klass);
        }

        if (translationStrategy == BY_METHOD || translationStrategy == BY_CLASS) {
          // if NOT inlining, then generate squawk code now.
          classFile.convertPhase2(this, translationStrategy == BY_METHOD);
          classFiles.remove(klass.getName());
        }
      }
    }
    lastClassNameStack.pop();
  }
Пример #3
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
  }
Пример #4
0
 /**
  * Generate squawk code for methods of <code>klass</code> when doing whole-suite translation
  * (inlining, etc.)
  *
  * @param klass the klass to generate code for
  */
 void convertPhase2(Klass klass) {
   Assert.that(translationStrategy != BY_METHOD);
   convert(klass);
   if (klass.getState() < Klass.STATE_CONVERTED) {
     if (!VM
         .isVerbose()) { // "squawk -verbose" will show the class names as it finishes loading
                         // them, which is progress enough
       traceProgress();
     }
     lastClassNameStack.push(klass.getName());
     ClassFile classFile = getClassFile(klass);
     classFile.convertPhase2(this, false);
     classFiles.remove(klass.getName());
     lastClassNameStack.pop();
   }
 }
Пример #5
0
  public void run() throws Exception {
    File javaFile = writeTestFile();
    File classFile = compileTestFile(javaFile);

    ClassFile cf = ClassFile.read(classFile);
    test(cf);
    for (Field f : cf.fields) {
      test(cf, f);
    }
    for (Method m : cf.methods) {
      test(cf, m);
    }

    countAnnotations();

    if (errors > 0) throw new Exception(errors + " errors found");
    System.out.println("PASSED");
  }
 /**
  * @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
     }
   }
 }
Пример #7
0
 /** Returns the type. */
 public String getType(ClassFile classFile) {
   return classFile.getCpString(u2descriptorIndex);
 }
Пример #8
0
 /** Returns the name. */
 public String getName(ClassFile classFile) {
   return classFile.getCpString(u2nameIndex);
 }
Пример #9
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());
    }
  }
Пример #10
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);
  }
Пример #11
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());
    }
  }
Пример #12
0
  /**
   * Factory method for creating <tt>AttributeInfo</tt> structures.
   *
   * <p>An <tt>AttributeInfo</tt> of the appropriate subtype from the <tt>attributes</tt> package is
   * created unless the type of the attribute is unknown in which case an instance of
   * <tt>AttributeInfo</tt> is returned.
   *
   * <p>
   *
   * <p>Attributes are skipped if the environment variable <tt>SYSTEM_PROPERTY_SKIP_ATTRIBUTES</tt>
   * is set to true.
   *
   * @param in the <tt>DataInput</tt> from which to read the <tt>AttributeInfo</tt> structure
   * @param classFile the parent class file of the structure to be created
   * @return the new <tt>AttributeInfo</tt> structure
   * @throws InvalidByteCodeException if the byte code is invalid
   * @throws IOException if an exception occurs with the <tt>DataInput</tt>
   */
  public static AttributeInfo createOrSkip(DataInput in, ClassFile classFile)
      throws InvalidByteCodeException, IOException {

    AttributeInfo attributeInfo = null;

    if (Boolean.getBoolean(SYSTEM_PROPERTY_SKIP_ATTRIBUTES)) {
      in.skipBytes(2);
      in.skipBytes(in.readInt());
    } else {
      int attributeNameIndex = in.readUnsignedShort();
      int attributeLength = in.readInt();

      ConstantUtf8Info cpInfoName = classFile.getConstantPoolUtf8Entry(attributeNameIndex);
      String attributeName = null;

      if (cpInfoName == null) {
        return null;
      }

      attributeName = cpInfoName.getString();

      if (ConstantValueAttribute.ATTRIBUTE_NAME.equals(attributeName)) {
        attributeInfo = new ConstantValueAttribute();

      } else if (CodeAttribute.ATTRIBUTE_NAME.equals(attributeName)) {
        attributeInfo = new CodeAttribute();

      } else if (ExceptionsAttribute.ATTRIBUTE_NAME.equals(attributeName)) {
        attributeInfo = new ExceptionsAttribute();

      } else if (InnerClassesAttribute.ATTRIBUTE_NAME.equals(attributeName)) {
        attributeInfo = new InnerClassesAttribute();

      } else if (SyntheticAttribute.ATTRIBUTE_NAME.equals(attributeName)) {
        attributeInfo = new SyntheticAttribute();

      } else if (SourceFileAttribute.ATTRIBUTE_NAME.equals(attributeName)) {
        attributeInfo = new SourceFileAttribute();

      } else if (LineNumberTableAttribute.ATTRIBUTE_NAME.equals(attributeName)) {
        attributeInfo = new LineNumberTableAttribute();

      } else if (LocalVariableTableAttribute.ATTRIBUTE_NAME.equals(attributeName)) {
        attributeInfo = new LocalVariableTableAttribute();

      } else if (DeprecatedAttribute.ATTRIBUTE_NAME.equals(attributeName)) {
        attributeInfo = new DeprecatedAttribute();

      } else if (EnclosingMethodAttribute.ATTRIBUTE_NAME.equals(attributeName)) {
        attributeInfo = new EnclosingMethodAttribute();

      } else if (SignatureAttribute.ATTRIBUTE_NAME.equals(attributeName)) {
        attributeInfo = new SignatureAttribute();

      } else if (LocalVariableTypeTableAttribute.ATTRIBUTE_NAME.equals(attributeName)) {
        attributeInfo = new LocalVariableTypeTableAttribute();

      } else if (RuntimeVisibleAnnotationsAttribute.ATTRIBUTE_NAME.equals(attributeName)) {
        attributeInfo = new RuntimeVisibleAnnotationsAttribute();

      } else if (RuntimeInvisibleAnnotationsAttribute.ATTRIBUTE_NAME.equals(attributeName)) {
        attributeInfo = new RuntimeInvisibleAnnotationsAttribute();

      } else if (AnnotationDefaultAttribute.ATTRIBUTE_NAME.equals(attributeName)) {
        attributeInfo = new AnnotationDefaultAttribute();

      } else if (BootstrapMethodsAttribute.ATTRIBUTE_NAME.equals(attributeName)) {
        attributeInfo = new BootstrapMethodsAttribute(attributeLength);

      } else {
        attributeInfo = new AttributeInfo(attributeLength);
      }
      attributeInfo.setAttributeNameIndex(attributeNameIndex);
      attributeInfo.setClassFile(classFile);
      attributeInfo.read(in);
    }

    return attributeInfo;
  }