jvm.c

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

C
2,294
字号
	    lineno = -1;#endif	}		CVMD_arrayWriteInt(pcArray, count, (CVMJavaInt)			   ((lineno << 16) |			    (CVMmbMethodIndex(mb) & 0xffff)));	/* Write the class object into the backtrace array. */	{	    CVMClassICell* classICell = 		CVMcbJavaInstance(CVMmbClassBlock(mb));	    CVMD_arrayWriteRef(backtrace, count + 2, 			       CVMID_icellDirect(ee, classICell));	}	count++;    }     CVMassert(count + 2 == CVMD_arrayGetLength(backtrace));#endif}#ifndef CDC_10static CVMInt32 CVMgetStackTraceDepth(CVMExecEnv *ee,                                      CVMThrowableICell* throwableICell){#ifdef CVM_DEBUG_STACKTRACES    CVMInt32 stackDepth = 0;    if (CVMID_icellIsNull(throwableICell)) {        CVMthrowNullPointerException(ee, NULL);        return 0;    }    CVMID_localrootBegin(ee) {        CVMID_localrootDeclare(CVMObjectICell, backtraceICell);                CVMID_fieldReadRef(ee, throwableICell,                           CVMoffsetOfjava_lang_Throwable_backtrace,                           backtraceICell);        if (!CVMID_icellIsNull(backtraceICell)) {            CVMID_arrayGetLength(ee, (CVMArrayOfRefICell*)backtraceICell,                                 stackDepth);            /* The first two elements of the backtrace array are pcValue             * array and isCompiled array. So need to subtract the size             * by 2 */            stackDepth -= 2;        }    } CVMID_localrootEnd();    return stackDepth;#else    return 0;#endif}JNIEXPORT jint JNICALLJVM_GetStackTraceDepth(JNIEnv *env, jobject throwable) {    CVMExecEnv* ee = CVMjniEnv2ExecEnv(env);    return CVMgetStackTraceDepth(ee, throwable);}#ifdef CVM_DEBUG_STACKTRACESstatic CVMObjectICell* CVMgetStackTraceElement(CVMExecEnv *ee,             CVMThrowableICell* throwableICell, CVMInt32 index){    CVMObjectICell* stElementICell;    CVMJavaInt backtraceLen;    CVMJavaInt linenoInfo, lineno;    CVMClassBlock* cb;    CVMMethodBlock* mb;    CVMMethodTypeID tid;    char buf[256];    const char* fn;    const CVMClassBlock* stackTraceElementCb;    CVMJavaBoolean isCompiled = CVM_FALSE;    if (CVMID_icellIsNull(throwableICell)) {        CVMthrowNullPointerException(ee, NULL);        return NULL;    }    stElementICell = CVMjniCreateLocalRef(ee);    CVMID_localrootBegin(ee) {        CVMID_localrootDeclare(CVMArrayOfRefICell, backtraceICell);#ifdef CVM_JIT        CVMID_localrootDeclare(CVMArrayOfBooleanICell, isCompiledArrayICell);#endif        CVMID_localrootDeclare(CVMArrayOfIntICell, pcArrayICell);        CVMID_localrootDeclare(CVMObjectICell, tempICell);        CVMID_localrootDeclare(CVMStringICell, stringICell);        /* Get 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 failed_goto_localRootEnd;        }        CVMID_arrayGetLength(ee, backtraceICell, backtraceLen);        if (index >= backtraceLen - 2) {            CVMthrowArrayIndexOutOfBoundsException(ee, NULL);            goto failed_goto_localRootEnd;        }        /* Now allocate a new java.lang.StackTraceElement object */        stackTraceElementCb = CVMsystemClass(java_lang_StackTraceElement);        CVMID_allocNewInstance(ee, (CVMClassBlock*)stackTraceElementCb,                               stElementICell);        if (CVMID_icellIsNull(stElementICell)) {            CVMthrowOutOfMemoryError(ee, NULL);            goto failed_goto_localRootEnd;        }        /* The first element of the backtrace array is an array of          * method index and lineno info:         *          *     lineno << 16 | methodIndex         *         */        CVMID_arrayReadRef(ee, backtraceICell, 0, tempICell);        CVMID_icellAssign(ee, pcArrayICell,                          (CVMArrayOfIntICell*)tempICell);        if (CVMID_icellIsNull(pcArrayICell)) {            goto failed_goto_localRootEnd;        }        CVMID_arrayReadInt(ee, pcArrayICell, index, linenoInfo);#ifdef CVM_JIT        /* The 2nd element of the backtrace array is an array of          * isCompiled values. */        CVMID_arrayReadRef(ee, backtraceICell, 1, tempICell);        CVMID_icellAssign(ee, isCompiledArrayICell,                          (CVMArrayOfBooleanICell*)tempICell);        if (CVMID_icellIsNull(isCompiledArrayICell)) {            goto failed_goto_localRootEnd;        }        CVMID_arrayReadBoolean(ee, isCompiledArrayICell, index, isCompiled);#endif        /* Get the indexed backtrace element. It's java.lang.Class         * object. */        CVMID_arrayReadRef(ee, backtraceICell, index+2, tempICell);        if (CVMID_icellIsNull(tempICell)) {            goto failed_goto_localRootEnd;        }            cb = CVMgcSafeClassRef2ClassBlock(ee, tempICell);        mb = CVMcbMethodSlot(cb, ((CVMUint32)linenoInfo & 0xffff));        lineno = linenoInfo >> 16;        tid = CVMmbNameAndTypeID(mb);        /* Fill in the fields */        /* Fill in the declaringClass field */        CVMclassname2String(CVMcbClassName(cb), buf, sizeof(buf));        CVMnewStringUTF(ee, stringICell, buf);        CVMID_fieldWriteRef(ee, stElementICell,            CVMoffsetOfjava_lang_StackTraceElement_declaringClass,            stringICell);        /* Fill in the methodName field */        CVMtypeidMethodNameToCString(tid, buf, sizeof(buf));        CVMnewStringUTF(ee, stringICell, buf);        CVMID_fieldWriteRef(ee, stElementICell,            CVMoffsetOfjava_lang_StackTraceElement_methodName,            stringICell);        /* Fill in the fileName field */        fn = getSourceFileName(cb);        if (fn != NULL) {            CVMnewStringUTF(ee, stringICell, fn);            CVMID_fieldWriteRef(ee, stElementICell,                CVMoffsetOfjava_lang_StackTraceElement_fileName,                stringICell);        }        /* Fill in the lineNumber field */        CVMID_fieldWriteInt(ee, stElementICell,            CVMoffsetOfjava_lang_StackTraceElement_lineNumber,            lineno);        /* Fill in the isCompiled field */        CVMID_fieldWriteInt(ee, stElementICell,	    CVMoffsetOfjava_lang_StackTraceElement_isCompiled,	    isCompiled);#ifdef CVM_DEBUG        /* Fill in the methodSignature field for debug builds. For non-debug         * leave the field as null.         */        CVMtypeidMethodTypeToCString(tid, buf, sizeof(buf));        CVMnewStringUTF(ee, stringICell, buf);        CVMID_fieldWriteRef(ee, stElementICell,	    CVMoffsetOfjava_lang_StackTraceElement_methodSignature,	    stringICell);#endiffailed_goto_localRootEnd:;    } CVMID_localrootEnd();    return stElementICell;}#endifJNIEXPORT jobject JNICALLJVM_GetStackTraceElement(JNIEnv *env, jobject throwable, jint index) {#ifdef CVM_DEBUG_STACKTRACES    CVMExecEnv* ee = CVMjniEnv2ExecEnv(env);    return (jobject)CVMgetStackTraceElement(ee, throwable,                                            (CVMInt32)index);#else    return NULL;#endif}#endif /* !CDC_10 *//* Called from object.c */JNIEXPORT jint JNICALLJVM_IHashCode(JNIEnv *env, jobject obj){    if (obj == NULL) {	return 0;    }    return CVMobjectGetHashSafe(CVMjniEnv2ExecEnv(env), obj);}JNIEXPORT void JNICALLJVM_MonitorWait(JNIEnv *env, jobject obj, jlong millis){    CVMExecEnv *ee = CVMjniEnv2ExecEnv(env);    if (CVMlongLtz(millis)) {	CVMthrowIllegalArgumentException(ee, "timeout value is negative");        return;    }#ifdef CVM_JVMPI    if (CVMjvmpiEventMonitorWaitIsEnabled()) {        CVMjvmpiPostMonitorWaitEvent(ee, obj, millis);    }#endif#ifdef CVM_JVMTI    ee->threadState = CVM_THREAD_WAITING | CVM_THREAD_OBJECT_WAIT;    ee->threadState |= (millis == 0 ? CVM_THREAD_WAITING_INDEFINITE :		       CVM_THREAD_WAITING_TIMEOUT);    if (CVMjvmtiShouldPostMonitorWait()) {        CVMjvmtiPostMonitorWaitEvent(ee, obj, millis);    }#endif    /* NOTE: CVMgcSafeObjectWait() may throw certain exceptions: */    CVMgcSafeObjectWait(ee, obj, millis);#ifdef CVM_JVMPI    if (CVMjvmpiEventMonitorWaitedIsEnabled()) {        CVMjvmpiPostMonitorWaitedEvent(ee, obj);    }#endif#ifdef CVM_JVMTI    if (CVMjvmtiShouldPostMonitorWaited()) {        CVMjvmtiPostMonitorWaitedEvent(ee, obj, CVM_FALSE);    }#endif}JNIEXPORT void JNICALLJVM_MonitorNotify(JNIEnv *env, jobject obj){    CVMExecEnv *ee = CVMjniEnv2ExecEnv(env);#ifdef CVM_JVMTI    ee->threadState &= ~(CVM_THREAD_WAITING | CVM_THREAD_WAITING_INDEFINITE |			 CVM_THREAD_WAITING_TIMEOUT);#endif    /* NOTE: CVMgcSafeObjectNotify() may throw certain exceptions: */    CVMgcSafeObjectNotify(ee, obj);}JNIEXPORT void JNICALLJVM_MonitorNotifyAll(JNIEnv *env, jobject obj){    CVMExecEnv *ee = CVMjniEnv2ExecEnv(env);#ifdef CVM_JVMTI    CVMsysMutexLock(ee, &CVMglobals.threadLock);    CVM_WALK_ALL_THREADS(ee, currentEE, {	    CVMassert(CVMcurrentThreadICell(currentEE) != NULL);	    if (!CVMID_icellIsNull(CVMcurrentThreadICell(currentEE))) {		currentEE->threadState &=  ~(CVM_THREAD_WAITING |					     CVM_THREAD_WAITING_INDEFINITE |					     CVM_THREAD_WAITING_TIMEOUT);	    }	});    CVMsysMutexUnlock(ee, &CVMglobals.threadLock);#endif    /* NOTE: CVMgcSafeObjectNotifyAll() may throw certain exceptions: */    CVMgcSafeObjectNotifyAll(ee, obj);}JNIEXPORT jobject JNICALLJVM_Clone(JNIEnv *env, jobject obj){    CVMClassBlock*  cb;    CVMExecEnv* ee = CVMjniEnv2ExecEnv(env);    jobject result;    CVMID_localrootBegin(ee) {	CVMID_localrootDeclare(CVMObjectICell, cloneObj);	CVMID_objectGetClass(ee, obj, cb);	/*	 * Now let's see whether we are cloning an array or an object	 */	if (CVMisArrayClass(cb)) {	    CVMArrayOfAnyTypeICell* arrObj = (CVMArrayOfAnyTypeICell*)obj;	    CVMBasicType typeCode = CVMarrayElemTypeCode(cb);	    CVMJavaInt   arrLen;	    CVMID_arrayGetLength(ee, arrObj, arrLen);	    /* Make the copy first */	    CVMID_allocNewArray(ee, typeCode, cb, arrLen, cloneObj);	    if (CVMID_icellIsNull(cloneObj)) {		/* Allocation failed */		result = NULL;		CVMthrowOutOfMemoryError(ee, "cloning array object");		goto bailOut;	    }	    JVM_ArrayCopy(env, NULL, obj, 0, cloneObj, 0, arrLen);	} else {	    if (!CVMimplementsInterface(ee, cb,				    CVMsystemClass(java_lang_Cloneable))) {		result = NULL;		if (!CVMlocalExceptionOccurred(ee)) {		   CVMthrowCloneNotSupportedException(ee,						   "cloning regular object");		}		goto bailOut;	    }	    CVMID_allocNewInstance(ee, cb, cloneObj);	    if (CVMID_icellIsNull(cloneObj)) {		/* Allocation failed */		result = NULL;		CVMthrowOutOfMemoryError(ee, "cloning regular object");		goto bailOut;	    }	    CVMD_gcUnsafeExec(ee, {		CVMObject* srcObj = CVMID_icellDirect(ee, obj);		CVMObject* dstObj = CVMID_icellDirect(ee, cloneObj);		CVMClassBlock* cbp;		CVMwithAssertsOnly(		    CVMUint32 coveredSize = sizeof(CVMObjectHeader);		);				/*		 * Walk all instance fields in superclass order,		 * and copy each with the right CVMD_ call.		 */		for (cbp = cb; cbp != NULL; cbp = CVMcbSuperclass(cbp)) {		    CVMUint32 i;		    /*		     * Go through the declared fields		     */		    for (i = 0; i < CVMcbFieldCount(cbp); i++) {			CVMFieldBlock* fb = CVMcbFieldSlot(cbp, i);			if (!CVMfbIs(fb, STATIC)) {			    CVMUint32 offset = CVMfbOffset(fb);			    CVMClassTypeID type =				CVMtypeidGetType(CVMfbNameAndTypeID(fb));			    switch (type) {				case CVM_TYPEID_INT:				case CVM_TYPEID_SHORT:				case CVM_TYPEID_CHAR:				case CVM_TYPEID_BYTE:			        case CVM_TYPEID_BOOLEAN: {				    CVMJavaInt elem;				    CVMD_fieldReadInt(srcObj, offset, elem);				    CVMD_fieldWriteInt(dstObj, offset, elem);				    CVMwithAssertsOnly(				        coveredSize += sizeof(CVMJavaInt);				    );				    break;				}			        case CVM_TYPEID_LONG: {				    CVMJavaLong l;				    CVMD_fieldReadLong(srcObj, offset, l);				    CVMD_fieldWriteLong(dstObj, offset, l);				    CVMwithAssertsOnly(				        coveredSize += sizeof(CVMJavaLong);				    );				    break;				}			        case CVM_TYPEID_DOUBLE: {				    CVMJavaDouble d;				    CVMD_fieldReadDouble(srcObj, offset, d);				    CVMD_fieldWriteDouble(dstObj, offset, d);				    CVMwithAssertsOnly(				        coveredSize += sizeof(CVMJavaDouble);				    );				    break;				}			        case CVM_TYPEID_FLOAT: {				    CVMJavaFloat f;				    CVMD_fieldReadFloat(srcObj, offset, f);				    CVMD_fieldWriteFloat(dstObj, offset, f);				    CVMwithAssertsOnly(				        coveredSize += sizeof(CVMJavaFloat);				    );				    break;				}			        default: /* Must be a ref */ {				    CVMObject* o;				    CVMD_fieldReadRef(srcObj, offset, o);				    CVMD_fieldWriteRef(dstObj, offset, o);				    CVMwithAssertsOnly(				        coveredSize += sizeof(CVMObject*);				    );				    break;				}			    }			}		    }		}		/*		 * Now make sure that we have copied just the right		 * number of bytes from one object to the other		 */		/* 		 * NOTE: the assert makes only sense if all the sizeof() above		 * are multiples of CVMJavaVal32.		 * For a 64 bit port this might not make sense.		 * Leave the assert in for now, until a 64-bit port makes		 * us modify it.		 */		CVMassert(coveredSize == CVMcbInstanceSize(cb));	    });	}	result = (*env)->NewLocalRef(env, cloneObj);    bailOut:;    } CVMID_localrootEnd();    return result;}/* * Thread class calls */typedef struct {    void (*nativeFunc)(void *);    void *nativeFuncArg;} CVMNativeRunInfo;#ifdef CVM_DEBUG_ASSERTSenum {    NATIVERUNINFO_UNDEFINED = 0,    NATIVERUNINFO_THREAD_START_INFO,    NATIVERUNINFO_NATIVE_RUN_INFO,};#endif

⌨️ 快捷键说明

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