jvm.c
来自「This is a resource based on j2me embedde」· C语言 代码 · 共 2,294 行 · 第 1/5 页
C
2,294 行
CVMInt64 diff = CVMlongSub(CVMtimeMillis(), CVMgcimplTimeOfLastMajorGC()); return diff;}JNIEXPORT void JNICALLJVM_TraceInstructions(jboolean on){#ifdef CVM_TRACE if (on) { CVMsetDebugFlags(CVM_DEBUGFLAG(TRACE_OPCODE)); } else { CVMclearDebugFlags(CVM_DEBUGFLAG(TRACE_OPCODE)); }#endif}JNIEXPORT void JNICALLJVM_TraceMethodCalls(jboolean on){#ifdef CVM_TRACE if (on) { CVMsetDebugFlags(CVM_DEBUGFLAG(TRACE_METHOD)); } else { CVMclearDebugFlags(CVM_DEBUGFLAG(TRACE_METHOD)); }#endif}JNIEXPORT jlong JNICALLJVM_TotalMemory(void){ CVMExecEnv* ee = CVMgetEE(); jlong totalMem; CVMD_gcUnsafeExec(ee, { totalMem = CVMgcTotalMemory(ee); }); return totalMem;}/* Called from Runtime.c */JNIEXPORT jlong JNICALLJVM_FreeMemory(void){ CVMExecEnv* ee = CVMgetEE(); jlong freeMem; CVMD_gcUnsafeExec(ee, { freeMem = CVMgcFreeMemory(ee); }); return freeMem;}#ifndef CDC_10/* Called from Runtime.c */JNIEXPORT jlong JNICALLJVM_MaxMemory(void){ return CVMint2Long(CVMglobals.maxHeapSize);}#endif /* !CDC_10 *//* Called from Throwable.c */#undef min#define min(x, y) (((int)(x) < (int)(y)) ? (x) : (y))/* NOTE: The second argument to printStackTrace() is expected to be an object * with a void println(char[]) method, such as a PrintStream or a PrintWriter. */JNIEXPORT void JNICALLJVM_PrintStackTrace(JNIEnv *env, jobject throwable, jobject printable){ CVMprintStackTrace(CVMjniEnv2ExecEnv(env), throwable, printable);}#ifndef CDC_10static const char*getSourceFileName(CVMClassBlock* cb){#ifdef CVM_DEBUG_CLASSINFO const char* fn = CVMcbSourceFileName(cb); const char* tmp; if (fn == NULL) { return NULL; } tmp = strrchr(fn, '/'); if (tmp != NULL) { fn = tmp + 1; /* skip past last separator */ } return fn;#else return NULL;#endif}#endif /* !CDC_10 */void CVMprintStackTrace(CVMExecEnv *ee, CVMThrowableICell* throwableICell, CVMObjectICell* printableICell){#ifndef CVM_DEBUG_STACKTRACES CVMconsolePrintf("\t<no backtrace available in non-debug build>\n");#else CVMID_localrootBegin(ee) { CVMID_localrootDeclare(CVMArrayOfRefICell, backtraceICell); CVMID_localrootDeclare(CVMArrayOfIntICell, pcArrayICell);#ifdef CVM_JIT CVMID_localrootDeclare(CVMArrayOfBooleanICell, isCompiledArrayICell);#endif CVMID_localrootDeclare(CVMStringICell, stringICell); CVMID_localrootDeclare(CVMObjectICell, objICell); CVMID_localrootDeclare(CVMObjectICell, tempICell); CVMUint32 count; CVMUint32 pcArrayLen; /* * Read in the backtrace array field of the throwable. */ CVMID_fieldReadRef(ee, throwableICell, CVMoffsetOfjava_lang_Throwable_backtrace, tempICell); CVMID_icellAssign(ee, backtraceICell, (CVMArrayOfRefICell*)tempICell); if (CVMID_icellIsNull(backtraceICell)) { goto localRootEnd; } /* * The first element of the backtrace array is an array of method index * and line number info. */ CVMID_arrayReadRef(ee, backtraceICell, 0, tempICell); CVMID_icellAssign(ee, pcArrayICell, (CVMArrayOfIntICell*)tempICell); if (CVMID_icellIsNull(pcArrayICell)) { goto localRootEnd; } /* * The 2nd element of the backtrace array is an array of isCompiled * values. */#ifdef CVM_JIT CVMID_arrayReadRef(ee, backtraceICell, 1, tempICell); CVMID_icellAssign(ee, isCompiledArrayICell, (CVMArrayOfBooleanICell*)tempICell); if (CVMID_icellIsNull(isCompiledArrayICell)) { goto localRootEnd; }#endif /* * Print each frame in the backtrace. */ CVMID_arrayGetLength(ee, pcArrayICell, pcArrayLen); for (count = 0; count < pcArrayLen; count++) { CVMassert(!CVMlocalExceptionOccurred(ee)); CVMID_arrayReadRef(ee, backtraceICell, count + 2, objICell); if (CVMID_icellIsNull(objICell)) { goto localRootEnd; } /* obj is a java.lang.Class. Compute the backtrace string. */ { CVMJavaInt linenoInfo; CVMJavaBoolean isCompiled; char buf[256]; int i = 0; CVMClassBlock* cb = CVMgcSafeClassRef2ClassBlock(ee, objICell); CVMMethodBlock* mb; /* get lineno, mb, and isCompiled values */ CVMID_arrayReadInt(ee, pcArrayICell, count, linenoInfo);#ifdef CVM_JIT CVMID_arrayReadBoolean(ee, isCompiledArrayICell, count, isCompiled);#else isCompiled = CVM_FALSE;#endif mb = CVMcbMethodSlot(cb, (CVMUint32)linenoInfo & 0xffff); strncpy(buf + i, "\tat ", 4); i += 4; /* make a string out of the lineno info. */ CVMlineno2string((linenoInfo >> 16), mb, CVM_FALSE, isCompiled, buf + i, buf + sizeof(buf)); CVMnewStringUTF(ee, stringICell, buf); CVMassert(!CVMlocalExceptionOccurred(ee)); } /* call the println method of the printable object */ if (!CVMID_icellIsNull(stringICell)) { CVMMethodBlock* mb; CVMClassBlock* cb; JNIEnv* env = CVMexecEnv2JniEnv(ee); /* * The only way to get a NULL printableICell is if you are * debugging and call this function manually ,or when called * during vm startup. In this case we use CVMconsolePrintf. */ if (printableICell == NULL) { const char* str = CVMjniGetStringUTFChars(env, stringICell, NULL); if (str == NULL) { break; } CVMconsolePrintf("%s\n", str); CVMjniReleaseStringUTFChars(env, stringICell, str); } else { CVMD_gcUnsafeExec(ee, { cb = CVMobjectGetClass( CVMID_icellDirect(ee, printableICell)); }); mb = CVMclassGetNonstaticMethodBlock( cb, CVMglobals.printlnTid); (*env)->CallVoidMethod(env, printableICell, mb, stringICell); /* maybe we should only check local exceptions, or disable remote exceptions? */ if ((*env)->ExceptionCheck(env)) { break; } } } } localRootEnd:; } CVMID_localrootEnd();#endif}/* * Fill in the specified Throwable object with the current backtrace, */JNIEXPORT void JNICALLJVM_FillInStackTrace(JNIEnv *env, jobject throwable){ CVMfillInStackTrace(CVMjniEnv2ExecEnv(env), throwable); /* NOTE: CVMfillInStackTrace() may throw an exception if it is not able to allocate memory for the stack trace. */}static void CVMgcUnsafeFillInStackTrace(CVMExecEnv *ee, CVMThrowableICell* throwableICell);void CVMfillInStackTrace(CVMExecEnv *ee, CVMThrowableICell* throwableICell) { if (CVMD_isgcSafe(ee)) { CVMD_gcUnsafeExec(ee, { CVMgcUnsafeFillInStackTrace(ee, throwableICell); }); } else { CVMgcUnsafeFillInStackTrace(ee, throwableICell); }}#ifdef CVM_DEBUG_STACKTRACESstatic voidthrowPreallocatedOutOfMemoryError(CVMExecEnv *ee, CVMThrowableICell* throwableICell){ /* Nullify the back trace too: */ CVMD_fieldWriteRef(CVMID_icellDirect(ee, throwableICell), CVMoffsetOfjava_lang_Throwable_backtrace, NULL);#ifdef CVM_DEBUG { CVMObject *exceptionObj = CVMID_icellDirect(ee, throwableICell); CVMClassBlock *exceptionCb = CVMobjectGetClass(exceptionObj); CVMdebugPrintf(( "Could not allocate backtrace for exception object \"%C\"; " "throwing a pre-allocated OutOfMemoryError object instead\n", exceptionCb)); }#endif CVMD_gcSafeExec(ee, { CVMgcSafeThrowLocalException( ee, CVMglobals.preallocatedOutOfMemoryError); });}#endifstatic void CVMgcUnsafeFillInStackTrace(CVMExecEnv *ee, CVMThrowableICell* throwableICell){#ifdef CVM_DEBUG_STACKTRACES CVMFrame* startFrame; CVMFrameIterator iter; CVMMethodBlock* mb; CVMArrayOfRef* backtrace; CVMArrayOfInt* pcArray;#ifdef CVM_JIT CVMArrayOfBoolean* isCompiledArray = NULL;#endif CVMObject* tempObj; CVMInt32 backtraceSize; CVMInt32 count; CVMBool noMoreFrameSkips; startFrame = CVMeeGetCurrentFrame(ee); /* how many useful frames are there on the stack? */ CVMD_gcSafeExec(ee, { noMoreFrameSkips = CVM_FALSE; backtraceSize = 0; CVMframeIterateInit(&iter, startFrame); while (CVMframeIterateNext(&iter)) { mb = CVMframeIterateGetMb(&iter); /* ignore all frames that are just part of the <init> of * the throwable object. */ if (!noMoreFrameSkips) { if (mb == CVMglobals.java_lang_Throwable_fillInStackTrace) { continue; } else if (CVMtypeidIsConstructor(CVMmbNameAndTypeID(mb)) && CVMisSubclassOf(ee, CVMmbClassBlock(mb), CVMsystemClass(java_lang_Throwable))) { continue; } else { noMoreFrameSkips = CVM_TRUE; } } backtraceSize++; } }); /* * The backtrace array contains the following: * <1> Pointer to an int[] for line number and the method index for * each frame. The lineno and index each take up 16-bits of the int. * <2> If the JIT is supported, a pointer to a boolean[] that contains * this isCompiled flag for each frame, otherwise NULL. * <3...n+2> The Class instance for each mb in each frame. This is * used to force all classes that are in a backtrace to stay loaded. */ backtrace = (CVMArrayOfRef*)CVMgcAllocNewArray( ee, CVM_T_CLASS, (CVMClassBlock*)CVMbasicTypeArrayClassblocks[CVM_T_CLASS], backtraceSize + 2); tempObj = (CVMObject*)backtrace; CVMD_fieldWriteRef(CVMID_icellDirect(ee, throwableICell), CVMoffsetOfjava_lang_Throwable_backtrace, tempObj); if (backtrace == NULL) { throwPreallocatedOutOfMemoryError(ee, throwableICell); return; } /* * The pcArray is a java array of ints and is stored as the first * element of the backtrace array. */ pcArray = (CVMArrayOfInt*)CVMgcAllocNewArray( ee, CVM_T_INT, (CVMClassBlock*)CVMbasicTypeArrayClassblocks[CVM_T_INT], backtraceSize); /* recache backtrace in case we became gcsafe during allocation. */ CVMD_fieldReadRef(CVMID_icellDirect(ee, throwableICell), CVMoffsetOfjava_lang_Throwable_backtrace, tempObj); backtrace = (CVMArrayOfRef*)tempObj; tempObj = (CVMObject*)pcArray; CVMD_arrayWriteRef(backtrace, 0, tempObj); if (pcArray == NULL) { throwPreallocatedOutOfMemoryError(ee, throwableICell); return; }#ifdef CVM_JIT /* * The isCompiledArray is an array of booleans and is stored as the * 2nd element of the backtrace array. */ isCompiledArray = (CVMArrayOfBoolean*)CVMgcAllocNewArray( ee, CVM_T_BOOLEAN, (CVMClassBlock*)CVMbasicTypeArrayClassblocks[CVM_T_BOOLEAN], backtraceSize); /* recache backtrace and pcArray in case we became gcsafe during * the allocation. */ CVMD_fieldReadRef(CVMID_icellDirect(ee, throwableICell), CVMoffsetOfjava_lang_Throwable_backtrace, tempObj); backtrace = (CVMArrayOfRef*)tempObj; CVMD_arrayReadRef(backtrace, 0, tempObj); pcArray = (CVMArrayOfInt*)tempObj; tempObj = (CVMObject*)isCompiledArray; CVMD_arrayWriteRef(backtrace, 1, tempObj); if (isCompiledArray == NULL) { throwPreallocatedOutOfMemoryError(ee, throwableICell); return; }#endif /* * Fill in the pcArray, isCompiledArray, and the backtrace array. */ noMoreFrameSkips = CVM_FALSE; count = 0; CVMframeIterateInit(&iter, startFrame); while (CVMframeIterateNext(&iter)) { CVMMethodBlock* mb = CVMframeIterateGetMb(&iter); CVMJavaInt lineno; /* ignore all frames that are just part of the <init> of * the throwable object. */ if (!noMoreFrameSkips) { if (mb == CVMglobals.java_lang_Throwable_fillInStackTrace) { continue; } else if (CVMtypeidIsConstructor(CVMmbNameAndTypeID(mb)) && CVMisSubclassOf(ee, CVMmbClassBlock(mb), CVMsystemClass(java_lang_Throwable))) { continue; } else { noMoreFrameSkips = CVM_TRUE; } } /* store the line number and the method index in the pcArray */ if (CVMmbIs(mb, NATIVE)) { lineno = -2; /* a native method has -2 as its lineno */ } else { CVMUint8* javaPc; CVMUint16 javaPcOffset;#ifdef CVM_JIT CVMBool isCompiled; if (CVMframeIterateIsInlined(&iter)) { isCompiled = CVM_TRUE; } else { CVMFrame* frame = CVMframeIterateGetFrame(&iter); CVMassert(frame->mb == mb); isCompiled = CVMframeIsCompiled(frame); } CVMD_arrayWriteBoolean(isCompiledArray, count, (CVMJavaBoolean)isCompiled);#endif javaPc = CVMframeIterateGetJavaPc(&iter); if (javaPc == NULL) { javaPc = CVMmbJavaCode(mb); } javaPcOffset = (javaPc - CVMmbJavaCode(mb)); /* We must eagerly compute the line number information for * <clinit> because the jmd may be freed after the <clinit> * is run. So we just get the lineno information for all. */#ifdef CVM_DEBUG_CLASSINFO lineno = CVMpc2lineno(mb, javaPcOffset);#else
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?