Implement JNI "weak global" references.

The VM now supports the NewWeakGlobalRef and DeleteWeakGlobalRef calls,
which create a kind of weak reference that's directly visible to native
code.  While the JNI spec says that these can be used directly, the only
safe way to use them is to convert them to a strong local or global
reference first, so this is enforced.

The net result is very similar to manually creating a global reference to
a WeakReference object and manipulating it with method calls from native
code, but the JNI calls are faster and more convenient.
diff --git a/vm/alloc/MarkSweep.c b/vm/alloc/MarkSweep.c
index 4bb917b..634cfda 100644
--- a/vm/alloc/MarkSweep.c
+++ b/vm/alloc/MarkSweep.c
@@ -349,6 +349,7 @@
     dvmMarkObjectNonNull(gDvm.outOfMemoryObj);
     dvmMarkObjectNonNull(gDvm.internalErrorObj);
     dvmMarkObjectNonNull(gDvm.noClassDefFoundErrorObj);
+    dvmMarkObject(gDvm.jniWeakGlobalRefQueue);
 //TODO: scan object references sitting in gDvm;  use pointer begin & end
 
     HPROF_CLEAR_GC_SCAN_STATE();
@@ -861,7 +862,21 @@
                  * (The referent will be marked outside of this loop,
                  * after handing all references of this strength, in
                  * case multiple references point to the same object.)
+                 *
+                 * One exception: JNI "weak global" references are handled
+                 * as a special case.  They're identified by the queue.
                  */
+                if (gDvm.jniWeakGlobalRefQueue != NULL) {
+                    Object* queue = dvmGetFieldObject(reference,
+                            gDvm.offJavaLangRefReference_queue);
+                    if (queue == gDvm.jniWeakGlobalRefQueue) {
+                        LOGV("+++ WGR: clearing + not queueing %p:%p\n",
+                            reference, referent);
+                        schedClear = clearReference(reference);
+                        schedEnqueue = false;
+                        break;
+                    }
+                }
                 schedClear = false;
 
                 /* A PhantomReference is only useful with a
@@ -926,6 +941,9 @@
     /* Walk though the reference list again, and mark any non-clear/marked
      * referents.  Only PhantomReferences can have non-clear referents
      * at this point.
+     *
+     * (Could skip this for JNI weak globals, since we know they've been
+     * cleared.)
      */
     if (refType == REF_PHANTOM) {
         bool scanRequired = false;