cvmwriter.java
来自「This is a resource based on j2me embedde」· Java 代码 · 共 1,949 行 · 第 1/5 页
JAVA
1,949 行
/* * @(#)CVMWriter.java 1.153 06/10/27 * * 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. * */package runtime;import consts.Const;import consts.CVMConst;import components.*;import vm.*;import jcc.Util;import util.*;import java.util.Arrays;import java.util.Comparator;import java.util.Vector;import java.util.Enumeration;import java.util.Hashtable;import java.io.OutputStream;/* * The CoreImageWriter for the Embedded VM */public class CVMWriter implements CoreImageWriter, Const, CVMConst { /* INSTANCE DATA */ protected Exception failureMode = null; // only interesting on falure protected String outputFileName; protected CCodeWriter classOut; protected CCodeWriter auxOut; protected OutputStream xxx; protected OutputStream zzz; protected String headerFileName = null; protected CCodeWriter headerOut; protected OutputStream yyy; protected String globalHeaderFileName = null; protected CCodeWriter globalHeaderOut; protected OutputStream www; /* * The following only used if we're segmenting the output, * which happens if this.init gets a maxSegSize > 0 */ protected boolean segmentedOutput; protected int maxClasses; protected int curClasses = 0; protected int nClassfileOut; protected BufferedPrintStream listOut; protected CVMStringTable stringTable; protected CVMClass classes[]; private VMClassFactory classMaker = new CVMClassFactory(); private CVMInitInfo initInfo; private CVMInitInfo initInfoForMBs; boolean formatError = false; boolean verbose = false; boolean classDebug = false; boolean lossless = false; boolean mutableMBs = false; private static final String staticInitThreadStoreName="StaticInitThreadStorage"; private static final String stringArrayName = "CVM_ROMStrings"; private static final String masterStringArrayName = "CVM_ROMStringsMaster"; private static final String staticStoreName = "CVM_staticData"; private static final String numStaticStoreName = "CVM_nStaticData"; private static final String masterStaticStoreName = "CVM_StaticDataMaster"; private ClassnameFilterList nativeTypes; private ClassnameFilter invisibleClassList = new ClassnameFilter(); private boolean classLoading = true; // by default. // Place all byte codes into read-write memory. Useful for setting // breakpoints. protected boolean noPureCode = false; private boolean doShared; private String sharedConstantPoolName; private int sharedConstantPoolSize; private CVMMethodType[] methodTypes; private int[] nMethodTypes; private int totalMethodTypes; // // to keep track of which variants of classblock, method arrays, field arrays, // and method descriptors have been declared // see declareClassblock, declareMethodArray, and declareFieldArray // respectively // private java.util.BitSet classblockSizes = new java.util.BitSet(); private java.util.BitSet runtimeMethodArraySizes = new java.util.BitSet(); private java.util.BitSet methodArraySizes = new java.util.BitSet(); private java.util.BitSet compressibleMethodArraySizes = new java.util.BitSet(); private java.util.BitSet fieldArraySizes = new java.util.BitSet(); /* * Per-class data that is built up as we * print out the various data structures. * Rather than trying to pass around both name and size of each, * we collect the information here. */ private String classBlockName; private String constantPoolName; private int constantPoolSize; private String methodArrayName; private int methodTableSize; private String checkedExceptionName; private String interfaceTableName; private String fieldTableName; private int fieldTableSize; /* for statistics only */ int ncodebytes; int ncatchframes; int nmethods; int nfields; int nconstants; int njavastrings; int ninnerclasses; int nWritableMethodBlocks; int nClassesWithWritableMethodBlocks; int nClinits; int nMethodsWithCheckinitInvokes; int nTotalMethods; /* number of total romized methods */ private CVMMethodStats methStats = new CVMMethodStats(); public CVMWriter( ){ initInfo = new CVMInitInfo(); initInfoForMBs = new CVMInitInfo(); stringTable = new CVMStringTable(initInfo); } public void init(boolean classDebug, boolean lossless, ClassnameFilterList nativeTypes, boolean verbose, int maxSegmentSize, boolean mutableMBs) { this.verbose = verbose; this.classDebug = classDebug; this.lossless = lossless; this.nativeTypes = nativeTypes; this.mutableMBs = mutableMBs; if ( maxSegmentSize > 0 ){ this.segmentedOutput = true; this.maxClasses = maxSegmentSize; } else { this.segmentedOutput = false; } } // If attribute starts with attributeName, then parse the rest of the // string as a list of classes. private boolean parseClassListAttribute(String attributeName, String attribute, ClassnameFilter filter) { if (!attribute.startsWith(attributeName)) return false; String val = attribute.substring(attributeName.length() ); java.util.StringTokenizer tkn = new java.util.StringTokenizer(val, " ,", false ); while ( tkn.hasMoreTokens() ){ String classname = tkn.nextToken().replace('.', '/'); filter.includeName(classname); } return true; } private boolean isClassInvisible( String classname ) { return invisibleClassList.accept(null, classname); } private boolean isClassCNI( String classname) { // compare against interned string return nativeTypes.isType( classname, "CNI" ); } private boolean isClassJNI( String classname) { // compare against interned string return nativeTypes.isType( classname, "JNI" ); } public boolean setAttribute( String attribute ){ if ( parseClassListAttribute("invisible=", attribute, invisibleClassList)){ return true; } else if ( attribute.equals("noClassLoading" ) ){ classLoading = false; return true; } else if ( attribute.equals("noPureCode") ) { noPureCode = true; return true; } else return false; // no attribute by this name. } /* * If this is a simple, unsegmented output file, then * the file name given is the name of the C file, from which * we compute the .h file, crudely. We open them here. * * But if this is a segmented output job, then the name given * serves as a prefix, and we open a whole bunch of files and * set up a whole bunch of state: * filename+"List" - file containing names of all .c files * generated opened as listOut; * filename+".h" - header file, as usual * filename+"Aux.c" - file containing all type, string, and other * miscellanious generated stuff. * opened as auxOut; * filename+"Class"+n+".c" - files containing directly class- * related data, whole classes, and a max of * this.maxClasses of them apiece. */ public boolean open( String filename ){ if ( classOut != null ) close(); outputFileName = filename; if ( ! segmentedOutput ){ /* old-fashioned, single output case */ if ( filename == null ){ xxx = System.out; headerFileName = "jcc.output.h"; } else { try { xxx = new java.io.FileOutputStream( filename ); } catch ( java.io.IOException e ){ failureMode = e; return false; } headerFileName = filename+".h"; } try { classOut = auxOut = new CCodeWriter( xxx ); yyy = new java.io.FileOutputStream( headerFileName ); headerOut = new CCodeWriter( yyy ); globalHeaderFileName = filename+"Globals.h"; www = new java.io.FileOutputStream( globalHeaderFileName ); globalHeaderOut = new CCodeWriter ( www ); } catch ( java.io.IOException e ){ failureMode = e; return false; } writeHeaderPrologue( headerOut ); writeGlobalHeaderPrologue( globalHeaderOut ); writePrologue( classOut ); return true; } else { /* segmented output. * open the aux file, the first classOut file, the list file and * the header file. */ curClasses = 0; nClassfileOut = 0; headerFileName = outputFileName+".h"; try { yyy = new java.io.FileOutputStream( headerFileName ); headerOut = new CCodeWriter( yyy ); globalHeaderFileName = outputFileName+"Globals.h"; www = new java.io.FileOutputStream( globalHeaderFileName ); globalHeaderOut = new CCodeWriter ( www ); zzz = new java.io.FileOutputStream( filename+"Aux.c"); auxOut = new CCodeWriter( zzz ); listOut = new BufferedPrintStream( new java.io.FileOutputStream(outputFileName + "List")); listOut.println( filename+"Aux.c"); openNextClassFile(); } catch ( java.io.IOException e ){ failureMode = e; return false; } writeHeaderPrologue( headerOut ); writeGlobalHeaderPrologue( globalHeaderOut ); writePrologue( auxOut ); /* * Moved global variables to CVMROMGlobals */ auxOut.println(""); auxOut.println("/* Moved global variables to CVMROMGlobals."); auxOut.println(" * For each global variable <V> that was originally accessible outside"); auxOut.println(" * the generated code, a corresponding constant pointer variable"); auxOut.println(" * is provided here that points into the global structure."); auxOut.println(" * (the name <V> has only been changed to <V>ptr for those"); auxOut.println(" * variables where the way they are accessed is changed)"); auxOut.println(" * "); auxOut.println(" * The size of CVMROMGlobals is provided in a global constant"); auxOut.println(" * so that the structure can be copied without including its definition."); auxOut.println(" */"); auxOut.println(""); auxOut.println("struct CVMROMGlobalState CVMROMGlobals;"); auxOut.println("const int CVMROMGlobalsSize = sizeof(CVMROMGlobals);"); auxOut.println(""); auxOut.println("CVMTypeIDNamePart * const CVMMemberNameHash = CVMROMGlobals.CVMMemberNameHash;"); auxOut.println("CVMTypeIDTypePart * const CVMMethodTypeHash = CVMROMGlobals.CVMMethodTypeHash;"); auxOut.println("struct sigForm ** const CVMformTablePtr = &CVMROMGlobals.CVMformTable;"); auxOut.println("struct pkg * const CVM_ROMpackages = CVMROMGlobals.CVM_ROMpackages;"); auxOut.println("struct pkg ** const CVM_pkgHashtable = CVMROMGlobals.CVM_pkgHashtable;"); auxOut.println("struct java_lang_Class * const CVM_ROMClassBlocks = CVMROMGlobals.CVM_ROMClassBlocks;"); auxOut.println("struct java_lang_Class * const CVM_ROMClasses = CVMROMGlobals.CVM_ROMClasses;"); auxOut.println("CVMAddr * const CVM_staticData = CVMROMGlobals.CVM_staticData;"); auxOut.println("struct java_lang_String * const CVM_ROMStrings = CVMROMGlobals.CVM_ROMStrings;"); auxOut.println("#if defined(CVM_JIT) && defined(CVM_MTASK)"); auxOut.println("CVMUint16 * const CVMROMMethodInvokeCosts = CVMROMGlobals.CVMROMMethodInvokeCosts;"); auxOut.println("#endif"); auxOut.println(""); return true; } } private void openNextClassFile() throws java.io.IOException{ if ( classOut != null ){ classOut.close(); } String newName = outputFileName+(nClassfileOut++)+".c"; xxx = new java.io.FileOutputStream( newName ); classOut = new CCodeWriter( xxx ); listOut.println( newName ); writePrologue( classOut ); } public void close(){ if ( classOut != null ){ classOut.close(); } if ( auxOut != null && auxOut != classOut ){ auxOut.close(); } auxOut = null; classOut = null; if ( listOut != null ){ listOut.close(); listOut = null; } if ( headerOut != null ){ /* * Added header file for globals */ writeHeaderEpilogue( headerOut ); headerOut.close(); headerOut = null; } /* * Added header file for globals */ if ( globalHeaderOut != null ){ writeGlobalHeaderEpilogue( globalHeaderOut ); globalHeaderOut.close(); globalHeaderOut = null; } outputFileName = null; return;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?