/* This file is part of JOP, the Java Optimized Processor see <http://www.jopdesign.com/> Copyright (C) 2004,2005, Flavius Gruian Copyright (C) 2005-2008, Martin Schoeberl (martin@jopdesign.com) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.jopdesign.build; import com.jopdesign.common.bcel.CustomAttribute; import java.io.FileOutputStream; import java.io.PrintWriter; import java.io.Serializable; /** * @author flavius, martin * */ public class JOPizer extends OldAppInfo implements Serializable { // needed to avoid issues related to store/load of serializable content private static final long serialVersionUID = 1307508540685275006L; public final static String nativeClass = "com.jopdesign.sys.Native"; public final static String startupClass = "com.jopdesign.sys.Startup"; public final static String jvmClass = "com.jopdesign.sys.JVM"; public final static String helpClass = "com.jopdesign.sys.JVMHelp"; public final static String bootMethod = "boot()V"; public final static String mainMethod = "main([Ljava/lang/String;)V"; public final static String rttmClass = "rttm.internal.Utils"; public final static String stringClass = "java.lang.String"; public final static String objectClass = "java.lang.Object"; public static final int PTRS = 6; public static final int IMPORTANT_PTRS = 12; public static final int GCINFO_NONREFARRY = 6; // gci is at -1 from classinfo public static final int CLASSINFO_NONREFARRY = GCINFO_NONREFARRY + 1; public static final int GCINFO_REFARRY = GCINFO_NONREFARRY+2; // gci must be at classinfo-1 public static final int CLASSINFO_REFARRY = GCINFO_NONREFARRY + 1; public static final int CLINITS_OFFSET = 11; public static final boolean CACHE_INVAL = false; public static final boolean USE_RTTM = false; /** * Maximum method size (for minimum cache) in bytes. * Is enforced in VHDL by an assertion statement. */ public static final int METHOD_MAX_SIZE = 2048; public static boolean dumpMgci = false; /** .jop output file */ transient PrintWriter out; /** text file for additional information */ transient PrintWriter outTxt; /** link info for the D$ analysis */ transient PrintWriter outLinkInfo; /** * Length of the generated application in words. * It is written as the first word in .jop * Equal to the address of the first free memory = heap start. */ int length; /** * Start of bytecode */ int codeStart; /** * Address of the important pointers */ int pointerAddr; /** * Address of class info structures */ int clinfoAddr; // Added to implement the symbol manager public static JOPizer jz; public JOPizer(OldClassInfo template) { super(template); } public static void main(String[] args) { dumpMgci = System.getProperty("mgci", "false").equals("true"); if (USE_RTTM) { // This will be done by AppSetup CustomAttribute.registerDefaultReader(); } // TODO: small change to implement quickly the symbol manager // JOPizer jz = new JOPizer(); jz = new JOPizer(JopClassInfo.getTemplate()); if(args.length < 3) { System.err.println("JOPizer arguments: [-cp classpath] -o file class [class]*"); System.exit(-1); }; jz.parseOptions(args); if(jz.outFile == null) { System.err.println("JOPizer: Missing argument: '-o file'"); System.exit(-1); } jz.addClass(startupClass); jz.addClass(jvmClass); jz.addClass(helpClass); if (USE_RTTM) { jz.addClass(rttmClass); } jz.excludeClass(nativeClass); try { jz.out = new PrintWriter(new FileOutputStream(jz.outFile)); jz.outTxt = new PrintWriter(new FileOutputStream(jz.outFile+".txt")); jz.outLinkInfo = new PrintWriter(new FileOutputStream(jz.outFile+".link.txt")); jz.load(); if (USE_RTTM) { jz.iterate(new ReplaceAtomicAnnotation(jz)); } // Reduce constant pool // TODO: remove unused field and static field entries // and remove the code from resolveCPool(cp). jz.iterate(new FindUsedConstants(jz)); // length of the reduced cpool is now known if(dumpMgci){ jz.iterate(new SetGCRTMethodInfo(jz)); } // replace the wide instructions generated // by Sun's javac 1.5 // TODO ReplaceIinc and InerstSynchronized has been ported to new AppInfo already, port rest of this tool! /* jz.iterate(new ReplaceIinc()); // add monitorenter and exit for synchronized // methods jz.iterate(new InsertSynchronized()); */ // dump of BCEL info to a text file jz.iterate(new Dump(jz, jz.outTxt)); // BuildVT was after SetMethodInfo // we need it for replace of field offsets // is this ok? // TODO: split VT and field info... // Build the virtual tables BuildVT vt = new BuildVT(jz); jz.iterate(vt); // find all <clinit> methods and their dependency, // resolve the depenency and generate the list OldClinitOrder cliOrder = new OldClinitOrder(jz); jz.iterate(cliOrder); JopMethodInfo.clinitList = cliOrder.findOrder(); // calculate addresses for static fields jz.iterate(new CountStaticFields(jz)); int addrVal = 2; JopClassInfo.addrValueStatic = addrVal; int addrRef = JopClassInfo.addrValueStatic + JopClassInfo.cntValueStatic; JopClassInfo.addrRefStatic = addrRef; jz.iterate(new SetStaticAddresses(jz)); // set back the start addresses JopClassInfo.addrValueStatic = addrVal; JopClassInfo.addrRefStatic = addrRef; // change methods - replace Native calls // TODO: also change the index into the cp for the // reduced version. jz.iterate(new ReplaceNativeAndCPIdx(jz)); // No further access via BCEL is now possible - // we have 'illegal' instructions in the bytecode. jz.codeStart = JopClassInfo.addrRefStatic + JopClassInfo.cntRefStatic;; // Now we can set the method info code and the address // jz.pointerAddr is set jz.iterate(new SetMethodAddress(jz)); // How long is the <clinit> List? int cntClinit = JopMethodInfo.clinitList.size(); // How long is the string table? StringInfo.stringTableAddress = jz.pointerAddr+PTRS+cntClinit+1; // Start of class info jz.clinfoAddr = StringInfo.stringTableAddress + StringInfo.length; // Calculate class info addresses ClassAddress cla = new ClassAddress(jz, jz.clinfoAddr); jz.iterate(cla); // Now all sizes are known jz.length = cla.getAddress(); // As all addresses are now known we can // resolve the constants. jz.iterate(new ResolveCPool(jz)); // Finally we can write the .jop file.... new JopWriter(jz).write(); jz.outLinkInfo.close(); } catch(Exception e) { e.printStackTrace();} } }