/* * Called once to build the initial prepared class hash table. */ void classTrack_initialize() { JNIEnv *env = getEnv(); jint classCount; jclass *classes = allLoadedClasses(&classCount); jint i; if (classes == NULL) { ALLOC_ERROR_EXIT(); } table = jdwpClearedAlloc(HASH_SLOT_COUNT * sizeof(KlassNode *)); if (table == NULL) { jdwpFree(classes); ALLOC_ERROR_EXIT(); } for (i=0; i<classCount; i++) { jclass klass = classes[i]; /* Filter out unprepared classes (arrays may or * may not be marked as prepared) */ jboolean preped = (classStatus(klass) & JVMDI_CLASS_STATUS_PREPARED) != 0; if (preped || isArrayClass(klass)) { classTrack_addPreparedClass(env, klass); } (*env)->DeleteGlobalRef(env, klass); } jdwpFree(classes); }
/* * Called after class unloads have occurred. Creates a new hash table * of currently loaded prepared classes. * The signatures of classes which were unloaded (not present in the * new table) are returned. */ struct bag * classTrack_processUnloads(JNIEnv *env) { KlassNode **newTable = jdwpClearedAlloc(HASH_SLOT_COUNT * sizeof(KlassNode *)); jint classCount; jclass *classes; jint i; struct bag *unloadedSignatures; if (newTable == NULL) { ALLOC_ERROR_EXIT(); } if ((classes = allLoadedClasses(&classCount)) == NULL) { jdwpFree(newTable); ALLOC_ERROR_EXIT(); } /* Transfer each current class into the new table */ for (i=0; i<classCount; i++) { jclass klass = classes[i]; transferClass(env, klass, newTable); (*env)->DeleteGlobalRef(env, klass); } jdwpFree(classes); /* Delete old table, install new one */ unloadedSignatures = deleteTable(env, table); table = newTable; return unloadedSignatures; }
/* * Determine the component class by looking thru all classes for * one that has the signature of the component and the same class loadeer * as the array. See JVM spec 5.3.3: * If the component type is a reference type, C is marked as having * been defined by the defining class loader of the component type. */ static jdwpError getComponentClass(JNIEnv *env, jclass arrayClass, char *componentSignature, jclass *componentClassPtr) { jobject arrayClassLoader; jclass *classes; jint count; jclass componentClass = NULL; jdwpError serror; jvmtiError error; serror = JDWP_ERROR(NONE); error = classLoader(arrayClass, &arrayClassLoader); if (error != JVMTI_ERROR_NONE) { return map2jdwpError(error); } error = allLoadedClasses(&classes, &count); if (error != JVMTI_ERROR_NONE) { serror = map2jdwpError(error); } else { int i; for (i = 0; (i < count) && (componentClass == NULL); i++) { char *signature = NULL; jclass clazz = classes[i]; jboolean match; jvmtiError error; /* signature must match */ error = classSignature(clazz, &signature, NULL); if (error != JVMTI_ERROR_NONE) { serror = map2jdwpError(error); break; } match = strcmp(signature, componentSignature) == 0; jvmtiDeallocate(signature); /* if signature matches, get class loader to check if * it matches */ if (match) { jobject loader; error = classLoader(clazz, &loader); if (error != JVMTI_ERROR_NONE) { return map2jdwpError(error); } match = isSameObject(env, loader, arrayClassLoader); } if (match) { componentClass = clazz; } } jvmtiDeallocate(classes); *componentClassPtr = componentClass; } if (serror == JDWP_ERROR(NONE) && componentClass == NULL) { /* per JVM spec, component class is always loaded * before array class, so this should never occur. */ serror = JDWP_ERROR(NOT_FOUND); } return serror; }