stackmaps.c

来自「This is a resource based on j2me embedde」· C语言 代码 · 共 1,928 行 · 第 1/5 页

C
1,928
字号
    state[v] = '\0';    CVMtraceStackmaps(("Variables %s\n", state));    for (v = 0; v < topOfStack; v++) {	state[v] = CVMstackmapCtsToChar(stackState[v]);    }     state[v] = '\0';    CVMtraceStackmaps(("Stack %s\n", state));    CVMtraceStackmaps(("Top of stack %d\n", topOfStack));}/* * Print the entry state of a basic block in human-readable form */static voidCVMstackmapPrintBBState(CVMStackmapContext* con, CVMBasicBlock* bb){    CVMstackmapPrintState(con, bb->topOfStack, bb->varState, bb->stackState);}#endif/* * Is the field reference of the non-quick field access bytecode at 'pc' * a reference or a value.from quicken.c.... */static voidCVMstackmapFieldKind(CVMStackmapContext* con, CVMUint8* pc,		     CVMBool* isRef, CVMBool* isDoubleword){    CVMUint32      cpIdx = CVMgetUint16(pc+1);    CVMFieldTypeID fbTid;#ifdef CVM_DEBUG_ASSERTS    {        CVMOpcode instr = (CVMOpcode)*pc;#ifdef CVM_JVMTI        if (instr == opc_breakpoint) {	    /* Must get the original byte-code: */	    instr = CVMjvmtiGetBreakpointOpcode(con->ee, pc, CVM_FALSE);	}#endif        CVMassert(instr == opc_getfield || instr == opc_getstatic ||                  instr == opc_putfield || instr == opc_putstatic ||                  instr == opc_putfield_quick_w ||                  instr == opc_getfield_quick_w);    }#endif    /*     * Get the typeID of the field at cpIdx.     */#ifdef CVM_CLASSLOADING    if (CVMcpIsResolved(con->cp, cpIdx)) {    resolved:#endif	fbTid = CVMfbNameAndTypeID(CVMcpGetFb(con->cp, cpIdx));#ifdef CVM_CLASSLOADING    } else {	CVMcpLock(con->ee);	if (CVMcpIsResolved(con->cp, cpIdx)) {	    CVMcpUnlock(con->ee);	goto resolved;	} else {	    CVMUint16 typeIDIdx = CVMcpGetMemberRefTypeIDIdx(con->cp, cpIdx);	    fbTid = CVMcpGetFieldTypeID(con->cp, typeIDIdx);	    CVMcpUnlock(con->ee);#endif /* CVM_CLASSLOADING */	}    }    *isRef = CVMtypeidFieldIsRef(fbTid);    *isDoubleword = CVMtypeidFieldIsDoubleword(fbTid);}/* * Handle method invocation given a methodblock */static CVMInt32CVMstackmapHandleMethod(CVMStackmapContext* con,			CVMCellTypeState* stack, 			CVMInt32 topOfStack,			CVMBool isStatic,			CVMMethodBlock* mb){    topOfStack -= CVMmbArgsSize(mb);    if (isStatic != CVMmbIs(mb, STATIC)) {	/*	 * There has been an illegal method call that has confused 	 * the stackmap generator. See bug #4381392. The method's	 * argsize is off by one because the invoker and invokee do	 * no agree on whether or not the method is static, and thus	 * whether or not there is a "this" argument. If the invoker	 * thinks the method should be static, then we need to "undo"	 * the popping of the "this" argument. If the invoker thinks	 * the method is not static, then we need to pop the "this"	 * argument because it was not accounted for in CVMmbArgsSize(mb).	 */	topOfStack += (isStatic ? 1 : -1);    }    switch(CVMtypeidGetReturnType(CVMmbNameAndTypeID(mb))) {	case CVM_TYPEID_VOID:	    break;	case CVM_TYPEID_OBJ:	    stack[topOfStack++] = CVMctsRef;	    break;	case CVM_TYPEID_LONG:	case CVM_TYPEID_DOUBLE:	    stack[topOfStack++] = CVMctsVal;	    stack[topOfStack++] = CVMctsVal;	    break;	default:	    stack[topOfStack++] = CVMctsVal;    }	    return topOfStack;}/* * Handle method invocation given a pc pointing to an invocation */static CVMInt32CVMstackmapHandleMethodRefFromCode(CVMStackmapContext* con,				   CVMCellTypeState* stack, 				   CVMInt32 topOfStack,				   CVMUint8* pc,				   CVMBool isStatic){    CVMUint32 cpIdx;#ifdef CVM_JVMTI    CVMassert(CVMbcAttr(*pc, INVOCATION) ||        (((CVMOpcode)*pc == opc_breakpoint) &&         CVMbcAttr(CVMjvmtiGetBreakpointOpcode(con->ee, pc, CVM_FALSE),                   INVOCATION)));#else    CVMassert(CVMbcAttr(*pc, INVOCATION));#endif    cpIdx = CVMgetUint16(pc+1);    /*     * The entry may not be resolved already, in which case we have     * to deal with an CVMMethodTypeID instead of an CVMMethodBlock.     */#ifdef CVM_CLASSLOADING    if (CVMcpIsResolved(con->cp, cpIdx)) {    resolved:#endif	return CVMstackmapHandleMethod(con, stack, topOfStack, isStatic,				       CVMcpGetMb(con->cp, cpIdx));#ifdef CVM_CLASSLOADING    } else {	CVMcpLock(con->ee);	if (CVMcpIsResolved(con->cp, cpIdx)) {	    CVMcpUnlock(con->ee);	    goto resolved;	} else {	    CVMUint16 typeIDIdx = CVMcpGetMemberRefTypeIDIdx(con->cp, cpIdx);	    CVMMethodTypeID methodTypeID = 		CVMcpGetMethodTypeID(con->cp, typeIDIdx);	    CVMcpUnlock(con->ee);	    	    /* adjust the stack by the number of arguments.*/	    topOfStack -= (isStatic ? 0 : 1); /* handle "this" argument */	    topOfStack -= CVMtypeidGetArgsSize(methodTypeID);	    	    /* set the return type */	    switch(CVMtypeidGetReturnType(methodTypeID)) {	    case CVM_TYPEID_VOID:		break;	    case CVM_TYPEID_OBJ:		stack[topOfStack++] = CVMctsRef;		break;	    case CVM_TYPEID_LONG:	    case CVM_TYPEID_DOUBLE:		stack[topOfStack++] = CVMctsVal;		stack[topOfStack++] = CVMctsVal;		break;	    default:		stack[topOfStack++] = CVMctsVal;	    }	    return topOfStack;	}    }#endif  /* CVM_CLASSLOADING */}static CVMInt32CVMstackmapLocalStore(CVMStackmapContext* con,		      CVMUint32 varNo, CVMInt32 topOfStack,		      CVMCellTypeState* stack, CVMCellTypeState* vars){    CVMassert(topOfStack >= 1);    CVMassert(stack[topOfStack - 1] == CVMctsVal);    vars[varNo] = stack[topOfStack - 1];    topOfStack--;    return topOfStack;}static CVMInt32CVMstackmapLocalAStore(CVMStackmapContext* con,		       CVMUint32 varNo, CVMInt32 topOfStack,		       CVMCellTypeState* stack, CVMCellTypeState* vars){    CVMassert(topOfStack >= 1);    CVMassert((stack[topOfStack - 1] == CVMctsRef) ||	      (CVMctsGetFlags(stack[topOfStack - 1]) == CVMctsPC));    vars[varNo] = stack[topOfStack - 1];    topOfStack--;    return topOfStack;}static CVMInt32CVMstackmapLocalDStore(CVMStackmapContext* con,		       CVMUint32 varNo, CVMInt32 topOfStack,		       CVMCellTypeState* stack, CVMCellTypeState* vars){    CVMassert(topOfStack >= 2);    CVMassert(stack[topOfStack - 1] == CVMctsVal);    CVMassert(stack[topOfStack - 2] == CVMctsVal);    vars[(varNo)]     = stack[topOfStack - 2];    vars[(varNo) + 1] = stack[topOfStack - 1];    topOfStack -= 2;    return topOfStack;}static CVMInt32CVMstackmapLocalLoad(CVMStackmapContext* con,		     CVMUint32 varNo, CVMInt32 topOfStack,		     CVMCellTypeState* stack, CVMCellTypeState* vars){    CVMassert(topOfStack < con->maxStack);    /*     * We don't care if we encounter a conflict here. We are only     * worried about using a conflict as a ref, which is handled in     * CVMstackmapLocalALoad().     */    stack[topOfStack++] = CVMctsVal;    return topOfStack;}static CVMInt32CVMstackmapLocalALoad(CVMStackmapContext* con, CVMUint8* pc,		      CVMUint32 varNo, CVMInt32 topOfStack,		      CVMCellTypeState* stack, CVMCellTypeState* vars){    CVMCellTypeState theVar = vars[varNo];    CVMassert(topOfStack < con->maxStack);    if (theVar != CVMctsRef) {	/*	 * Conflicts had better not occur unless we have pre-determined	 * that they are possible.	 */	CVMassert(con->mayNeedRewriting);	if (CVMctsIsUninit(theVar)) {	    CVMtraceStackmaps(("ALOAD(%d) at relPC=%d: "			       "Ref-uninit conflict (%C.%M)\n",			       varNo, pc - con->code, con->cb, con->mb));	    /* 	     * Record the use of this conflict, along with its type. We'll	     * check this use during map generation.	     */	    if (con->refVarsToInitialize[varNo] == 0) {		/*		 * We have not made a record of this variable yet		 */		con->refVarsToInitialize[varNo] = theVar;		con->numRefVarsToInitialize++;	    }	} else if (CVMctsIsPC(theVar)) {	    CVMtraceStackmaps(("ALOAD(%d) at relPC=%d: "			       "Ref-pc conflict (%C.%M)\n",			       varNo, pc - con->code, con->cb, con->mb));	    con->nRefPCConflicts++;	    remapConflictVarno(con, varNo);	} else {	    CVMassert(CVMctsIsVal(theVar));	    CVMtraceStackmaps(("ALOAD(%d) at relPC=%d: "			       "Ref-val conflict (%C.%M)\n",			       varNo, pc - con->code, con->cb, con->mb));	    con->nRefValConflicts++;	    remapConflictVarno(con, varNo);	}    }    stack[topOfStack++] = CVMctsRef;    return topOfStack;}static CVMInt32CVMstackmapLocalDLoad(CVMStackmapContext* con,		      CVMUint32 varNo, CVMInt32 topOfStack,		      CVMCellTypeState* stack, CVMCellTypeState* vars){    CVMassert(topOfStack - 1 < con->maxStack);    /*     * We don't care if we encounter a conflict here. We are only     * worried about using a conflict as a ref, which is handled in     * CVMstackmapLocalALoad().     */    stack[topOfStack++] = CVMctsVal;    stack[topOfStack++] = CVMctsVal;    return topOfStack;}/* * Interpret one opcode. Return updated topOfStack. Don't do anything * for opcodes that don't affect state (variables, stack).  */static CVMInt32CVMstackmapInterpretOne(CVMStackmapContext* con,			CVMUint8* pc, CVMCellTypeState* vars,			CVMCellTypeState* stack, CVMInt32 topOfStack){    CVMOpcode instr = (CVMOpcode)*pc;    CVMassert(topOfStack >= 0);#ifdef CVM_JVMTI    /* Just in case we have to re-do the instruction due to a breakpoint */ interpretInstr:#endif    switch(instr) {        case opc_nop:        case opc_goto:        case opc_goto_w:        case opc_iinc:        case opc_return:        case opc_ret: /* hairy ret handling outside of here */	    /* nothing */	    break;        case opc_iload:        case opc_fload:	    topOfStack =		CVMstackmapLocalLoad(con, pc[1], topOfStack, stack, vars);	    break;        case opc_lload:        case opc_dload:	    topOfStack =		CVMstackmapLocalDLoad(con, pc[1], topOfStack, stack, vars);	    break;        case opc_aload:          	    topOfStack =		CVMstackmapLocalALoad(con, pc, pc[1], topOfStack, stack, vars);	    break;        case opc_iload_0:        case opc_fload_0:	    topOfStack =		CVMstackmapLocalLoad(con, 0, topOfStack, stack, vars);	    break;        case opc_iload_1:        case opc_fload_1:	    topOfStack =		CVMstackmapLocalLoad(con, 1, topOfStack, stack, vars);	    break;        case opc_iload_2:        case opc_fload_2:	    topOfStack =		CVMstackmapLocalLoad(con, 2, topOfStack, stack, vars);	    break;        case opc_iload_3:        case opc_fload_3:	    topOfStack =		CVMstackmapLocalLoad(con, 3, topOfStack, stack, vars);	    break;        case opc_lload_0:        case opc_dload_0:	    topOfStack =		CVMstackmapLocalDLoad(con, 0, topOfStack, stack, vars);	    break;        case opc_lload_1:        case opc_dload_1:	    topOfStack =		CVMstackmapLocalDLoad(con, 1, topOfStack, stack, vars);	    break;        case opc_lload_2:        case opc_dload_2:	    topOfStack =		CVMstackmapLocalDLoad(con, 2, topOfStack, stack, vars);	    break;        case opc_lload_3:        case opc_dload_3:	    topOfStack =		CVMstackmapLocalDLoad(con, 3, topOfStack, stack, vars);	    break;        case opc_aload_0:	    topOfStack =		C

⌨️ 快捷键说明

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