jvmtienv.c
来自「This is a resource based on j2me embedde」· C语言 代码 · 共 2,229 行 · 第 1/5 页
C
2,229 行
"JVMTI_ERROR_NO_MORE_FRAMES", "JVMTI_ERROR_OPAQUE_FRAME", NULL, "JVMTI_ERROR_TYPE_MISMATCH", "JVMTI_ERROR_INVALID_SLOT", NULL, NULL, NULL, NULL, "JVMTI_ERROR_DUPLICATE", "JVMTI_ERROR_NOT_FOUND", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "JVMTI_ERROR_INVALID_MONITOR", "JVMTI_ERROR_NOT_MONITOR_OWNER", "JVMTI_ERROR_INTERRUPT", NULL, NULL, NULL, NULL, NULL, NULL, NULL, "JVMTI_ERROR_INVALID_CLASS_FORMAT", "JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION", "JVMTI_ERROR_FAILS_VERIFICATION", "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED", "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED", "JVMTI_ERROR_INVALID_TYPESTATE", "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED", "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED", "JVMTI_ERROR_UNSUPPORTED_VERSION", "JVMTI_ERROR_NAMES_DONT_MATCH", "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED", "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED", NULL, NULL, NULL, NULL, NULL, NULL, NULL, "JVMTI_ERROR_UNMODIFIABLE_CLASS", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "JVMTI_ERROR_NOT_AVAILABLE", "JVMTI_ERROR_MUST_POSSESS_CAPABILITY", "JVMTI_ERROR_NULL_POINTER", "JVMTI_ERROR_ABSENT_INFORMATION", "JVMTI_ERROR_INVALID_EVENT_TYPE", "JVMTI_ERROR_ILLEGAL_ARGUMENT", "JVMTI_ERROR_NATIVE_METHOD", NULL, "JVMTI_ERROR_CLASS_LOADER_UNSUPPORTED", NULL, NULL, NULL, "JVMTI_ERROR_OUT_OF_MEMORY", "JVMTI_ERROR_ACCESS_DENIED", "JVMTI_ERROR_WRONG_PHASE", "JVMTI_ERROR_INTERNAL", NULL, "JVMTI_ERROR_UNATTACHED_THREAD", "JVMTI_ERROR_INVALID_ENVIRONMENT"};#if 0 /* Unused. TODO: remove if still unused later. *//* Event threaded */const jboolean JvmtiEventThreaded[] ={ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0};#endif /* TODO */static CVMJvmtiContext *CVMjvmtiCreateContext();/* mlam :: REVIEW DONE *//* TODO: Change to not rely on 64bit masking if possible. At least change to us HPI long functions. */static const jlong GLOBAL_EVENT_BITS = ~THREAD_FILTERED_EVENT_BITS;static CVMBool jvmtiIsGCOwner;CVMBoolCVMjvmtiIsGCOwner() { return jvmtiIsGCOwner;}voidCVMjvmtiSetGCOwner(CVMBool jvmtiGCOwner) { CVMassert(jvmtiIsGCOwner != jvmtiGCOwner); jvmtiIsGCOwner = jvmtiGCOwner;}/* * Threads *//* CVMjvmti...ICellDirect() macros =============================== The ICellDirect macros (defined further down below) are used to get/set direct object pointers from/to icells/refs. CVMjvmtiGetICellDirect() is analogous to CVMID_icellGetDirect(). CVMjvmtiSetICellDirect() is analogous to CVMID_icellSetDirect(). CVMjvmtiAssignICellDirect() is analogous to CVMID_icellAssignDirect(). Unlike their similarly named counterparts in indirectmem.h, this version of these macros allow direct handling of the object pointers under any of these conditions: 1. the current thread is in a GC unsafe state, or 2. the VM is in a GC safe all state that is requested by the current thread, or 3. the current thread owns the heapLock. If any of these conditions are true, then the current thread will be able to handle direct object pointers of fearing complications with the GC. The above condition expresses a "safe to access direct object" state (as captured in the CVMjvmtiIsSafeToAccessDirectObject() macro) which basically says that it is safe to handle direct object pointers while the current thread is in this state. Note: these macros need to be used in place of their indirectmem.h counterparts when the current thread is in a region protected by the STOP/RESUME_STACK_MUTATION pair. This is because a GC safe all state may be used to stop stack mutation. In a GC safe all state, the current thread is not allowed to become GC unsafe (which is needed by the indirectmem.h macros). Hence, we'll need to use these macros instead.*//* Purpose: Checks to see if the VM has reached a safe all state requested by the current thread. ee is the ee for the current thread. Note: in order for the VM to reached a safe all state, the current thread, being the requester, must have first acquire certain necessary sys mutexes. These locks also prevents GC from running. Hence, it is safe for us to do direct object accesses without becoming GC unsafe. In fact, the current thread is forbidden from becoming GC unsafe while we are in a safe all state.*//* mlam :: REVIEW DONE *//* Purpose: Gets the cb pointer from the class object. */CVMClassBlock *CVMjvmtiGetObjectCB(CVMExecEnv *ee, jobject obj){ CVMClassBlock *cb = NULL; if (obj != NULL) { /* If we requested safety then don't do the gcUnsafeExec as * we'll hit an assertion. We requested the safeall so we * can access objects directly. */ if (CVMgcIsGCThread(ee)) { CVMObject* directObj = CVMjvmtiGetICellDirect(ee, obj); cb = CVMobjectGetClass(directObj); } else { CVMD_gcUnsafeExec(ee, { CVMObject* directObj = CVMID_icellDirect(ee, obj); cb = CVMobjectGetClass(directObj); }); } } return cb;}#define THREAD_ID_OK(thread) \ { \ CVMClassBlock *__cb__ = CVMjvmtiGetObjectCB(ee, thread); \ if (__cb__ != CVMsystemClass(java_lang_Thread) && \ !CVMisSubclassOf(ee, __cb__, CVMsystemClass(java_lang_Thread))) { \ return JVMTI_ERROR_INVALID_THREAD; \ } \ }/* mlam :: REVIEW DONE *//* Small utility function to read the eetop field from the Thread object. This function doesn't do any error checking. It's assumed that the caller will do all necessary checks before call this function.*/static CVMExecEnv *getThreadEETopField(CVMExecEnv *ee, jthread thread){ CVMExecEnv *targetEE; CVMJavaLong eetop; CVMextraAssert(CVMD_isgcSafe(ee)); CVMextraAssert(thread != NULL); CVMextraAssert(!CVMID_icellIsNull(thread)); if (CVMjvmtiIsSafeToAccessDirectObject(ee)) { /* We're in a safe all state requested by the current thread. Hence, cannot and do not need to become unsafe in order to access the field. */ CVMObject *threadObj = CVMjvmtiGetICellDirect(ee, thread); CVMD_fieldReadLong(threadObj, CVMoffsetOfjava_lang_Thread_eetop, eetop); } else { /* Else, access the field the normal way: */ CVMID_fieldReadLong(ee, (CVMObjectICell*) thread, CVMoffsetOfjava_lang_Thread_eetop, eetop); } targetEE = (CVMExecEnv*)CVMlong2VoidPtr(eetop); return targetEE;}/* mlam :: REVIEW DONE */static CVMBoolgetThreadHasRunOnceField(CVMExecEnv *ee, jthread thread){ CVMJavaInt hasRunOnce; CVMextraAssert(CVMD_isgcSafe(ee)); CVMextraAssert(thread != NULL); CVMextraAssert(!CVMID_icellIsNull(thread)); if (CVMjvmtiIsSafeToAccessDirectObject(ee)) { /* We're in a safe all state requested by the current thread. Hence, cannot and do not need to become unsafe in order to access the field. */ CVMObject *threadObj = CVMjvmtiGetICellDirect(ee, thread); CVMD_fieldReadInt(threadObj, CVMoffsetOfjava_lang_Thread_hasStartedOnce, hasRunOnce); } else { /* Else, access the field the normal way: */ CVMID_fieldReadInt(ee, (CVMObjectICell*) thread, CVMoffsetOfjava_lang_Thread_hasStartedOnce, hasRunOnce); } return (CVMBool)hasRunOnce;}/* mlam :: REVIEW DONE *//* Purpose: Gets the ee pointer from the jthread object. */static jvmtiErrorjthreadToExecEnv(CVMExecEnv *ee, jthread thread, CVMExecEnv **targetEE){ CVMassert(ee == CVMgetEE()); CVMassert(targetEE != NULL); CVMassert(CVMD_isgcSafe(ee)); /* JVMTI may pass in a NULL jthread as an indicator that the target thread of interest is the current thread. */ if (thread == NULL) { *targetEE = ee; return JVMTI_ERROR_NONE; } if (CVMID_icellIsNull(thread)) { return JVMTI_ERROR_INVALID_THREAD; } /* Make sure that object passed in is in fact a Thread */ THREAD_ID_OK(thread); *targetEE = getThreadEETopField(ee, thread); if (*targetEE == NULL) { return JVMTI_ERROR_THREAD_NOT_ALIVE; } return JVMTI_ERROR_NONE;}/* mlam :: REVIEW DONE *//* * clean up breakpoint - doesn't actually remove it. * lock must be held */static CVMBoolclearBkpt(CVMExecEnv *ee, struct bkpt *bp){ JNIEnv *env = CVMexecEnv2JniEnv(ee); CVMassert(*(bp->pc) == opc_breakpoint); CVMassert(CVMsysMutexIAmOwner(ee, &CVMglobals.jvmtiLock)); /* TODO: Do we need the CODE_LOCK here? Check interplay of CODE_LOCK and jvmtiLock. */ *(bp->pc) = (CVMUint8)(bp->opcode);#ifdef CVM_HW CVMhwFlushCache(bp->pc, bp->pc + 1);#endif /* * De-reference the enclosing class so that it's GC * is no longer prevented by this breakpoint. */ (*env)->DeleteGlobalRef(env, bp->classRef);#ifdef CVM_DEBUG bp->classRef = NULL;#endif return CVM_TRUE;}/* Purpose: Gets the ClassBlock from the specified java.lang.Class ref. See also CVMjvmtiClassObject2ClassBlock() in jvmtiEnv.h. CVMjvmtiClassObject2ClassBlock() takes a direct class object as input while CVMjvmtiClassRef2ClassBlock() takes a class ref i.e. jclass.*/CVMClassBlock *CVMjvmtiClassRef2ClassBlock(CVMExecEnv *ee, jclass clazz){ CVMClassBlock *cb = NULL; CVMassert(CVMD_isgcSafe(ee)); if (clazz == NULL) { return cb; }#ifdef CVM_DEBUG_ASSERTS /* The ref must point to an instance of java.lang.Class: */ CVMD_gcUnsafeExec(ee, { CVMClassBlock *ccb; CVMObject* directObj = CVMID_icellDirect(ee, clazz); ccb = CVMobjectGetClass(directObj); CVMassert(ccb == CVMsystemClass(java_lang_Class)); });#endif CVMD_gcUnsafeExec(ee, { cb = CVMgcUnsafeClassRef2ClassBlock(ee, clazz); }); return cb;}/* * Capability functions */ /* mlam :: REVIEW DONE */static jvmtiCapabilities *getCapabilities(CVMJvmtiContext *context){ return &context->currentCapabilities;}/* mlam :: REVIEW DONE */static jvmtiCapabilities *getProhibitedCapabilities(CVMJvmtiContext *context){ return &context->prohibitedCapabilities;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?