ccm_runtime.c
来自「This is a resource based on j2me embedde」· C语言 代码 · 共 1,826 行 · 第 1/5 页
C
1,826 行
CVMCCMstatsInc(ee, CVMCCM_STATS_CVMCCMruntimeInstanceOf); success = CVMisAssignable(ee, objCb, instanceofCb); /* CVMgcUnsafeIsInstanceOf() may have thrown StackOverflowError */ if (CVMlocalExceptionOccurred(ee)) { CVMCCMhandleException(ccee); } /* NOTE: If the instanceof is successful, then we know that objCb is cast- safe with respect to instanceofCb. We will cache objCb because we may very well check another object of the same type against castCb again when we go through this code path again. The cached ClassBlock will allow us to quickly determine cast-safety by a simple equivalence test instead of having to go through CVMisAssignable() again. */ /* Only write back the objCb for methods above codeCacheDecompileStart. * If CVM_AOT is enabled, make sure we don't write into the AOT code. */ /* Make sure cachedCbPtr is in the codecache */#ifdef CVM_AOT CVMassert(((CVMUint8*)cachedCbPtr >= CVMglobals.jit.codeCacheStart && (CVMUint8*)cachedCbPtr < CVMglobals.jit.codeCacheEnd) || ((CVMUint8*)cachedCbPtr >= CVMglobals.jit.codeCacheAOTStart && (CVMUint8*)cachedCbPtr < CVMglobals.jit.codeCacheAOTEnd));#else CVMassert(((CVMUint8*)cachedCbPtr >= CVMglobals.jit.codeCacheStart && (CVMUint8*)cachedCbPtr < CVMglobals.jit.codeCacheEnd));#endif if (success && (CVMUint8*)cachedCbPtr > CVMglobals.jit.codeCacheDecompileStart#ifdef CVM_AOT && !((CVMUint8*)cachedCbPtr >= CVMglobals.jit.codeCacheAOTStart && (CVMUint8*)cachedCbPtr < CVMglobals.jit.codeCacheAOTEnd)#endif ) { *cachedCbPtr = objCb; }#if 0 /* Do a dumpstack so we know who is failing a lot */ if (success && !((CVMUint8*)cachedCbPtr > CVMglobals.jit.codeCacheDecompileStart) { CVMMethodBlock* mb = ee->interpreterStack.currentFrame->mb; CVMconsolePrintf("--> %C.%M\n", CVMmbClassBlock(mb), mb); CVMdumpStack(&ee->interpreterStack,0,0,0); }#endif return success;}#endif#ifndef CVMCCM_HAVE_PLATFORM_SPECIFIC_LOOKUP_INTEFACE_MB/* Purpose: Looks up the target MethodBlock which implements the specified interface method. *//* Type: STATE_FLUSHED THROWS_SINGLE *//* Throws: IncompatibleClassChangeError. *//* NOTE: The caller should check if the object is NULL first. */const CVMMethodBlock *CVMCCMruntimeLookupInterfaceMB(CVMCCExecEnv *ccee, CVMClassBlock *ocb, const CVMMethodBlock *imb, CVMInt32 *guessPtr){#if defined(CVM_DEBUG_ASSERTS) || defined(CVM_CCM_COLLECT_STATS) CVMExecEnv *ee = CVMcceeGetEE(ccee);#endif const CVMMethodBlock *mb; CVMClassBlock *icb; /* interface cb for method we are calling */ CVMInterfaces *interfaces; CVMUint32 interfaceCount; CVMInterfaceTable *itablePtr; CVMUint16 methodTableIndex;/* index into ocb's methodTable */ CVMInt32 guess; CVMassert(CVMD_isgcUnsafe(ee)); CVMCCMstatsInc(ee, CVMCCM_STATS_CVMCCMruntimeLookupInterfaceMB); icb = CVMmbClassBlock(imb); interfaces = CVMcbInterfaces(ocb); interfaceCount = CVMcbInterfaceCountGivenInterfaces(interfaces); itablePtr = CVMcbInterfaceItable(interfaces); /* * Search the objects interface table, looking for the entry * whose interface cb matches the cb of the inteface we * are invoking. */ guess = interfaceCount - 1; while ((guess >= 0) && (CVMcbInterfacecbGivenItable(itablePtr,guess) != icb)) { guess--; } if (guess >= 0) { CVMassert(CVMcbInterfacecbGivenItable(itablePtr, guess) == icb); /* Update the guess if it was wrong, the code is not * for a romized class, and the code is not transition * code, which is also in ROM. */ /* Only write back the guess for methods above * codeCacheDecompileStart. If CVM_AOT is enabled, * make sure we don't write into the AOT code. */ /* Make sure guessPtr is in the codecache */#ifdef CVM_AOT CVMassert(((CVMUint8*)guessPtr >= CVMglobals.jit.codeCacheStart && (CVMUint8*)guessPtr < CVMglobals.jit.codeCacheEnd) || ((CVMUint8*)guessPtr >= CVMglobals.jit.codeCacheAOTStart && (CVMUint8*)guessPtr < CVMglobals.jit.codeCacheAOTEnd));#else CVMassert(((CVMUint8*)guessPtr >= CVMglobals.jit.codeCacheStart && (CVMUint8*)guessPtr < CVMglobals.jit.codeCacheEnd));#endif if (CVMcbInterfacecb(ocb, guess) == icb && (CVMUint8*)guessPtr > CVMglobals.jit.codeCacheDecompileStart#ifdef CVM_AOT && !((CVMUint8*)guessPtr >= CVMglobals.jit.codeCacheAOTStart && (CVMUint8*)guessPtr < CVMglobals.jit.codeCacheAOTEnd)#endif ) { *guessPtr = guess; } /* * We know CVMcbInterfacecb(ocb, guess) is for the interface that * we are invoking. Use it to convert the index of the method in * the interface's methods array to the index of the method * in the class' methodTable array. */ methodTableIndex = CVMcbInterfaceMethodTableIndexGivenInterfaces( interfaces, guess, CVMmbMethodSlotIndex(imb)); } else if (icb == CVMsystemClass(java_lang_Object)) { /* * Per VM spec 5.4.3.4, the resolved interface method may be * a method of java/lang/Object. */ methodTableIndex = CVMmbMethodTableIndex(imb); } else { CVMExecEnv *ee = CVMcceeGetEE(ccee); CVMthrowIncompatibleClassChangeError(ee, "class %C does not implement interface %C", ocb, icb); CVMCCMhandleException(ccee); methodTableIndex = 0; /* NOTREACHED, make compiler happy */ } /* * Fetch the proper mb and it's cb. */ mb = CVMcbMethodTableSlot(ocb, methodTableIndex); return mb;}#endif#ifndef CVMCCM_HAVE_PLATFORM_SPECIFIC_NEW/* Purpose: Instantiates an object of the specified class. *//* Type: STATE_FLUSHED_TOTALLY THROWS_SINGLE *//* Throws: OutOfMemoryError. */CVMObject *CVMCCMruntimeNew(CVMCCExecEnv *ccee, CVMClassBlock *newCb){ CVMObject *obj; CVMExecEnv *ee = CVMcceeGetEE(ccee); CVMassert(CVMD_isgcUnsafe(ee));#if CVM_DEBUG /* We better not be holding a microlock */ CVMassert(ee->microLock == 0);#endif CVMCCMstatsInc(ee, CVMCCM_STATS_CVMCCMruntimeNew); obj = CVMgcAllocNewInstance(ee, newCb); if (obj == NULL) { /* Failed to instantiate the object. So throw an OutOfMemoryError: */ CVMthrowOutOfMemoryError(ee, "%C", newCb); CVMCCMhandleException(ccee); } return obj;}#endif#ifndef CVMCCM_HAVE_PLATFORM_SPECIFIC_NEWARRAY/* Purpose: Instantiates a primitive array of the specified type and size. *//* Type: STATE_FLUSHED_TOTALLY THROWS_MULTIPLE *//* Throws: OutOfMemoryError, NegativeArraySizeException. */CVMObject *CVMCCMruntimeNewArray(CVMCCExecEnv *ccee, CVMJavaInt length, CVMClassBlock *arrCB){ CVMExecEnv *ee = CVMcceeGetEE(ccee); CVMObject *arrObj; CVMBasicType typeCode = CVMarrayBaseType(arrCB); CVMassert(CVMD_isgcUnsafe(ee));#if CVM_DEBUG /* We better not be holding a microlock */ CVMassert(ee->microLock == 0);#endif CVMCCMstatsInc(ee, CVMCCM_STATS_CVMCCMruntimeNewArray); if (length < 0) { CVMthrowNegativeArraySizeException(ee, NULL); CVMCCMhandleException(ccee); } CVMassert(arrCB != NULL); /* NOTE: CVMgcAllocNewArray may block and initiate GC. */ arrObj = (CVMObject *)CVMgcAllocNewArray(ee, typeCode, arrCB, length); /* Make sure we created the right beast: */ CVMassert(arrObj == NULL || CVMisArrayClassOfBasicType(CVMobjectGetClass(arrObj), CVMbasicTypeID[typeCode])); if (arrObj == NULL) { CVMthrowOutOfMemoryError(ee, "%C", arrCB); CVMCCMhandleException(ccee); } return arrObj;}#endif#ifndef CVMCCM_HAVE_PLATFORM_SPECIFIC_ANEWARRAY/* Purpose: Instantiates an object array of the specified type and size. *//* Type: STATE_FLUSHED_TOTALLY THROWS_MULTIPLE *//* Throws: OutOfMemoryError, NegativeArraySizeException, StackOverflowError. */CVMObject *CVMCCMruntimeANewArray(CVMCCExecEnv *ccee, CVMJavaInt length, CVMClassBlock *arrayCb){ CVMExecEnv *ee = CVMcceeGetEE(ccee); CVMObject *arrObj; CVMassert(CVMD_isgcUnsafe(ee));#if CVM_DEBUG /* We better not be holding a microlock */ CVMassert(ee->microLock == 0);#endif CVMCCMstatsInc(ee, CVMCCM_STATS_CVMCCMruntimeANewArray); if (length < 0) { CVMthrowNegativeArraySizeException(ee, NULL); CVMCCMhandleException(ccee); } arrObj = (CVMObject *)CVMgcAllocNewArray(ee, CVM_T_CLASS, arrayCb, length); if (arrObj == NULL) { CVMthrowOutOfMemoryError(ee, "%C", arrayCb); CVMCCMhandleException(ccee); } return arrObj;}#endif#ifndef CVMCCM_HAVE_PLATFORM_SPECIFIC_MULTIANEWARRAY/* Purpose: Instantiates a multi dimensional object array of the specified dimensions. *//* Type: STATE_FLUSHED_TOTALLY THROWS_MULTIPLE *//* Throws: OutOfMemoryError, NegativeArraySizeException. *//* * CVMmultiArrayAlloc() is called from java opcode multianewarray * and passes the top of stack as parameter dimensions. * Because the width of the array dimensions is obtained via * dimensions[i], dimensions has to be of the same type as * the stack elements for proper access. */CVMObject *CVMCCMruntimeMultiANewArray(CVMCCExecEnv *ccee, CVMJavaInt nDimensions, CVMClassBlock *arrCb, CVMStackVal32 *dimensions){ CVMExecEnv *ee = CVMcceeGetEE(ccee); CVMObject *arrObj; CVMInt32 effectiveNDimensions; CVMInt32 dimCount; /* in case we encounter a 0 */ CVMObjectICell *resultCell; CVMassert(CVMD_isgcUnsafe(ee));#if CVM_DEBUG /* We better not be holding a microlock */ CVMassert(ee->microLock == 0);#endif CVMCCMstatsInc(ee, CVMCCM_STATS_CVMCCMruntimeMultiANewArray); effectiveNDimensions = nDimensions; /* * Now go through the dimensions. Check for negative dimensions. * Also check for whether there is a 0 in the dimensions array * which would prevent the allocation from continuing. */ for (dimCount = 0; dimCount < nDimensions; dimCount++) { CVMInt32 dim = dimensions[dimCount].j.i; if (dim <= 0) { /* Remember the first 0 in the dimensions array */ if ((dim == 0) && (effectiveNDimensions == nDimensions)) { effectiveNDimensions = dimCount + 1; /* ... and keep checking for -1's despite a 0 */ } else if (dim < 0) { CVMthrowNegativeArraySizeException(ee, NULL); CVMCCMhandleException(ccee); } } } /* * CVMmultiArrayAlloc() will do all the work * * Be paranoid about GC in this case (too many intermediate * results). */ resultCell = CVMmiscICell(ee); CVMassert(CVMID_icellIsNull(resultCell)); CVMD_gcSafeExec(ee, { /* * do not cast the pointer type of topOfStack * because it is required for correct stack access * via topOfStack[index] in CVMmultiArrayAlloc */ CVMmultiArrayAlloc(ee, effectiveNDimensions, dimensions, arrCb, resultCell); }); if (CVMID_icellIsNull(resultCell)) { /* * CVMmultiArrayAlloc() returned a null. This only happens * if an allocation failed, so throw an OutOfMemoryError */ CVMthrowOutOfMemoryError(ee, NULL); CVMCCMhandleException(ccee); } arrObj = CVMID_icellDirect(ee, resultCell); /* * Set this to null when we're done. The misc icell is needed elsewhere, * and the nullness is used to prevent errors. */ CVMID_icellSetNull(resultCell); return arrObj;}#endif#ifndef CVMCCM_HAVE_PLATFORM_SPECIFIC_RUN_CLASS_INITIALIZER/* Purpose: Runs the static initializer for the specified class if necessary. Result: -Returns true if the class has been intialized. -Returns false if class is being intialized by current thread. -Otherwise attempts to intialize the class and will return to the address in the current frame when intialization is complete.*//* Type: STATE_FLUSHED_TOTALLY THROWS_??? */CVMBoolCVMCCMruntimeRunClassInitializer(CVMCCExecEnv *ccee, CVMExecEnv *ee, CVMClassBlock *cb){
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?