javacodecompact.java
来自「This is a resource based on j2me embedde」· Java 代码 · 共 1,056 行 · 第 1/3 页
JAVA
1,056 行
/* * @(#)JavaCodeCompact.java 1.96 06/11/07 * * Copyright 1990-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 only, as published by the Free Software Foundation. * * 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 version 2 for more details (a copy is * included at /legal/license.txt). * * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. * */import consts.*;import components.*;import vm.*;import runtime.*;import util.Assert;import util.*;import jcc.*;import java.io.FileReader;import java.io.BufferedReader;import java.io.PrintStream;import java.io.FileOutputStream;import java.io.IOException;import java.io.File;import java.util.Enumeration;import java.util.HashSet;import java.util.Hashtable;import java.util.Set;import java.util.Vector;import components.ClassLoader;public class JavaCodeCompact extends LinkerUtil { int verbosity = 0; //ConstantPool classNameConstants = new ConstantPool(); ClassFileFinder searchPath; String firstFileName; static String outName; /** If true, JCC should include class debug info in generated class data. * This includes line number tables, local var info, etc. */ boolean classDebug = false; boolean outSet = false; String archName = "CVM"; boolean archSet = false; /** If true, JCC will attempt to share the same constant pool for all the * classes that it romizes. */ boolean useSharedCP = false; boolean validate = false; boolean unresolvedOk = false; Vector romAttributes = new Vector(); ClassReader rdr; Hashtable headerDirs = new Hashtable(31); String stubDestName; boolean stubTraceMode = false; ClassnameFilterList nativeTypes = new ClassnameFilterList(); ClassnameFilterList extraHeaders = new ClassnameFilterList(); int maxSegmentSize = -1; boolean firstTimeOnly = true; /* arguments for JavaAPILister */ static String APIListerArgs = null; private void fileFound(String fname) { // currently, the only thing we do with file names // is make them into potential output file names. if (firstFileName == null) firstFileName = fname; } private void makeOutfileName(){ if ( outName != null ) return; // already done by -o option. if (firstFileName==null) firstFileName = "ROMjava.c"; int sepindex = firstFileName.lastIndexOf( File.separatorChar )+1; int suffindex = firstFileName.lastIndexOf( '.' ); if ( suffindex < 0 ) suffindex = firstFileName.length(); outName = firstFileName.substring( sepindex, suffindex) + ".c"; } private boolean readFile(String fileName, Vector classesRead) { if (rdr == null){ rdr = new ClassReader(verbosity); } try { if (fileName.endsWith(".zip") || fileName.endsWith(".jar")){ rdr.readZip(fileName, classesRead); } else { rdr.readFile(fileName, classesRead); } fileFound(fileName); } catch (IOException e) { System.out.println(Localizer.getString( "javacodecompact.could_not_read_file", fileName)); e.printStackTrace(); return false; } return true; } /* Return the outName string. */ public static String getOutName() { return outName; } /** * Iterate through the classes looking for unresolved * class references. */ protected Set findUnresolvedClassNames(Enumeration e){ Set undefinedClassNames = new HashSet(); ClassInfo cinfo; while (e.hasMoreElements()){ cinfo = (ClassInfo)e.nextElement(); cinfo.findUndefinedClasses(undefinedClassNames); } return undefinedClassNames; } /* * Find the unresolved class names. * Make a list of them, as java Strings. */ public String[] unresolvedClassNames(Set undefinedClassNames){ int nUndefined; nUndefined = undefinedClassNames.size(); if (nUndefined == 0) return null; String names[] = new String[nUndefined]; names = (String[])undefinedClassNames.toArray(names); return names; } Vector classesProcessed = new Vector(); int nclasses = 0; /** If true, JCC is not allowed to do lossy quickening. */ boolean qlossless = false; /** If true, JCC needs to generate JIT friendly output. */ boolean jitOn = false; /** If true, JCC is not allowed to apply optimizations that can compact * the code. Example of such compaction includes removing nop bytecodes, * and useless gotos. */ boolean noCodeCompaction = false; /** * Processes all the JCC command line arguments into internal flags. Also * checks for the validity of the arguments. * * NOTE: processOptions() also loads and processes all the classfiles of * the initial set to be romized. Later on, process() will pull in all * other classes needed for the full transitive closure of class * references from the constant pools of the classes. processOptions() * does not resolve any of the constant pool entries (not even those in * the initial set of classes). The only CP entries that can be resolved * here are the UTF8 and value constants that do not require binding to * and other classes. * * @return false if an error was encountered. */ private boolean processOptions(String clist[]) throws Exception { boolean success = true; for( int i = 0; i < clist.length; i++ ){ if ( clist[i].equals(/*NOI18N*/"-jit") ){ jitOn = true; // Generate JIT friendly output. continue; } else if ( clist[i].equals(/*NOI18N*/"-qlossless") ){ qlossless = true; // Disallow lossy quickening. continue; } else if ( clist[i].equals(/*NOI18N*/"-noCodeCompaction") ){ noCodeCompaction = true; // Disallow code compaction. continue; } else if ( clist[i].equals(/*NOI18N*/"-g") ){ classDebug = true; // Include class debug info. ClassInfo.classDebug = true; continue; } else if ( clist[i].equals(/*NOI18N*/"-imageAttribute") ){ romAttributes.addElement( clist[ ++i ] ); continue; } else if ( clist[i].equals(/*NOI18N*/"-v") ){ verbosity++; continue; } else if ( clist[i].equals(/*NOI18N*/"-o") ){ outName = clist[ ++i ]; } else if ( clist[i].equals(/*NOI18N*/"-classpath") ){ if ( searchPath == null ) { searchPath = new ClassFileFinder(); ClassTable.setSearchPath(searchPath); } searchPath.addToSearchPath( clist[ ++i ] ); } else if ( clist[i].equals(/*NOI18N*/"-arch") ){ String archArg = clist[ ++i ]; archName = archArg.toUpperCase(); if ( archSet ){ System.err.println(Localizer.getString( "javacodecompact.too_many_-arch_targetarchname_specifiers")); success = false; } archSet = true; continue; } else if (clist[i].equals("-target")){ if (!VMConfig.setJDKVersion(clist[++i])) { System.err.println(Localizer.getString( "javacodecompact.invalid_target_version", clist[i])); return false; } } else if (clist[i].equals("-sharedCP")){ useSharedCP = true; } else if ( clist[i].equals("-headersDir") ){ String type = clist[++i]; String dir = clist[++i]; headerDirs.put(type, dir);/* These not supported by CVM } else if ( clist[i].equals("-stubs") ){ stubDestName = clist[++i]; } else if ( clist[i].equals("-trace") ){ stubTraceMode = true;*/ } else if ( clist[i].equals("-f") ){ try { success = processOptions( parseOptionFile( clist[++i] ) ); } catch ( java.io.IOException e ){ e.printStackTrace(); success = false; } } else if ( clist[i].equals("-nativesType") ){ String name = clist[++i]; String patterns = clist[++i]; nativeTypes.addTypePatterns( name, patterns ); } else if ( clist[i].equals("-extraHeaders") ){ String name = clist[++i]; String patterns = clist[++i]; extraHeaders.addTypePatterns( name, patterns ); } else if ( clist[i].equals("-maxSegmentSize") ){ String arg = clist[++i]; try { maxSegmentSize = Integer.parseInt(arg); } catch (NumberFormatException ex) { System.err.println(Localizer.getString( "javacodecompact.invalid_max_segment_size")); success = false; } } else if ( clist[i].equals("-validate") ){ // validate data structures before writing output validate = true; } else if ( clist[i].equals("-excludeFile") ){ // A file containing a list of methods & fields to exclude readExcludeFile(clist[++i]); } else if (clist[i].equals("-allowUnresolved")){ unresolvedOk = true; } else if (clist[i].startsWith("-cl:")){ process(false); searchPath = null; // user classloader String arg = clist[i].substring("-cl:".length()); String name; ClassLoader parent = null; int sepIndex = arg.indexOf(':'); if (sepIndex > 0) { name = arg.substring(0, sepIndex); String parentName = arg.substring(sepIndex + 1, arg.length()); parent = ClassTable.getClassLoader(parentName); if (parent == null) { /* parent classloader not defined */ System.err.println(Localizer.getString("javacodecompact.parent_classloader_not_defined", parentName) ); return false; } } else { name = arg; parent = ClassTable.getClassLoader(); } if (ClassTable.getClassLoader(name) != null) { /* classloader name already used */ System.err.println(Localizer.getString("javacodecompact.classloader_already_defined", name) ); return false; } ClassLoader l = new components.ClassLoader(name, parent); ClassTable.setClassLoader(l); } else if (clist[i].startsWith("-listapi:")) { APIListerArgs = clist[i]; } else { Vector classesRead = new Vector(); /* Read in classes that need to be ROMized. */ classesRead.clear(); if (!readFile(clist[i], classesRead)) { success = false; // but keep going to process rest of options anyway. } classesProcessed.addAll(classesRead); ClassTable.initIfNeeded(verbosity); if (!ClassTable.enterClasses(classesRead.elements())) { success = false; } } } // Default classname filter for natives nativeTypes.addTypePatterns( "JNI", "-*" ); return success; } private boolean loadClass(ClassLoader cl, String classname, Vector oneClass) throws Exception { ClassLoader parent = cl.getParent(); if (parent != null) { if (loadClass(parent, classname, oneClass)) { return true; } } ClassFileFinder searchPath = cl.getSearchPath(); if (searchPath == null) { // If the search path is empty, then there is no place else // to look for the class. So, fail: return false; } int nfound = rdr.readClass(classname, searchPath, oneClass); if (nfound == 1) { // Add class to the appropriate classloader ClassInfo ci = (ClassInfo)oneClass.elementAt(0); if (!ClassTable.enterClass(ci, cl)) { throw new Exception(); }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?