cvmmethodinfo.java

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

JAVA
1,382
字号
	OpcodeInfo[opc_vinvokevirtual_quick]	= new CVMOpcodeInfoType(255);	OpcodeInfo[opc_invokenonvirtual_quick]	= new CVMOpcodeInfoType(255);	OpcodeInfo[opc_invokesuper_quick]	= new CVMOpcodeInfoType(255);	OpcodeInfo[opc_invokestatic_quick]	= new CVMOpcodeInfoType(255);	OpcodeInfo[opc_invokeinterface_quick]	= new CVMOpcodeInfoType(255);	OpcodeInfo[opc_invokevirtualobject_quick] = new CVMOpcodeInfoType(255);	OpcodeInfo[opc_invokeignored_quick] =	    new CVMOpcodeInfoType(opc_invokeignored_quick);	OpcodeInfo[opc_new_quick]= 	    new CVMOpcodeInfoType(opc_iadd, 0, 1,			       CVMOpcodeInfoType.CAN_ERROR			       | CVMOpcodeInfoType.CONSTANT_POOL);	OpcodeInfo[opc_anewarray_quick]	= 	    new CVMOpcodeInfoType(opc_iadd, 1, 1,			       CVMOpcodeInfoType.CAN_ERROR			       | CVMOpcodeInfoType.CONSTANT_POOL);	OpcodeInfo[opc_multianewarray_quick]	= new CVMOpcodeInfoType(255);	OpcodeInfo[opc_checkcast_quick]	= 	    new CVMOpcodeInfoType(opc_iadd, 1, 1,			       CVMOpcodeInfoType.CAN_ERROR			       | CVMOpcodeInfoType.CONSTANT_POOL);	OpcodeInfo[opc_instanceof_quick] = 	    new CVMOpcodeInfoType(opc_iadd, 1, 1, CVMOpcodeInfoType.CONSTANT_POOL);	OpcodeInfo[opc_invokevirtual_quick_w] = 	    new CVMOpcodeInfoType(255);	OpcodeInfo[opc_getfield_quick_w] =	    new CVMOpcodeInfoType(opc_getfield_quick_w);	OpcodeInfo[opc_putfield_quick_w] =	    new CVMOpcodeInfoType(opc_getfield_quick_w);	OpcodeInfo[opc_nonnull_quick] =	    new CVMOpcodeInfoType(opc_nonnull_quick);	OpcodeInfo[opc_agetfield_quick] =	    new CVMOpcodeInfoType(opc_iadd, 1, 1, CVMOpcodeInfoType.NULL_CHECK);	OpcodeInfo[opc_aputfield_quick] =	    new CVMOpcodeInfoType(opc_iadd, 2, 0, CVMOpcodeInfoType.NULL_CHECK);	OpcodeInfo[opc_invokestatic_checkinit_quick]	=  	    new CVMOpcodeInfoType(255);	OpcodeInfo[opc_getstatic_checkinit_quick]	=  	    new CVMOpcodeInfoType(255);	OpcodeInfo[opc_putstatic_checkinit_quick]	= 	    new CVMOpcodeInfoType(255);	OpcodeInfo[opc_agetstatic_checkinit_quick]	= 	    new CVMOpcodeInfoType(255);	OpcodeInfo[opc_aputstatic_checkinit_quick]	= 	    new CVMOpcodeInfoType(255);	OpcodeInfo[opc_getstatic2_checkinit_quick]	= 	    new CVMOpcodeInfoType(255);	OpcodeInfo[opc_putstatic2_checkinit_quick]	=	    new CVMOpcodeInfoType(255);	OpcodeInfo[opc_new_checkinit_quick]	= new CVMOpcodeInfoType(255);	OpcodeInfo[opc_exittransition]		= new CVMOpcodeInfoType(255);    };    static CVMOpcodeInfoType[] OpcodeInfoSpecial = {	/* getfield_quick    */ new CVMOpcodeInfoType(opc_iadd, 1, 1,				    CVMOpcodeInfoType.NULL_CHECK				    | CVMOpcodeInfoType.CONSTANT_POOL),	/* putfield_quick    */ new CVMOpcodeInfoType(opc_iadd, 2, 0,				    CVMOpcodeInfoType.NULL_CHECK				    | CVMOpcodeInfoType.CONSTANT_POOL),	/* getfield2_quick   */ new CVMOpcodeInfoType(opc_iadd, 1, 2,				    CVMOpcodeInfoType.NULL_CHECK				    | CVMOpcodeInfoType.CONSTANT_POOL),	/* putfield2_quick   */ new CVMOpcodeInfoType(opc_iadd, 3, 0,				    CVMOpcodeInfoType.NULL_CHECK				    | CVMOpcodeInfoType.CONSTANT_POOL)    };    /**     * Print the code as Java assembly language instructions     */      String disassembleInlining() {	byte codeBytes[] = new byte[3];	// Copy inlining into codeBytes[] buffer	codeBytes[0] = (byte)(inlining & 0xff);	codeBytes[1] = (byte)((inlining >> 8) & 0xff);	codeBytes[2] = (byte)((inlining >> 16) & 0xff);	return MethodInfo.disassemble(codeBytes, 0, 3);    }     private String myName;    public String toString() {	if (myName == null) {	    myName = method.parent.className + "." + method.name.string + 		method.type.string;	} 	return myName;    }    static int total = 0;    // After inlining some code, we try to see if we can remove code.  For    // example, the frequent case of opc_aload_0 invokeingored_quick #1 T can    // simply "go away"    final boolean compress () {	MethodInfo mb = method;        boolean rewritten = false;        byte[] code = mb.code;	int[] stack = new int[mb.stack + 1];	int stackHeight = 0;	int nextpc;	java.util.BitSet targets = mb.getLabelTargets();	for (int pc = 0; pc < code.length; pc = nextpc) {	    nextpc = pc + mb.opcodeLength(pc);	    int opcode = code[pc] & 0xff;	    int popping = 0;	    boolean checkThis = false;	    if (targets.get(pc)) { 	        stackHeight = 0;	    }	    stack[stackHeight] = pc;	    // Invariant.  the stackheight at this point is stackHeight or less.	    // 	    // We can pop n items from the stack (where n <= stackHeight) by	    // simply deleting all the code from stackHeight[n] to this point	    // in the code.  No side effects are removed.	    // 	    // Note that instructions that have a side effect should set	    // stackHeight = 0, to indicate that it can't be deleted.	    switch (opcode) {	    case opc_nop:	    case opc_ineg: case opc_fneg:	    case opc_i2f: case opc_f2i:	    case opc_i2b: case opc_i2c: case opc_i2s:	    case opc_newarray:	    case opc_anewarray_quick:	    case opc_instanceof_quick:	    case opc_lneg: case opc_dneg:	    case opc_l2d: case opc_d2l:	        // these don't change stack height, and we know as much about	        // the stack before as we do after.	        break;	    case opc_aconst_null: 	    case opc_iconst_m1: case opc_iconst_0: 	    case opc_iconst_1:  case opc_iconst_2:  	    case opc_iconst_3:  case opc_iconst_4:	    case opc_iconst_5:  	    case opc_fconst_0:  case opc_fconst_1: 	    case opc_fconst_2:	    case opc_bipush:    case opc_sipush:	    case opc_iload:     case opc_fload:    	    case opc_aload:	    case opc_iload_0:   case opc_iload_1:  	    case opc_iload_2:   case opc_iload_3:	    case opc_fload_0:   case opc_fload_1:  	    case opc_fload_2:   case opc_fload_3:	    case opc_aload_0:   case opc_aload_1:	    case opc_aload_2:   case opc_aload_3:	    case opc_ldc_quick: case opc_ldc_w_quick:	    case opc_aldc_quick: case opc_aldc_w_quick:	    case opc_aldc_ind_quick: case opc_aldc_ind_w_quick:	    case opc_getstatic_quick:	    case opc_agetstatic_quick:	    case opc_dup:		        // These push some value onto the stack, no matter what was	        // there before	        stackHeight += 1;		break;	    case opc_lconst_0: case opc_lconst_1:	    case opc_dconst_0: case opc_dconst_1:	    case opc_lload:    case opc_dload:	    case opc_lload_0:  case opc_lload_1:	    case opc_lload_2:  case opc_lload_3:	    case opc_dload_0:  case opc_dload_1:	    case opc_dload_2:  case opc_dload_3:	    case opc_ldc2_w_quick:	    case opc_getstatic2_quick:	        // These push two values onto the stack, no matter what was 	        // there before.	        stackHeight += 2;		break;	    case opc_i2l: case opc_i2d:	    case opc_f2l: case opc_f2d:	        // if we knew the top element of the stack, we know more	        stackHeight = (stackHeight < 1) ? 0 : stackHeight + 1;		break;	    case opc_iadd: case opc_fadd:	    case opc_isub: case opc_fsub:	    case opc_imul: case opc_fmul:	    case opc_fdiv: case opc_frem:	    case opc_ishl: case opc_ishr: case opc_iushr:	    case opc_iand: case opc_ior: case opc_ixor:	    case opc_l2i: case opc_l2f:	    case opc_d2i:  case opc_d2f:	    case opc_fcmpl: case opc_fcmpg:	        // if we knew the top two elements of the stack, the stack	        // has just shrunk	        stackHeight = (stackHeight < 2) ? 0 : stackHeight - 1;		break;	    case opc_lshl: case opc_lshr: case opc_lushr:	        // if we knew the top three elements of the stack, we now	        // know the top two	        stackHeight = (stackHeight < 3) ? 0 : stackHeight  - 1;		break;	    case opc_lcmp: case opc_dcmpl: case opc_dcmpg:	        // if we knew the top 4 elements of the stack, we now	        // know the top element	        stackHeight = (stackHeight < 4) ? 0 : stackHeight - 3;		break;	      	    case opc_ladd: case opc_dadd:	    case opc_lsub: case opc_dsub:	    case opc_lmul: case opc_dmul:	    case opc_ddiv: case opc_drem:	    case opc_land: case opc_lor: case opc_lxor:	        // if we knew the top 4 elements of the stack, we now	        // know the top 2	        stackHeight = (stackHeight < 4) ? 0 : stackHeight - 2;		break;	    // The dup's (other than opc_dup) deal with the stack in 	    // a way that's not worth the hassle of dealing with.	    case opc_getfield_quick:	    case opc_agetfield_quick:	    case opc_arraylength:	        // If we throw away the result, then we just need to check that	        // the value is non-null.		if (code[nextpc] == (byte)(opc_pop)) { 		    checkThis = true;		    nextpc += 1;		} else { 		    stackHeight = 0;		}		break;	    case opc_pop2:		popping++;	// fall thru	    case opc_pop:	        // We have to be careful.  The inliner may produce code that	        // does correspond to the stack.  For example, it might 	        // produce "pop pop2" to remove a double then an int.  We need	        // to deal with series of them at once.		if (stackHeight > 0) {		    popping++;		    for(;;) {			opcode = code[++pc] & 0xFF;			if (opcode == opc_pop) 			    popping++;			else if (opcode == opc_pop2)			    popping += 2;			else 			    break;		    }		    nextpc = pc;		}		break;	    case opc_invokeignored_quick: 	        popping = code[pc + 1] & 0xff;		if (code[pc + 2] != 0) { 		    checkThis = true; popping--;		} 		break;			    default:	        stackHeight = 0;	    }	    	    if (checkThis || (popping > 0 && stackHeight > 0)) {		rewritten = true;	        if (stackHeight >= popping) { 		    stackHeight -= popping;		    popping = 0;		} else { 		    popping -= stackHeight;		    stackHeight = 0;		}		int start = stack[stackHeight];		    		if (checkThis) { 		    if (popping == 0 && (nextpc - start != 3)) {		        mb.replaceCode(start, nextpc, opc_nonnull_quick);		    } else { 			mb.replaceCode(start, nextpc, 				       opc_invokeignored_quick, popping+1, 1);		    }		    stackHeight = 0;		} else { 		    switch (popping) { 		    case 0:  		        mb.replaceCode(start, nextpc); break;		    case 1:  		        mb.replaceCode(start, nextpc, opc_pop); break; 		    case 2:  		        mb.replaceCode(start, nextpc, opc_pop2); break; 		    default: 		        mb.replaceCode(start, nextpc, opc_invokeignored_quick, 				       popping, 0); 			break;		    }		}	    }	}	return rewritten;    }}/** * Class used for inlining info.  See inlining code in MethodInfo */class CVMOpcodeInfoType {     int opcode;				// really the opcode type    int inStack;    int outStack;    static final int CAN_ERROR = 0x01;	/* can give error in addition to                                           NULL_CHECK */    static final int NULL_CHECK = 0x02;	/* checks that first arg isn't null */    static final int CONSTANT_POOL = 0x04; /* uses the constant pool */    int flags;    CVMOpcodeInfoType(int opcode, int inStack, int outStack, int flags) {        this.opcode = opcode;        this.inStack = inStack;        this.outStack = outStack;        this.flags = flags;    }    CVMOpcodeInfoType(int opcode, int inStack, int outStack) {        this(opcode, inStack, outStack, 0);    }    CVMOpcodeInfoType(int opcode, int inStack) {        this(opcode, inStack, 0, 0);    }    CVMOpcodeInfoType(int opcode) {        this(opcode, 0, 0, 0);    }};

⌨️ 快捷键说明

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