⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 evmmethodinfo.java

📁 已经移植好的java虚拟机
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
		    result = 			makeOpcodeResult(checkThis, nextReg, opPtr.inStack,					 2, opcode, code[pc+1] & 0xff, 0);		    break;		case 3:		    result = 			makeOpcodeResult(checkThis, nextReg, opPtr.inStack,					 3, opcode,					 code[pc+1] & 0xff, code[pc+2] & 0xff);		    break;		default:		    throw new RuntimeException("sysAssert(FALSE);");		    // result = NO_INLINE_FLAG; // not reached		    // break;			// not reached		}		if ((result & NO_INLINE_FLAG) == 0) { 		    if ((opPtr.flags & OpcodeInfoType.CONSTANT_POOL) != 0) 			result |= SAME_CLASS_FLAG;		    if (redoInlining) 			result |= REDO_INLINING_FLAG;		}		return result;	    }	    default:		throw new RuntimeException("sysAssert(FALSE);");	    case 255:		/* random instruction */		return NO_INLINE_FLAG;	    } /* of switch statement */	} /* end of for loop */    }    /* This method is called to create the code that is actually going to     * replace the indicated method, when the method does nothing, or when     * it simply returns one of its arguments.     *     * It takes the following arguments:     *   mb:          Method we are examining     *   checkThis:   If true,  We must specially check that the first argument     *                "this" isn't null.      *   highReg,     One greater than the highest register on the stack when     *                the return or Xreturn is called.     *   returnSize   Size of the return (0 for return, 1 for ireturn,      *                 2 for lreturn, etc);     *     * We have to emulate the method call in 3 bytes.  At the time the     * method is called, the arguments reg[0] . . . reg[mb->args_size - 1]     * are pushed on the stack.     */    static int[] poppers = { opc_nop, opc_pop, opc_pop2 };    private int makeReturnResult(boolean checkThis, int highReg, int returnSize) {         MethodInfo mb = method;	int argsSize = mb.argsSize;	if (returnSize == 0) { 	    /* Return void */	    return MAKE_INLINING(opc_invokeignored_quick, argsSize,				 (checkThis ? 1 : 0));	} else {	    /* Return some value from the stack */	    int returnReg = highReg - returnSize;  	    int excessArgs =  argsSize - returnSize - returnReg;	    // sysAssert(returnReg >= 0 && returnSize >= 0);	    if (returnReg == 0) { 		/* Returning reg0 or reg0/reg1 */		if (checkThis) { 		    /* Must be returning reg0, which is also checked. We		     * require argsSize >= 2 (which is the same thing as		     * excessArgs >= 1), because otherwise the "dup" might		     * overflow the stack.  More sophisticated inliners		     * might see if there is space on the caller's stack.		     */		    // sysAssert(returnSize == 1);		    if (argsSize < 2) { 			return NO_INLINE_FLAG;		    } else if (excessArgs > 2) { 		        return NO_INLINE_FLAG;		    } else { 		        return MAKE_INLINING(poppers[excessArgs],					     opc_dup,					     opc_nonnull_quick);		    }		} else {		    /* We're returning reg0 or reg0/reg1 which isn't null		     * checked.  We just pop extraneous stuff off the stack		     * */		    return MAKE_INLINING(opc_invokeignored_quick,					 excessArgs, 0);		}	    } else {		/* At this point, returnReg > 0.  We're returning something		 * other than the bottom of the stack.		 */	        if (returnSize == 1 && returnReg == 1) { 		    if (excessArgs > 2) { 			return NO_INLINE_FLAG;		    }		    return MAKE_INLINING(poppers[excessArgs], 					 opc_swap, 					 checkThis ? opc_nonnull_quick					    : opc_pop);		}		return NO_INLINE_FLAG;	    }	}    }    /* This method is called to create the code that is actually going to     * replace the indicated method     *      * makeOpcodeResult is used to create a inlining that can be used anywhere     * It takes the following arguments:     *     *   mb:          Method we are examining     *   checkThis:   If true,  We must specially check that the first argument     *                "this" isn't null.  This condition is >>NOT<< tested by      *                the generated code.     *   nextReg:     In the emulation, the highest register on the stack is     *                reg[nextReg - 1].     *   icount       The number of bytes of instructions that follow.     *   opcode, op1, op2     *                The bytes of instruction.     *     * We have to emulate the method call in 3 bytes.  At the time the     * method is called, the arguments reg[0] . . . reg[mb->args_size - 1]     * are pushed on the stack.  So in three bytes, we have to:     *     Remove any excess arguments from the stack.     *     Perform the operation on the indicated stack registers     *     Remove any objects lower down on the stack (this is hard!)     *     Make sure that reg[0] is checked for being non-null, if necessary.     */      private int makeOpcodeResult(boolean checkThis, 				  int nextReg, int opcodeArgCount,				  int icount, int opcode, int op1, int op2) {        MethodInfo mb = method;	int firstReg = (opcodeArgCount == 0) ? 0 : nextReg - opcodeArgCount;	// sysAssert(firstReg >= 0 && opcodeArgCount >= 0 && icount > 0);	if (firstReg > 0) {	    /* There are extra registers at the bottom of the stack */	    return makePoppingResult(checkThis, firstReg, opcodeArgCount, 				     icount, opcode, op1, op2);	} else {	    /* No extra registers at bottom of stack */	    int argsSize = mb.argsSize;	    int excessArgs = argsSize - opcodeArgCount; /* extra at top */	    int popSpace = 3 - icount; /* space to pop args at top */	    int result = 0;	    int i;	    if (checkThis) { 		/* Unless this is a constant method that ignores all of its		 * arguments, we don't really have any way of checking		 * register 0 if the instructions doesn't.  If it is a		 * constant instruction, deduct one from both popSpace and		 * from excessArgs, since we are popping that last argument		 * when an opc_nonnull_quick;		 */		if (opcodeArgCount > 0 || popSpace == 0)		    return NO_INLINE_FLAG;		popSpace--; excessArgs--; 		// sysAssert(excessArgs >= 0);	    }	    if (excessArgs > 2 * popSpace) 		return NO_INLINE_FLAG;	    for (i = 0; i < popSpace; i++) { 		/* If excessArgs <= popSpace, the following generates excessArgs		 * "pops" followed by nops.  Otherwise, it generates 		 * excessArgs - popSpace pop2's followed by pop's.		 */		int opcodeTmp = (excessArgs <= i) ? opc_nop 		    : (excessArgs <= popSpace + i) ? opc_pop 			: opc_pop2;		result |= (opcodeTmp << (i << 3));	    }	    if (checkThis) 		result |= opc_nonnull_quick << ((i++) << 3);	    // sysAssert(i + icount == 3);	    switch (icount) { 	       case 3: result |= op2 << ((i + 2) << 3);	       case 2: result |= op1 << ((i + 1) << 3);	       case 1: result |= opcode << ((i + 0) << 3);	    }	    return result;	}    }    /*      * Called by makeOpcodeResult.       * Same arguments.  But there are extra arguments on the bottom to pop.     */    private int makePoppingResult(boolean checkThis, 				  int firstReg, int opcodeArgCount,				  int icount, int opcode, int op1, int op2) {        MethodInfo mb = method;	int argsSize = mb.argsSize;	int excessArgs = argsSize - opcodeArgCount - firstReg; /* extra on top*/	if (icount > 1)	    /* We're just not prepared to deal with this. */	    return NO_INLINE_FLAG;	if (OpcodeInfo[opcode].outStack == 0) {	    int result = 0;	    /* Something like an array store, that leaves no value on the               stack */	    int i = 0;	    /* We can't deal with checkThis, since it might reverse the order of	     * an exception.  We have a total of two instructions to do all the 	     * pre and post popping.	     */	    if (checkThis || ((excessArgs + 1)/2 + (firstReg + 1)/2) > 2)		return NO_INLINE_FLAG;	    for (; excessArgs > 0; excessArgs -=2) /* pre popping */		result |= (excessArgs == 1 ? opc_pop : opc_pop2)		    << ((i++) << 3);	    result |= opcode << ((i++) << 3);	    for (; firstReg > 0; firstReg -=2) /* post popping */		result |= (firstReg == 1 ? opc_pop : opc_pop2)		    << ((i++) << 3);	    while (i < 3)		result |= opc_nop << ((i++) << 3);	    return result;	}	if (excessArgs > 0 || firstReg > 1)	    /* We can't both do useful work and remove more than this many 	     * items from the stack. */	    return NO_INLINE_FLAG;	if (opcodeArgCount == 1) { 	    return MAKE_INLINING(opc_swap, 				 checkThis ? opc_nonnull_quick				    : opc_pop, 				 opcode);	}	if (   ((OpcodeInfo[opcode].flags &		 (OpcodeInfoType.NULL_CHECK | OpcodeInfoType.CAN_ERROR)) == 0)	    && (OpcodeInfo[opcode].outStack == 1)) {	    /* The result creates one thing on the stack, and it can't error */	    return MAKE_INLINING(opcode,				 opc_swap,				 checkThis ? opc_nonnull_quick				    : opc_pop);	}	return NO_INLINE_FLAG;    }    private static boolean isXreturn(int opcode) {	return (opcode >= opc_ireturn) && (opcode <= opc_areturn);    }    private static byte INLINING_WORD1(int simp) {	return (byte) (simp & 0xFF);    }    private static byte INLINING_WORD2(int simp) {	return (byte) ((simp >> 8) & 0xFF);    }    private static byte INLINING_WORD3(int simp) {	return (byte) ((simp >> 16) & 0xFF);    }    private static int MAKE_INLINING(int op1, int op2, int op3) {	return (op1 << 0) + (op2 << 8) + (op3 << 16);    }    private static int REGSIZE(OpcodeInfoType ptr) {	return (ptr.inStack);    }    private static int REGNUM(OpcodeInfoType ptr) {	return (ptr.outStack);    }    static OpcodeInfoType[] OpcodeInfo = {	/*  { opc_pop  <number of words to pop from stack> } 	 *  { opc_iadd <words popped from stack> <words pushed to stack> }	 *  { opc_iload <words pushed to stack> } 	 *  { opc_iload_0 <words pushed to stack> <implicit register> } 	 *  { opc_return  <words returned> } 	 *    255 indicates opcode that we can't inline	 *  other values are special opcodes that must be handled specially	 */	/* nop               */ new OpcodeInfoType(opc_pop, 0),	/* aconst_null       */ new OpcodeInfoType(opc_iadd, 0, 1),	/* iconst_m1         */ new OpcodeInfoType(opc_iadd, 0, 1),	/* iconst_0          */ new OpcodeInfoType(opc_iadd, 0, 1),	/* iconst_1          */ new OpcodeInfoType(opc_iadd, 0, 1),	/* iconst_2          */ new OpcodeInfoType(opc_iadd, 0, 1),	/* iconst_3          */ new OpcodeInfoType(opc_iadd, 0, 1),	/* iconst_4          */ new OpcodeInfoType(opc_iadd, 0, 1),	/* iconst_5          */ new OpcodeInfoType(opc_iadd, 0, 1),	/* lconst_0          */ new OpcodeInfoType(opc_iadd, 0, 2),	/* lconst_1          */ new OpcodeInfoType(opc_iadd, 0, 2),	/* fconst_0          */ new OpcodeInfoType(opc_iadd, 0, 1),	/* fconst_1          */ new OpcodeInfoType(opc_iadd, 0, 1),	/* fconst_2          */ new OpcodeInfoType(opc_iadd, 0, 1),	/* dconst_0          */ new OpcodeInfoType(opc_iadd, 0, 2),	/* dconst_1          */ new OpcodeInfoType(opc_iadd, 0, 2),	/* bipush            */ new OpcodeInfoType(opc_iadd, 0, 1),	/* sipush            */ new OpcodeInfoType(opc_iadd, 0, 1),	/* ldc               */ new OpcodeInfoType(255),	/* ldc_w             */ new OpcodeInfoType(255),	/* ldc2_w            */ new OpcodeInfoType(255),	/* iload             */ new OpcodeInfoType(opc_iload, 1),	/* lload             */ new OpcodeInfoType(opc_iload, 2),	/* fload             */ new OpcodeInfoType(opc_iload, 1),	/* dload             */ new OpcodeInfoType(opc_iload, 2),	/* aload             */ new OpcodeInfoType(opc_iload, 1),	/* iload_0           */ new OpcodeInfoType(opc_iload_0, 1, 0),	/* iload_1           */ new OpcodeInfoType(opc_iload_0, 1, 1),	/* iload_2           */ new OpcodeInfoType(opc_iload_0, 1, 2),	/* iload_3           */ new OpcodeInfoType(opc_iload_0, 1, 3),	/* lload_0           */ new OpcodeInfoType(opc_iload_0, 2, 0),	/* lload_1           */ new OpcodeInfoType(opc_iload_0, 2, 1),	/* lload_2           */ new OpcodeInfoType(opc_iload_0, 2, 2),	/* lload_3           */ new OpcodeInfoType(opc_iload_0, 2, 3),	/* fload_0           */ new OpcodeInfoType(opc_iload_0, 1, 0),	/* fload_1           */ new OpcodeInfoType(opc_iload_0, 1, 1),	/* fload_2           */ new OpcodeInfoType(opc_iload_0, 1, 2),	/* fload_3           */ new OpcodeInfoType(opc_iload_0, 1, 3),	/* dload_0           */ new OpcodeInfoType(opc_iload_0, 2, 0),	/* dload_1           */ new OpcodeInfoType(opc_iload_0, 2, 1),	/* dload_2           */ new OpcodeInfoType(opc_iload_0, 2, 2),	/* dload_3           */ new OpcodeInfoType(opc_iload_0, 2, 3),	/* aload_0           */ new OpcodeInfoType(opc_iload_0, 1, 0),	/* aload_1           */ new OpcodeInfoType(opc_iload_0, 1, 1),	/* aload_2           */ new OpcodeInfoType(opc_iload_0, 1, 2),	/* aload_3           */ new OpcodeInfoType(opc_iload_0, 1, 3),	/* iaload            */ new OpcodeInfoType(opc_iadd, 2, 1,						   OpcodeInfoType.NULL_CHECK),	/* laload            */ new OpcodeInfoType(opc_iadd, 2, 2,						   OpcodeInfoType.NULL_CHECK),	/* faload            */ new OpcodeInfoType(opc_iadd, 2, 1,						   OpcodeInfoType.NULL_CHECK),	/* daload            */ new OpcodeInfoType(opc_iadd, 2, 2,						   OpcodeInfoType.NULL_CHECK),	/* aaload            */ new OpcodeInfoType(opc_iadd, 2, 1,						   OpcodeInfoType.NULL_CHECK),	/* baload            */ new OpcodeInfoType(opc_iadd, 2, 1,						   OpcodeInfoType.NULL_CHECK),	/* caload            */ new OpcodeInfoType(opc_iadd, 2, 1,						   OpcodeInfoType.NULL_CHECK),	/* saload            */ new OpcodeInfoType(opc_iadd, 2, 1,						   OpcodeInfoType.NULL_CHECK),	/* istore            */ new OpcodeInfoType(255),	/* lstore            */ new OpcodeInfoType(255),	/* fstore            */ new OpcodeInfoType(255),	/* dstore            */ new OpcodeInfoType(255),	/* astore            */ new OpcodeInfoType(255),	/* istore_0          */ new OpcodeInfoType(255),	/* istore_1          */ new OpcodeInfoType(255),	/* istore_2          */ new OpcodeInfoType(255),	/* istore_3          */ new OpcodeInfoType(255),	/* lstore_0          */ new OpcodeInfoType(255),	/* lstore_1          */ new OpcodeInfoType(255),	/* lstore_2          */ new OpcodeInfoType(255),	/* lstore_3          */ new OpcodeInfoType(255),	/* fstore_0          */ new OpcodeInfoType(255),	/* fstore_1          */ new OpcodeInfoType(255),	/* fstore_2          */ new OpcodeInfoType(255),	/* fstore_3          */ new OpcodeInfoType(255),	/* dstore_0          */ new OpcodeInfoType(255),	/* dstore_1          */ new OpcodeInfoType(255),	/* dstore_2          */ new OpcodeInfoType(255),	/* dstore_3          */ new OpcodeInfoType(255),	/* astore_0          */ new OpcodeInfoType(255),	/* astore_1          */ new OpcodeInfoType(255),	/* astore_2          */ new OpcodeInfoType(255),	/* astore_3          */ new OpcodeInfoType(255),	/* iastore           */ new OpcodeInfoType(opc_iadd, 3, 0,						   OpcodeInfoType.NULL_CHECK),	/* lastore           */ new OpcodeInfoType(opc_iadd, 4, 0,						   OpcodeInfoType.NULL_CHECK),	/* fastore           */ new OpcodeInfoType(opc_iadd, 3, 0,						   OpcodeInfoType.NULL_CHECK),	/* dastore           */ new OpcodeInfoType(opc_iadd, 4, 0,						   OpcodeInfoType.NULL_CHECK),	/* aastore           */ new OpcodeInfoType(opc_iadd, 3, 0,						   OpcodeInfoType.NULL_CHECK),	/* bastore           */ new OpcodeInfoType(opc_iadd, 3, 0,						   OpcodeInfoType.NULL_CHECK),	/* castore           */ new OpcodeInfoType(opc_iadd, 3, 0,						   OpcodeInfoType.NULL_CHECK),	/* sastore           */ new OpcodeInfoType(opc_iadd, 3, 0,						   OpcodeInfoType.NULL_CHECK),	/* pop               */ new OpcodeInfoType(opc_pop, 1),	/* pop2              */ new OpcodeInfoType(opc_pop, 2),	/* dup               */ new OpcodeInfoType(255),	/* dup_x1            */ new OpcodeInfoType(255),	/* dup_x2            */ new OpcodeInfoType(255),	/* dup2              */ new OpcodeInfoType(255),	/* dup2_x1           */ new OpcodeInfoType(255),

⌨️ 快捷键说明

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