/*
 * 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;
}
Beispiel #3
0
/*
 * 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;
}