javacodecompact.java

来自「This is a resource based on j2me embedde」· Java 代码 · 共 1,056 行 · 第 1/3 页

JAVA
1,056
字号
	    return true;	} else {	    return false;	}    }    /**     * Do closure on CP entry class constant references until no unresolved     * constants remain.     * NOTE: doClosure() only loads ClassInfos for each class that is     * referenced from unresolved CP entries.  After doClosure() is done     * (assuming full transitive closure is desired), then all the CP     * entries for class constants will reference a ClassInfo object.     * NOTE: resolving CP entry class constants to ClassInfo does not     * include quickening of bytecodes and other types of VM specific     * processing associated with resolution yet.  That part is done     * later.     */    private boolean doClosure() {	// do closure on references until none remain.	while (true) {            Assert.disallowClassloading();            Set undefinedClassNames =                findUnresolvedClassNames(classesProcessed.elements());	    String unresolved[] = unresolvedClassNames(undefinedClassNames);            Assert.allowClassloading();            if (unresolved == null)		break; // none left!	    int nfound = 0;	    Vector processedThisTime = new Vector();	    for( int i=0; i < unresolved.length; i++){		try {		    Vector oneClass = new Vector();		    loadClass(ClassTable.getClassLoader(), unresolved[i],			oneClass);		    processedThisTime.addAll(oneClass);		} catch (Exception e) {		    return false;		}	    }	    // If we have gone through an iteration when we weren't able to	    // resolve any more classes, then we have resolved everything	    // we can.  Hence, break out of here.	    if (processedThisTime.isEmpty()) {		break;	    }	    // Otherwise, continue to resolve the new classes that we've found.	    classesProcessed.addAll(processedThisTime);	}	return true;    }    /**     * Performs the work for JCC.  This is the root processing method in JCC     * which in turn will call all other processing methods.     * NOTE: process() is responsible for resolving all the constant pool     * entries of the loaded classes if possible.  If full transitive closure     * is required, then this is the place where the work will be done.     *      * @return false if an error was discovered.     */    private boolean process(boolean doWrite) throws Exception { 	/* Do closure on references until none remain.         * NOTE: doClosure() only loads ClassInfos for each class that is         * referenced from unresolved CP entries.  After doClosure() is done         * (assuming full transitive closure is desired), then all the CP         * entries for class constants will reference a ClassInfo object.         * NOTE: resolving CP entry class constants to ClassInfo does not         * include quickening of bytecodes and other types of VM specific         * processing associated with resolution yet.  That part is done         * later.         */        if (!doClosure()) {	    return false;	}	ClassInfo c[] = ClassTable.allClasses();	nclasses = c.length;	if (verbosity != 0) System.out.println(Localizer.getString(		"javacodecompact.resolving_superclass_hierarchy") );	if (! ClassInfo.resolveSupers()){	    return false; // missing superclass is a fatal error.	}	for (int i = 0; i < nclasses; i++){            ClassInfo cinfo = c[i];	    if (!(cinfo instanceof PrimitiveClassInfo) &&		!(cinfo instanceof ArrayClassInfo))	    {		if (verbosity != 0) System.out.println(Localizer.getString(			"javacodecompact.building_tables_for_class",			cinfo.className));		cinfo.buildFieldtable();		cinfo.buildMethodtable();	    }	}        // Warn if fields or methods marked for exclusion were not found        checkExcludedClassEntries();	if (!doWrite) {	    return true;	}	// now write the output	if (verbosity != 0) System.out.println(Localizer.getString(		"javacodecompact.writing_output_file"));	writeNativeHeaders( nativeTypes, c, nclasses );	writeNativeHeaders( extraHeaders, c, nclasses );	if (stubDestName != null){	    writeCStubs( c, nclasses );	}	boolean good = true;	if (firstTimeOnly) {	    // For CVM, make sure that all arrays of basic types	    // are instantiated!	    good = instantiateBasicArrayClasses(verbosity > 1);	    firstTimeOnly = false;	}        // prepareClasses() is responsible for quickening bytecodes,        // optimizing the bytecode, constantpools, etc.  This is where        // CP resolution as the VM knows it is done.        if (!prepareClasses(c) || !good) {	    return false;	}	if (doWrite) {	    makeOutfileName();	}	good = writeROMFile( outName, c, romAttributes, doWrite );        /* Don't destroy class vector. The JavaAPILister         * needs to access class typeids, which come         * from CVMClass and CVMClass come from the class         * vector.         */	//ClassClass.destroyClassVector();	return good;    }    public static void main( String clist[] ){	boolean success = false;	try {	    try {                JavaCodeCompact jcc = new JavaCodeCompact();		// Parse the command line arguments and check for malformed                // arguments or a file read error?                // Note that processOptions also loads all the initial                // classes to be romized specified at the JCC command line.                // These classes will be loaded, but their constant pool                // entries wil not be resolved yet.		if (jcc.processOptions(clist)) {                    // If we got here, then the arguments were parsed                    // successfully.  Now, we are ready to do some                    // additional work.  This includes resolving the                    // constant pool entries, quickening bytecodes, etc.		    success = jcc.process(true);		}                /* We are done with processing ROMized classes. Now run                  * JavaAPILister, which need to access some of the data                 * such as class and member typeid that we created during                 * Romizing classes.                 */                if (APIListerArgs != null) {                    new JavaAPILister().process(APIListerArgs);                }	    }finally{		System.out.flush();		System.err.flush();	    }	}catch (Throwable t){	    t.printStackTrace();	}	if (!success){	    // process threw error or failed	    System.exit(1);	}	return;    }    /*     * ALL THIS IS FOR ROMIZATION     */    public boolean instantiateBasicArrayClasses(boolean verbose)    {	boolean good = true;	// For CVM, make sure that all arrays of basic types	// are instantiated!	String basicArray[] = { "[C", "[S", "[Z", "[I", "[J", "[F", "[D", "[B", 		"[Ljava/lang/Object;" // not strictly basic.	};	for ( int ino = 0; ino < basicArray.length; ino++ ){	    if (!ArrayClassInfo.collectArrayClass(basicArray[ino], verbose)) {		good = false;	    }	}	return good;    }    /*     * Iterate through all known classes.     * Iterate through all constant pools.     * Look at ClassConstants. If they are unbound,     * and if they are references to array classes,     * then instantiate the classes and rebind.     */    public boolean instantiateArrayClasses(	ClassInfo classTable[],	boolean verbose)    {	int nclasses = classTable.length;	boolean good = true;	// Now dredge through all class constant pools.	for ( int cno = 0; cno < nclasses; cno++ ){	    ClassInfo c = classTable[cno];	    ConstantObject ctable[] = c.getConstantPool().getConstants();	    if ( ctable == null ) continue;	    int n = ctable.length;	    for( int i = 1; i < n; i++ ){		if ( ctable[i] instanceof ClassConstant ){		    ClassConstant cc = (ClassConstant)ctable[i];		    String        cname = cc.name.string;		    if (cname.charAt(0) != Const.SIGC_ARRAY ){			continue; // not interesting		    }		    if (cc.isResolved()){			continue; // not interesting		    }		    if (!vm.ArrayClassInfo.collectArrayClass(cname, verbose)) {			good = false;		    }		    cc.forget(); // forget the fact that we couldn't find it		}	    }                    // We might just want to check the code as well.            for (int j = 0; j < c.methods.length; j++) {                MethodInfo m = c.methods[j];                m.collectArrayForAnewarray(ctable, c.className);	    }	}	return good;    }    /*     * We attempt to factor out VM specific code     * by subclassing ClassClass. Perhaps we should be subclassing     * components.ClassInfo itself.     * Anyway, this is the CVM-specific class factory. This     * would better be dependent on a runtime switch.     */    VMClassFactory classMaker = new CVMClassFactory();    public ClassClass[]    finalizeClasses() throws Exception{	ClassClass classes[] = ClassClass.getClassVector(classMaker);        int numberOfClasses = classes.length;	CodeHacker ch = new CodeHacker( qlossless, jitOn, verbosity >= 2 );	for (int i = 0; i < numberOfClasses; i++) {	    if (verbosity != 0) {                System.out.println(Localizer.getString(		    "javacodecompact.quickening_code_of_class",                    classes[i].classInfo.className));            }            if (!ch.quickenAllMethodsInClass(classes[i].classInfo)) {                throw new Exception(Localizer.getString(		    "javacodecompact.quickening_code_of_class",                    classes[i].classInfo.className));	    }	}	// constant pool smashing has to be done after quickening,	// else it doesn't make much difference!	for (int i = 0; i < numberOfClasses; i++) {	    ClassInfo cinfo = classes[i].classInfo;	    if (verbosity != 0) {                System.out.println(Localizer.getString(                    "javacodecompact.reducing_constant_pool_of_class",                    cinfo.className));            }	    cinfo.countReferences(false);	    cinfo.smashConstantPool();	    cinfo.relocateReferences();	}	/*	 * This last-minute preparation step might be generalized	 * to something more useful.	 */	if (!noCodeCompaction && !qlossless) {            for (int i = 0; i < numberOfClasses; i++) {                classes[i].getInlining();            }	}	return classes;    }    private void    validateClasses(ClassClass classes[], ConstantPool sharedConstant){	int totalclasses = classes.length;	for (int i = 0; i < totalclasses; i++){	    ClassInfo ci = classes[i].classInfo;	    ci.validate(sharedConstant);	}    }    ConstantPool sharedConstant = null;    private boolean    prepareClasses(ClassInfo classTable[]) throws Exception    {	UnresolvedReferenceList missingObjects = new UnresolvedReferenceList();	boolean anyMissingConstants = false;	boolean good = instantiateArrayClasses( classTable, verbosity>1 );	// is better to have this after instantiating Array classes, I think.	ClassClass classes[] = finalizeClasses();	int	   totalclasses = classes.length;	// at this point, the classes array INCLUDES all the array	// classes. classTable doesn't include these!	// Since array classes CANNOT participate in sharing	// (because of magic offsets) they are excluded from the	// sharing calculation below. And because they don't have	// any code...	if (useSharedCP) {	    // create a shared constant pool	    sharedConstant = new ConstantPool();	    for (int i = 0; i < classTable.length; i++) 		mergeConstantsIntoSharedPool(classTable[i], sharedConstant);	   	    // sort the reference count	    sharedConstant.doSort();	    // run via the shared constant pool once.	    if (ClassClass.isPartiallyResolved(sharedConstant)) {		sharedConstant = classMaker.makeResolvable(		    sharedConstant, missingObjects, "shared constant pool");

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?