Ejemplo n.º 1
0
/*
 * Returns true if the reference was registered with a reference queue
 * and has not yet been enqueued.
 */
static jboolean isEnqueuable(Env* env, Object* reference) {
    // This code is a port of the isEnqueuable() function in Android's MarkSweep.cpp
    assert(reference != NULL);
    Object* queue = rvmGetObjectInstanceFieldValue(env, reference, java_lang_ref_Reference_queue);
    Object* queueNext = rvmGetObjectInstanceFieldValue(env, reference, java_lang_ref_Reference_queueNext);
    return (queue != NULL && queueNext == NULL) ? TRUE : FALSE;
}
Ejemplo n.º 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;
}
Ejemplo n.º 3
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);
    }
}
Ejemplo n.º 4
0
/*
 * Unlink the reference list clearing references objects with unreachable
 * referents.  Cleared references registered to a reference queue are
 * enqueued on the cleared list.
 */
static void clearAndEnqueueReferences(Env* env, Object** list, Object** cleared) {
    // This code is a port of the clearWhiteReferences() function in Android's MarkSweep.cpp
    assert(list != NULL);
    assert(cleared != NULL);
    while (*list != NULL) {
        Object* ref = dequeuePendingReference(env, list);
        Object* referent = rvmGetObjectInstanceFieldValue(env, ref, java_lang_ref_Reference_referent);
        if (referent != NULL) {
            clearReference(env, ref);
            if (isEnqueuable(env, ref)) {
                enqueueReference(env, ref, cleared);
            }
        }
    }
    assert(*list == NULL);
}
Ejemplo n.º 5
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);
}
Ejemplo n.º 6
0
static jobject GetObjectField(JNIEnv* env, jobject obj, jfieldID fieldID) {
    return (jobject) rvmGetObjectInstanceFieldValue((Env*) env, (Object*) obj, (InstanceField*) fieldID);
}