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]); }
/** {@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(); }
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 }
/** * 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(); } }
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 } } }
/** Returns the type. */ public String getType(ClassFile classFile) { return classFile.getCpString(u2descriptorIndex); }
/** Returns the name. */ public String getName(ClassFile classFile) { return classFile.getCpString(u2nameIndex); }
/** * 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()); } }
/** * 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); }
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()); } }
/** * 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; }