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 + -
显示快捷键?