예제 #1
0
/*
 * Adds a reference to the tail of a circular queue of references.
 */
static void enqueuePendingReference(Env* env, Object* ref, Object** list) {
    // This code is a port of the enqueuePendingReference() function in Android's MarkSweep.cpp
    if (*list == NULL) {
        // ref.pendingNext = ref
        rvmSetObjectInstanceFieldValue(env, ref, java_lang_ref_Reference_pendingNext, ref);
        *list = ref;
    } else {
        // head = list.pendingNext
        Object* head = rvmGetObjectInstanceFieldValue(env, *list, java_lang_ref_Reference_pendingNext);
        // ref.pendingNext = head
        rvmSetObjectInstanceFieldValue(env, ref, java_lang_ref_Reference_pendingNext, head);
        // list.pendingNext = ref
        rvmSetObjectInstanceFieldValue(env, *list, java_lang_ref_Reference_pendingNext, ref);
    }
}
예제 #2
0
/*
 * Removes the reference at the head of a circular queue of
 * references.
 */
static Object* dequeuePendingReference(Env* env, Object** list) {
    // This code is a port of the dequeuePendingReference() function in Android's MarkSweep.cpp
    assert(list != NULL);
    assert(*list != NULL);
    // head = list.pendingNext
    Object* head = rvmGetObjectInstanceFieldValue(env, *list, java_lang_ref_Reference_pendingNext);
    Object* ref;
    if (*list == head) {
        ref = *list;
        *list = NULL;
    } else {
        // next = head.pendingNext
        Object* next = rvmGetObjectInstanceFieldValue(env, head, java_lang_ref_Reference_pendingNext);
        // list.pendingNext = next
        rvmSetObjectInstanceFieldValue(env, *list, java_lang_ref_Reference_pendingNext, next);
        ref = head;
    }
    rvmSetObjectInstanceFieldValue(env, ref, java_lang_ref_Reference_pendingNext, NULL);
    return ref;
}
예제 #3
0
/*
 * Enqueues finalizer references with unreachable referents.  The
 * referent is moved to the zombie field (which makes it reachable again), 
 * and the referent field is cleared.
 */
static void enqueueFinalizerReferences(Env* env, Object** list, Object** cleared) {
    // This code is a port of the enqueueFinalizerReferences() function in Android's MarkSweep.cpp
    assert(list != NULL);
    while (*list != NULL) {
        Object* ref = dequeuePendingReference(env, list);
        Object* referent = rvmGetObjectInstanceFieldValue(env, ref, java_lang_ref_Reference_referent);
        if (referent != NULL) {
            /* If the referent is non-null the reference must queuable. */
            assert(isEnqueuable(env, ref));
            // Copy the referent to the zombie field
            rvmSetObjectInstanceFieldValue(env, ref, java_lang_ref_FinalizerReference_zombie, referent);
            // Clear the referent
            clearReference(env, ref);
            enqueueReference(env, ref, cleared);
        }
    }
    assert(*list == NULL);
}
예제 #4
0
/*
 * Clear the referent field.
 */
static void clearReference(Env* env, Object* reference) {
    // This code is a port of the clearReference() function in Android's MarkSweep.cpp
    rvmSetObjectInstanceFieldValue(env, reference, java_lang_ref_Reference_referent, NULL);
}
예제 #5
0
파일: attribute.c 프로젝트: Zubnix/aura
static jboolean getAnnotationValue(Env* env, void** attributes, Class* expectedAnnotationClass, Object* classLoader,
        jvalue* result, jboolean ignoreClassNotFound) {

    char* annotationTypeName = getString(attributes);
    if (expectedAnnotationClass && strncmp(&annotationTypeName[1], expectedAnnotationClass->name, strlen(expectedAnnotationClass->name))) {
        return throwFormatError(env, rvmFromBinaryClassName(env, expectedAnnotationClass->name));
    }

    Class* annotationClass = expectedAnnotationClass;
    if (!annotationClass) {
        annotationClass = rvmFindClassByDescriptor(env, annotationTypeName, classLoader);
        if (!annotationClass) {
            if (ignoreClassNotFound && rvmExceptionOccurred(env)->clazz == java_lang_ClassNotFoundException) {
                rvmExceptionClear(env);
                jint length = getInt(attributes);
                for (jint i = 0; i < length; i++) {
                    getString(attributes);
                    skipElementValue(attributes);
                }
            }
            return FALSE;
        }
    }

    // Find the annotation impl class
    Class* annotationImplClass = findAnnotationImplClass(env, annotationClass, classLoader);
    if (rvmExceptionCheck(env)) return FALSE;

    jint length = getInt(attributes);
    if (length == 0) {
        // No member values specified. Use a singleton instance.
        Method* factoryMethod = rvmGetClassMethod(env, annotationImplClass, "$createSingleton", "()Ljava/lang/Object;");
        if (rvmExceptionCheck(env)) return FALSE;
        Object* annotationObject = rvmCallObjectClassMethod(env, annotationImplClass, factoryMethod);
        if (rvmExceptionCheck(env)) return FALSE;
        result->l = (jobject) annotationObject;
        return TRUE;
    }

    // Call the annotation impl $create() method
    Method* factoryMethod = rvmGetClassMethod(env, annotationImplClass, "$create", "()Ljava/lang/Object;");
    if (rvmExceptionCheck(env)) return FALSE;
    Object* annotationObject = rvmCallObjectClassMethod(env, annotationImplClass, factoryMethod);
    if (rvmExceptionCheck(env)) return FALSE;

    jint i = 0;
    for (i = 0; i < length; i++) {
        char* name = getString(attributes);
        Method* method = getAnnotationValueMethod(env, annotationClass, name);
        if (rvmExceptionCheck(env)) return FALSE;
        if (!method) {
            skipElementValue(attributes);
        } else {
            const char* memberDesc = rvmGetReturnType(method->desc);
            Class* type = findType(env, memberDesc, method->clazz->classLoader);
            Object* value = NULL;
            if (!type) {
                value = rvmExceptionClear(env);
            } else {
                jvalue v = {0};
                if (!parseElementValue(env, attributes, type, classLoader, &v)) {
                    value = rvmExceptionClear(env);
                } else {
                    value = rvmBox(env, type, &v);
                }
            }

            InstanceField* field = getAnnotationMemberField(env, annotationImplClass, method->name);
            if (!field) return FALSE;

            rvmSetObjectInstanceFieldValue(env, annotationObject, field, value);
            if (rvmExceptionCheck(env)) return FALSE;
        }
    }

    result->l = (jobject) annotationObject;
    return TRUE;
}
예제 #6
0
static void SetObjectField(JNIEnv* env, jobject obj, jfieldID fieldID, jobject val) {
    rvmSetObjectInstanceFieldValue((Env*) env, (Object*) obj, (InstanceField*) fieldID, (Object*) val);
}