ccm_runtime.c
来自「This is a resource based on j2me embedde」· C语言 代码 · 共 1,826 行 · 第 1/5 页
C
1,826 行
CVMCCMstatsInc(ee, CVMCCM_STATS_CVMCCMruntimeRunClassInitializer); /* * If static intializers still need to be run for this class, then * leave it up to the interpreter to do this for us first. */ if (CVMcbInitializationNeeded(cb, ee)) { int result; CVMCCMruntimeLazyFixups(ee); CVMD_gcSafeExec(ee, { CVMMethodBlock *mb; /* NOTE: &mb cannot be 0. Otherwise, CVMclassInitNoCRecursion will invoke the interpreter loop rather than setup a transition frame. */ result = CVMclassInitNoCRecursion(ee, cb, &mb); }); /* No action take. Class is already initialized. */ if (result == 0) { /* Nothing to do. Class is already initialized. */ /* Transition frame successfully pushed. */ } else if (result == 1) { CVMJITexitNative(ccee); /* An error occurred. Exception was thrown. */ } else { CVMCCMhandleException(ccee); } } /* * Return TRUE if <clinit> has been run. The only time this will not * be the case is if it is being run by the current thread. */ return !CVMcbCheckInitNeeded(cb, ee);}#endif#if !defined(CVMCCM_HAVE_PLATFORM_SPECIFIC_RESOLVE_CLASS_BLOCK) || \ !defined(CVMCCM_HAVE_PLATFORM_SPECIFIC_RESOLVE_ARRAY_CLASS_BLOCK) || \ !defined(CVMCCM_HAVE_PLATFORM_SPECIFIC_RESOLVE_GETFIELD_OFFSET) || \ !defined(CVMCCM_HAVE_PLATFORM_SPECIFIC_RESOLVE_PUTFIELD_OFFSET) || \ !defined(CVMCCM_HAVE_PLATFORM_SPECIFIC_RESOLVE_METHOD_BLOCK) || \ !defined(CVMCCM_HAVE_PLATFORM_SPECIFIC_RESOLVE_SPECIAL_METHOD_BLOCK) || \ !defined(CVMCCM_HAVE_PLATFORM_SPECIFIC_RESOLVE_METHOD_TABLE_OFFSET) || \ !defined(CVMCCM_HAVE_PLATFORM_SPECIFIC_RESOLVE_NEW_CLASS_BLOCK_AND_CLINIT)||\ !defined(CVMCCM_HAVE_PLATFORM_SPECIFIC_RESOLVE_GETSTATIC_FB_AND_CLINIT)||\ !defined(CVMCCM_HAVE_PLATFORM_SPECIFIC_RESOLVE_PUTSTATIC_FB_AND_CLINIT)||\ !defined(CVMCCM_HAVE_PLATFORM_SPECIFIC_RESOLVE_STATIC_MB_AND_CLINIT)/* Purpose: Resolves the specified constant pool entry. *//* Type: STATE_FLUSHED_TOTALLY THROWS_MULTIPLE *//* Throws: IllegalAccessError, IncompatibleClassChangeError, NoSuchFieldError, NoSuchMethodError, etc. */static voidCVMCCMruntimeResolveConstantPoolEntry(CVMCCExecEnv *ccee, CVMExecEnv *ee, CVMUint16 cpIndex, CVMConstantPool *cp){ /* NOTE: CVMcpResolveEntry() will check if the constant pool is already resolved. If it is, it won't go through the resolution process again. If the constantpool entry isn't resolved yet, CVMcpResolveEntry() will resolve it. If it fails to resolve it, the appropriate exception will already have been thrown. */ if (!CVMcpIsResolved(cp, cpIndex)) { CVMBool success; CVMCCMruntimeLazyFixups(ee); CVMD_gcSafeExec(ee, { success = CVMcpResolveEntry(ee, cp, cpIndex); }); if (!success) { CVMCCMhandleException(ccee); } }}#endif#ifndef CVMCCM_HAVE_PLATFORM_SPECIFIC_RESOLVE_CLASS_BLOCK/* Purpose: Resolves the specified class block constant pool entry. *//* Result: Always returns TRUE since no class initialization is needed. *//* Type: STATE_FLUSHED_TOTALLY THROWS_MULTIPLE *//* Throws: IllegalAccessError, etc. */CVMBoolCVMCCMruntimeResolveClassBlock(CVMCCExecEnv *ccee, CVMExecEnv *ee, CVMUint16 cpIndex, CVMClassBlock **cachedConstant){ CVMConstantPool *cp = CVMeeGetCurrentFrameCp(ee); CVMClassBlock *cb; CVMCCMstatsInc(ee, CVMCCM_STATS_CVMCCMruntimeResolveClassBlock); /* NOTE: CVMCCMruntimeResolveConstantPoolEntry() won't return if an exception was thrown. It will bypass all this and turn control over to the VM's exception handling mechanism. */ CVMCCMruntimeResolveConstantPoolEntry(ccee, ee, cpIndex, cp); cb = CVMcpGetCb(cp, cpIndex); CVMassert(cachedConstant != NULL); /* Make sure cachedConstant is in the codecache */ CVMassert(((CVMUint8*)cachedConstant >= CVMglobals.jit.codeCacheStart && (CVMUint8*)cachedConstant < CVMglobals.jit.codeCacheEnd)); /* * AOT only supports ROMized classes, whose cp are always resolved. * CVMCCMruntimeResolveClassBlock should never called for AOT code. * The above assertion covers that. */ *cachedConstant = cb; return CVM_TRUE; /* no class initialization needed */}#endif#ifndef CVMCCM_HAVE_PLATFORM_SPECIFIC_RESOLVE_ARRAY_CLASS_BLOCK/* Purpose: Resolves the specified array class block constant pool entry. *//* Result: Always returns TRUE since no class initialization is needed. *//* Type: STATE_FLUSHED_TOTALLY THROWS_MULTIPLE *//* Throws: IllegalAccessError, etc. */CVMBoolCVMCCMruntimeResolveArrayClassBlock(CVMCCExecEnv *ccee, CVMExecEnv *ee, CVMUint16 cpIndex, CVMClassBlock **cachedConstant){ CVMConstantPool *cp = CVMeeGetCurrentFrameCp(ee); CVMClassBlock *elemCb; CVMClassBlock *arrCb; CVMCCMstatsInc(ee, CVMCCM_STATS_CVMCCMruntimeResolveArrayClassBlock); /* NOTE: CVMCCMruntimeResolveConstantPoolEntry() won't return if an exception was thrown. It will bypass all this and turn control over to the VM's exception handling mechanism. */ CVMCCMruntimeResolveConstantPoolEntry(ccee, ee, cpIndex, cp); elemCb = CVMcpGetCb(cp, cpIndex); /* CVMclassGetArrayOf() may block. CVMgcAllocNewArray() may block. */ CVMD_gcSafeExec(ee, { arrCb = CVMclassGetArrayOf(ee, elemCb); }); if (arrCb == NULL) { /* CVMclassGetArrayOf() has already thrown an exception. */ CVMCCMhandleException(ccee); } CVMassert(cachedConstant != NULL); /* Make sure cachedConstant is in the codecache */ CVMassert(((CVMUint8*)cachedConstant >= CVMglobals.jit.codeCacheStart && (CVMUint8*)cachedConstant < CVMglobals.jit.codeCacheEnd)); /* * AOT only supports ROMized classes, whose cp are always resolved. * CVMCCMruntimeResolveArrayClassBlock should never called for AOT code. * The above assertion covers that. */ *cachedConstant = arrCb; return CVM_TRUE; /* no class initialization needed */}#endif#if !defined(CVMCCM_HAVE_PLATFORM_SPECIFIC_RESOLVE_GETFIELD_OFFSET) || \ !defined(CVMCCM_HAVE_PLATFORM_SPECIFIC_RESOLVE_PUTFIELD_OFFSET)/* Purpose: Resolves the specified field block constant pool entry into a field offset, checks if the filed has changed into a static field, and checks if the field is final (i.e. not writable to) if necessary. *//* Result: Always returns TRUE since no class initialization is needed. *//* Type: STATE_FLUSHED_TOTALLY THROWS_MULTIPLE *//* Throws: IllegalAccessError, IncompatibleClassChangeError, NoSuchFieldError, etc. */static CVMBoolCVMCCMruntimeResolveFieldOffset(CVMCCExecEnv *ccee, CVMExecEnv *ee, CVMUint16 cpIndex, CVMUint32 *cachedConstant, CVMBool isWrite){ CVMConstantPool *cp = CVMeeGetCurrentFrameCp(ee); CVMUint32 offset; CVMFieldBlock *fb; /* NOTE: CVMCCMruntimeResolveConstantPoolEntry() won't return if an exception was thrown. It will bypass all this and turn control over to the VM's exception handling mechanism. */ CVMCCMruntimeResolveConstantPoolEntry(ccee, ee, cpIndex, cp); fb = CVMcpGetFb(cp, cpIndex); offset = CVMfbOffset(fb) * sizeof(CVMJavaVal32);#ifndef CVM_TRUSTED_CLASSLOADERS { /* Make sure that the field is not static: */ if (!CVMfieldHasNotChangeStaticState(ee, fb, CVM_FALSE)) { CVMCCMhandleException(ccee); } /* Make sure we're allowed to write to the field: */ if (isWrite && !CVMfieldIsOKToWriteTo(ee, fb, CVMeeGetCurrentFrameCb(ee), CVM_TRUE)) { CVMCCMhandleException(ccee); } }#endif CVMassert(cachedConstant != NULL); /* Make sure cachedConstant is in the codecache */ CVMassert(((CVMUint8*)cachedConstant >= CVMglobals.jit.codeCacheStart && (CVMUint8*)cachedConstant < CVMglobals.jit.codeCacheEnd)); /* * AOT only supports ROMized classes, whose cp are always resolved. * CVMCCMruntimeResolveFieldOffset should never called for AOT code. * The above assertion covers that. */ *cachedConstant = offset; return CVM_TRUE; /* no class initialization needed */}#endif#ifndef CVMCCM_HAVE_PLATFORM_SPECIFIC_RESOLVE_GETFIELD_OFFSET/* Purpose: Resolves the specified field block constant pool entry into a field offset, and checks if the filed has changed into a static field. *//* Result: Always returns TRUE since no class initialization is needed. *//* Type: STATE_FLUSHED_TOTALLY THROWS_MULTIPLE *//* Throws: IllegalAccessError, IncompatibleClassChangeError, NoSuchFieldError, etc. */CVMBoolCVMCCMruntimeResolveGetfieldFieldOffset(CVMCCExecEnv *ccee, CVMExecEnv *ee, CVMUint16 cpIndex, CVMUint32 *cachedConstant){ CVMCCMstatsInc(ee, CVMCCM_STATS_CVMCCMruntimeResolveGetfieldFieldOffset); return CVMCCMruntimeResolveFieldOffset(ccee, ee, cpIndex, cachedConstant, CVM_FALSE);}#endif#ifndef CVMCCM_HAVE_PLATFORM_SPECIFIC_RESOLVE_PUTFIELD_OFFSET/* Purpose: Resolves the specified field block constant pool entry into a field offset, checks if the filed has changed into a static field, and checks if the field is final (i.e. not writable to). *//* Result: Always returns TRUE since no class initialization is needed. *//* Type: STATE_FLUSHED_TOTALLY THROWS_MULTIPLE *//* Throws: IllegalAccessError, IncompatibleClassChangeError, NoSuchFieldError, etc. */CVMBoolCVMCCMruntimeResolvePutfieldFieldOffset(CVMCCExecEnv *ccee, CVMExecEnv *ee, CVMUint16 cpIndex, CVMUint32 *cachedConstant){ CVMCCMstatsInc(ee, CVMCCM_STATS_CVMCCMruntimeResolvePutfieldFieldOffset); return CVMCCMruntimeResolveFieldOffset(ccee, ee, cpIndex, cachedConstant, CVM_TRUE);}#endif#ifndef CVMCCM_HAVE_PLATFORM_SPECIFIC_RESOLVE_METHOD_BLOCK/* Purpose: Resolves the specified method block constant pool entry. *//* Result: Always returns TRUE since no class initialization is needed. *//* Type: STATE_FLUSHED_TOTALLY THROWS_MULTIPLE *//* Throws: IllegalAccessError, NoSuchMethodError, etc. */CVMBoolCVMCCMruntimeResolveMethodBlock(CVMCCExecEnv *ccee, CVMExecEnv *ee, CVMUint16 cpIndex, CVMMethodBlock **cachedConstant){ CVMConstantPool *cp = CVMeeGetCurrentFrameCp(ee); CVMMethodBlock *mb; CVMCCMstatsInc(ee, CVMCCM_STATS_CVMCCMruntimeResolveMethodBlock); /* NOTE: CVMCCMruntimeResolveConstantPoolEntry() won't return if an exception was thrown. It will bypass all this and turn control over to the VM's exception handling mechanism. */ CVMCCMruntimeResolveConstantPoolEntry(ccee, ee, cpIndex, cp); mb = CVMcpGetMb(cp, cpIndex); CVMassert(cachedConstant != NULL); /* Make sure cachedConstant is in the codecache */ CVMassert(((CVMUint8*)cachedConstant >= CVMglobals.jit.codeCacheStart && (CVMUint8*)cachedConstant < CVMglobals.jit.codeCacheEnd)); /* * AOT only supports ROMized classes, whose cp are always resolved. * CVMCCMruntimeResolveMethodBlock should never called for AOT code. * The above assertion covers that. */ *cachedConstant = mb; return CVM_TRUE; /* no class initialization needed */}#endif#ifndef CVMCCM_HAVE_PLATFORM_SPECIFIC_RESOLVE_SPECIAL_METHOD_BLOCK/* Purpose: Resolves the specified method block constant pool entry for invokespecial, and checks if the method has changed into a static method. *//* Result: Always returns TRUE since no class initialization is needed. *//* Type: STATE_FLUSHED_TOTALLY THROWS_MULTIPLE *//* Throws: IllegalAccessError, IncompatibleClassChangeError, NoSuchMethodError, etc. */CVMBoolCVMCCMruntimeResolveSpecialMethodBlock(CVMCCExecEnv *ccee, CVMExecEnv *ee, CVMUint16 cpIndex, CVMMethodBlock **cachedConstant){ CVMConstantPool *cp = CVMeeGetCurrentFrameCp(ee); CVMMethodBlock *mb; CVMClassBlock *currentCb; CVMCCMstatsInc(ee, CVMCCM_STATS_CVMCCMruntimeResolveSpecialMethodBlock); /* NOTE: CVMCCMruntimeResolveConstantPoolEntry() won't return if an exception was thrown. It will bypass all this and turn control over to the VM's exception handling mechanism. */ CVMCCMruntimeResolveConstantPoolEntry(ccee, ee, cpIndex, cp); mb = CVMcpGetMb(cp, cpIndex);#ifndef CVM_TRUSTED_CLASSLOADERS CVMCCMruntimeLazyFixups(ee); /* Make sure that the method is not static: */ if (!CVMmethodHasNotChangeStaticState(ee, mb, CVM_FALSE)) { CVMCCMhandleException(ccee); }#endif /* NOTE: The following method of getting the currentCb is based on the assumption that inlining is not allowed for methods which have unresolved nodes i.e. CVMeeGetCurrentFrame(ee)->mb will yield the mb of the method doing the invokespecial. */ currentCb = CVMeeGetCurrentFrameCb(ee); if (CVMisSpecialSuperCall(currentCb, mb)) { /* NOTE: In the quickener, the following test is done: new_mb = CVMlookupSpecialSuperMethod(ee, currClass, methodID); if (new_mb == mb) quicken to invokenonvirtual. else quicken to invokesuper and store method index (computed from CVMmbMethodTableIndex(new_mb)) in the opcode operand. In the interpreter, invokenonvirtual would invoke the mb in the CP entry, and invokesuper would use the stored method index to compute the mb in such a way that results in the same mb as new_mb above. Hence, for the case of the CCM runtime, regardless of whether new_mb equals mb or not, we effectively always end up using the value in new_mb anyway. So, we can simplify logic above into just the new_mb lookup. */ CVMMethodTypeID methodID = CVMmbNameAndTypeID(mb); /* Find matching declared method in a super class. */ mb = CVMlookupSpecialSuperMethod(ee, currentCb, methodID); } CVMassert(cachedConstant != NULL);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?