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 + -
显示快捷键?