/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * Dalvik implementation of JNI interfaces.
 */
#include "Dalvik.h"
#include "JniInternal.h"

#include <stdlib.h>
#include <stdarg.h>
#include <limits.h>

/*
Native methods and interaction with the GC

All JNI methods must start by changing their thread status to
THREAD_RUNNING, and finish by changing it back to THREAD_NATIVE before
returning to native code.  The switch to "running" triggers a thread
suspension check.

With a rudimentary GC we should be able to skip the status change for
simple functions, e.g.  IsSameObject, GetJavaVM, GetStringLength, maybe
even access to fields with primitive types.  Our options are more limited
with a compacting GC, so we should replace JNI_ENTER with JNI_ENTER_NCGC
or somesuch on the "lite" functions if we want to try this optimization.

For performance reasons we do as little error-checking as possible here.
For example, we don't check to make sure the correct type of Object is
passed in when setting a field, and we don't prevent you from storing
new values in a "final" field.  Such things are best handled in the
"check" version.  For actions that are common, dangerous, and must be
checked at runtime, such as array bounds checks, we do the tests here.


General notes on local/global reference tracking

JNI provides explicit control over natively-held references that the GC
needs to know about.  These can be local, in which case they're released
when the native method returns into the VM, or global, which are held
until explicitly released.  (There are also weak-global references,
which have the lifespan and visibility of global references, but the
object they refer to may be collected.)

The references can be created with explicit JNI NewLocalRef / NewGlobalRef
calls.  The former is very unusual, the latter is reasonably common
(e.g. for caching references to class objects).

Local references are most often created as a side-effect of JNI functions.
For example, the AllocObject/NewObject functions must create local
references to the objects returned, because nothing else in the GC root
set has a reference to the new objects.

The most common mode of operation is for a method to create zero or
more local references and return.  Explicit "local delete" operations
are expected to be exceedingly rare, except when walking through an
object array, and the Push/PopLocalFrame calls are expected to be used
infrequently.  For efficient operation, we want to add new local refs
with a simple store/increment operation; to avoid infinite growth in
pathological situations, we need to reclaim the space used by deleted
entries.

If we just want to maintain a list for the GC root set, we can use an
expanding append-only array that compacts when objects are deleted.
In typical situations, e.g. running through an array of objects, we will
be deleting one of the most recently added entries, so we can minimize
the number of elements moved (or avoid having to move any).

If we want to conceal the pointer values from native code, which is
necessary to allow the GC to move JNI-referenced objects around, then we
have to use a more complicated indirection mechanism.

The spec says, "Local references are only valid in the thread in which
they are created.  The native code must not pass local references from
one thread to another."


Pinned objects

For some large chunks of data, notably primitive arrays and String data,
JNI allows the VM to choose whether it wants to pin the array object or
make a copy.  We currently pin the memory for better execution performance.

TODO: we're using simple root set references to pin primitive array data,
because they have the property we need (i.e. the pointer we return is
guaranteed valid until we explicitly release it).  However, if we have a
compacting GC and don't want to pin all memory held by all global refs,
we need to treat these differently.


Global reference tracking

There should be a small "active" set centered around the most-recently
added items.

Because it's global, access to it has to be synchronized.  Additions and
removals require grabbing a mutex.  If the table serves as an indirection
mechanism (i.e. it's not just a list for the benefit of the garbage
collector), reference lookups may also require grabbing a mutex.

The JNI spec does not define any sort of limit, so the list must be able
to expand to a reasonable size.  It may be useful to log significant
increases in usage to help identify resource leaks.


Weak-global reference tracking

[TBD]


Local reference tracking

The table of local references can be stored on the interpreted stack or
in a parallel data structure (one per thread).

*** Approach #1: use the interpreted stack

The easiest place to tuck it is between the frame ptr and the first saved
register, which is always in0.  (See the ASCII art in Stack.h.)  We can
shift the "VM-specific goop" and frame ptr down, effectively inserting
the JNI local refs in the space normally occupied by local variables.

(Three things are accessed from the frame pointer:
 (1) framePtr[N] is register vN, used to get at "ins" and "locals".
 (2) framePtr - sizeof(StackSaveArea) is the VM frame goop.
 (3) framePtr - sizeof(StackSaveArea) - numOuts is where the "outs" go.
The only thing that isn't determined by an offset from the current FP
is the previous frame.  However, tucking things below the previous frame
can be problematic because the "outs" of the previous frame overlap with
the "ins" of the current frame.  If the "ins" are altered they must be
restored before we return.  For a native method call, the easiest and
safest thing to disrupt is #1, because there are no locals and the "ins"
are all copied to the native stack.)

We can implement Push/PopLocalFrame with the existing stack frame calls,
making sure we copy some goop from the previous frame (notably the method
ptr, so that dvmGetCurrentJNIMethod() doesn't require extra effort).

We can pre-allocate the storage at the time the stack frame is first
set up, but we have to be careful.  When calling from interpreted code
the frame ptr points directly at the arguments we're passing, but we can
offset the args pointer when calling the native bridge.

To manage the local ref collection, we need to be able to find three
things: (1) the start of the region, (2) the end of the region, and (3)
the next available entry.  The last is only required for quick adds.
We currently have two easily-accessible pointers, the current FP and the
previous frame's FP.  (The "stack pointer" shown in the ASCII art doesn't
actually exist in the interpreted world.)

We can't use the current FP to find the first "in", because we want to
insert the variable-sized local refs table between them.  It's awkward
to use the previous frame's FP because native methods invoked via
dvmCallMethod() or dvmInvokeMethod() don't have "ins", but native methods
invoked from interpreted code do.  We can either track the local refs
table size with a field in the stack frame, or insert unnecessary items
so that all native stack frames have "ins".

Assuming we can find the region bounds, we still need pointer #3
for an efficient implementation.  This can be stored in an otherwise
unused-for-native field in the frame goop.

When we run out of room we have to make more space.  If we start allocating
locals immediately below in0 and grow downward, we will detect end-of-space
by running into the current frame's FP.  We then memmove() the goop down
(memcpy if we guarantee the additional size is larger than the frame).
This is nice because we only have to move sizeof(StackSaveArea) bytes
each time.

Stack walking should be okay so long as nothing tries to access the
"ins" by an offset from the FP.  In theory the "ins" could be read by
the debugger or SIGQUIT handler looking for "this" or other arguments,
but in practice this behavior isn't expected to work for native methods,
so we can simply disallow it.

A conservative GC can just scan the entire stack from top to bottom to find
all references.  An exact GC will need to understand the actual layout.

*** Approach #2: use a parallel stack

Each Thread/JNIEnv points to a reference table.  The struct has
a system-heap-allocated array of references and a pointer to the
next-available entry ("nextEntry").

Each stack frame has a pointer to what it sees as the "bottom" element
in the array (we can double-up the "currentPc" field).  This is set to
"nextEntry" when the frame is pushed on.  As local references are added
or removed, "nextEntry" is updated.

We implement Push/PopLocalFrame with actual stack frames.  Before a JNI
frame gets popped, we set "nextEntry" to the "top" pointer of the current
frame, effectively releasing the references.

The GC will scan all references from the start of the table to the
"nextEntry" pointer.

*** Comparison

All approaches will return a failure result when they run out of local
reference space.  For #1 that means blowing out the stack, for #2 it's
running out of room in the array.

Compared to #1, approach #2:
 - Needs only one pointer in the stack frame goop.
 - Makes pre-allocating storage unnecessary.
 - Doesn't contend with interpreted stack depth for space.  In most
   cases, if something blows out the local ref storage, it's because the
   JNI code was misbehaving rather than called from way down.
 - Allows the GC to do a linear scan per thread in a buffer that is 100%
   references.  The GC can be slightly less smart when scanning the stack.
 - Will be easier to work with if we combine native and interpeted stacks.

 - Isn't as clean, especially when popping frames, since we have to do
   explicit work.  Fortunately we only have to do it when popping native
   method calls off, so it doesn't add overhead to interpreted code paths.
 - Is awkward to expand dynamically.  We'll want to pre-allocate the full
   amount of space; this is fine, since something on the order of 1KB should
   be plenty.  The JNI spec allows us to limit this.
 - Requires the GC to scan even more memory.  With the references embedded
   in the stack we get better locality of reference.

*/

/* fwd */
static const struct JNINativeInterface gNativeInterface;
static jobject addGlobalReference(Object* obj);

#ifdef WITH_JNI_STACK_CHECK
# define COMPUTE_STACK_SUM(_self)   computeStackSum(_self);
# define CHECK_STACK_SUM(_self)     checkStackSum(_self);
//static void computeStackSum(Thread* self);
//static void checkStackSum(Thread* self);
#else
# define COMPUTE_STACK_SUM(_self)   ((void)0)
# define CHECK_STACK_SUM(_self)     ((void)0)
#endif


/*
 * ===========================================================================
 *      Utility functions
 * ===========================================================================
 */

/*
 * Entry/exit processing for all JNI calls.
 *
 * If TRUSTED_JNIENV is set, we get to skip the (curiously expensive)
 * thread-local storage lookup on our Thread*.  If the caller has passed
 * the wrong JNIEnv in, we're going to be accessing unsynchronized
 * structures from more than one thread, and things are going to fail
 * in bizarre ways.  This is only sensible if the native code has been
 * fully exercised with CheckJNI enabled.
 */
#define TRUSTED_JNIENV
#ifdef TRUSTED_JNIENV
# define JNI_ENTER()                                                        \
        Thread* _self = ((JNIEnvExt*)env)->self;                            \
        CHECK_STACK_SUM(_self);                                             \
        dvmChangeStatus(_self, THREAD_RUNNING)
#else
# define JNI_ENTER()                                                        \
        Thread* _self = dvmThreadSelf();                                    \
        UNUSED_PARAMETER(env);                                              \
        CHECK_STACK_SUM(_self);                                             \
        dvmChangeStatus(_self, THREAD_RUNNING)
#endif
#define JNI_EXIT()                                                          \
        dvmChangeStatus(_self, THREAD_NATIVE);                              \
        COMPUTE_STACK_SUM(_self)

#define kGlobalRefsTableInitialSize 512
#define kGlobalRefsTableMaxSize     51200       /* arbitrary, must be < 64K */
#define kGrefWaterInterval          100
#define kTrackGrefUsage             true

#define kPinTableInitialSize        16
#define kPinTableMaxSize            1024
#define kPinComplainThreshold       10

/*
 * Allocate the global references table, and look up some classes for
 * the benefit of direct buffer access.
 */
bool dvmJniStartup(void)
{
#ifdef USE_INDIRECT_REF
    if (!dvmInitIndirectRefTable(&gDvm.jniGlobalRefTable,
            kGlobalRefsTableInitialSize, kGlobalRefsTableMaxSize,
            kIndirectKindGlobal))
        return false;
#else
    if (!dvmInitReferenceTable(&gDvm.jniGlobalRefTable,
            kGlobalRefsTableInitialSize, kGlobalRefsTableMaxSize))
        return false;
#endif

    dvmInitMutex(&gDvm.jniGlobalRefLock);
    gDvm.jniGlobalRefLoMark = 0;
    gDvm.jniGlobalRefHiMark = kGrefWaterInterval * 2;

    if (!dvmInitReferenceTable(&gDvm.jniPinRefTable,
            kPinTableInitialSize, kPinTableMaxSize))
        return false;

    dvmInitMutex(&gDvm.jniPinRefLock);

    Method* meth;

    /*
     * Grab the PhantomReference constructor.
     */
    gDvm.classJavaLangRefPhantomReference =
        dvmFindSystemClassNoInit("Ljava/lang/ref/PhantomReference;");
    if (gDvm.classJavaLangRefPhantomReference == NULL) {
        LOGE("Unable to find PhantomReference class\n");
        return false;
    }
    meth= dvmFindDirectMethodByDescriptor(gDvm.classJavaLangRefPhantomReference,
        "<init>", "(Ljava/lang/Object;Ljava/lang/ref/ReferenceQueue;)V");
    if (meth == NULL) {
        LOGE("Unable to find constructor for PhantomReference\n");
        return false;
    }
    gDvm.methJavaLangRefPhantomReference_init = meth;


    /*
     * Look up and cache pointers to some direct buffer classes, fields,
     * and methods.
     */
    ClassObject* readWriteBufferClass =
        dvmFindSystemClassNoInit("Ljava/nio/ReadWriteDirectByteBuffer;");
    ClassObject* bufferClass =
        dvmFindSystemClassNoInit("Ljava/nio/Buffer;");

    if (readWriteBufferClass == NULL || bufferClass == NULL) {
        LOGE("Unable to find internal direct buffer classes\n");
        return false;
    }
    gDvm.classJavaNioReadWriteDirectByteBuffer = readWriteBufferClass;

    meth = dvmFindDirectMethodByDescriptor(readWriteBufferClass,
                "<init>",
                "(II)V");
    if (meth == NULL) {
        LOGE("Unable to find ReadWriteDirectByteBuffer.<init>\n");
        return false;
    }
    gDvm.methJavaNioReadWriteDirectByteBuffer_init = meth;

    gDvm.offJavaNioBuffer_capacity =
        dvmFindFieldOffset(bufferClass, "capacity", "I");
    if (gDvm.offJavaNioBuffer_capacity < 0) {
        LOGE("Unable to find Buffer.capacity\n");
        return false;
    }

    gDvm.offJavaNioBuffer_effectiveDirectAddress =
        dvmFindFieldOffset(bufferClass, "effectiveDirectAddress", "I");
    if (gDvm.offJavaNioBuffer_effectiveDirectAddress < 0) {
        LOGE("Unable to find Buffer.effectiveDirectAddress\n");
        return false;
    }

    return true;
}

/*
 * Free the global references table.
 */
void dvmJniShutdown(void)
{
#ifdef USE_INDIRECT_REF
    dvmClearIndirectRefTable(&gDvm.jniGlobalRefTable);
#else
    dvmClearReferenceTable(&gDvm.jniGlobalRefTable);
#endif
    dvmClearReferenceTable(&gDvm.jniPinRefTable);
}


/*
 * Find the JNIEnv associated with the current thread.
 *
 * Currently stored in the Thread struct.  Could also just drop this into
 * thread-local storage.
 */
JNIEnvExt* dvmGetJNIEnvForThread(void)
{
    Thread* self = dvmThreadSelf();
    if (self == NULL)
        return NULL;
    return (JNIEnvExt*) dvmGetThreadJNIEnv(self);
}

/*
 * Create a new JNIEnv struct and add it to the VM's list.
 *
 * "self" will be NULL for the main thread, since the VM hasn't started
 * yet; the value will be filled in later.
 */
JNIEnv* dvmCreateJNIEnv(Thread* self)
{
    JavaVMExt* vm = (JavaVMExt*) gDvm.vmList;
    JNIEnvExt* newEnv;

    //if (self != NULL)
    //    LOGI("Ent CreateJNIEnv: threadid=%d %p\n", self->threadId, self);

    assert(vm != NULL);

    newEnv = (JNIEnvExt*) calloc(1, sizeof(JNIEnvExt));
    newEnv->funcTable = &gNativeInterface;
    newEnv->vm = vm;
    newEnv->forceDataCopy = vm->forceDataCopy;
    if (self != NULL) {
        dvmSetJniEnvThreadId((JNIEnv*) newEnv, self);
        assert(newEnv->envThreadId != 0);
    } else {
        /* make it obvious if we fail to initialize these later */
        newEnv->envThreadId = 0x77777775;
        newEnv->self = (Thread*) 0x77777779;
    }
    if (vm->useChecked)
        dvmUseCheckedJniEnv(newEnv);

    dvmLockMutex(&vm->envListLock);

    /* insert at head of list */
    newEnv->next = vm->envList;
    assert(newEnv->prev == NULL);
    if (vm->envList == NULL)            // rare, but possible
        vm->envList = newEnv;
    else
        vm->envList->prev = newEnv;
    vm->envList = newEnv;

    dvmUnlockMutex(&vm->envListLock);

    //if (self != NULL)
    //    LOGI("Xit CreateJNIEnv: threadid=%d %p\n", self->threadId, self);
    return (JNIEnv*) newEnv;
}

/*
 * Remove a JNIEnv struct from the list and free it.
 */
void dvmDestroyJNIEnv(JNIEnv* env)
{
    JNIEnvExt* extEnv = (JNIEnvExt*) env;
    JavaVMExt* vm = extEnv->vm;
    Thread* self;

    if (env == NULL)
        return;

    self = dvmThreadSelf();
    assert(self != NULL);

    //LOGI("Ent DestroyJNIEnv: threadid=%d %p\n", self->threadId, self);

    dvmLockMutex(&vm->envListLock);

    if (extEnv == vm->envList) {
        assert(extEnv->prev == NULL);
        vm->envList = extEnv->next;
    } else {
        assert(extEnv->prev != NULL);
        extEnv->prev->next = extEnv->next;
    }
    if (extEnv->next != NULL)
        extEnv->next->prev = extEnv->prev;

    dvmUnlockMutex(&extEnv->vm->envListLock);

    free(env);
    //LOGI("Xit DestroyJNIEnv: threadid=%d %p\n", self->threadId, self);
}


/*
 * Retrieve the ReferenceTable struct for the current thread.
 *
 * Going through "env" rather than dvmThreadSelf() is faster but will
 * get weird if the JNI code is passing the wrong JNIEnv around.
 */
#ifdef USE_INDIRECT_REF
static inline IndirectRefTable* getLocalRefTable(JNIEnv* env)
#else
static inline ReferenceTable* getLocalRefTable(JNIEnv* env)
#endif
{
    //return &dvmThreadSelf()->jniLocalRefTable;
    return &((JNIEnvExt*)env)->self->jniLocalRefTable;
}

#ifdef USE_INDIRECT_REF
/*
 * Convert an indirect reference to an Object reference.  The indirect
 * reference may be local, global, or weak-global.
 *
 * If "jobj" is NULL or an invalid indirect reference, this returns NULL.
 */
Object* dvmDecodeIndirectRef(JNIEnv* env, jobject jobj)
{
    if (jobj == NULL)
        return NULL;

    Object* result;

    switch (dvmGetIndirectRefType(jobj)) {
    case kIndirectKindLocal:
        {
            IndirectRefTable* pRefTable = getLocalRefTable(env);
            result = dvmGetFromIndirectRefTable(pRefTable, jobj);
        }
        break;
    case kIndirectKindGlobal:
        {
            // TODO: find a way to avoid the mutex activity here
            IndirectRefTable* pRefTable = &gDvm.jniGlobalRefTable;
            dvmLockMutex(&gDvm.jniGlobalRefLock);
            result = dvmGetFromIndirectRefTable(pRefTable, jobj);
            dvmUnlockMutex(&gDvm.jniGlobalRefLock);
        }
        break;
    case kIndirectKindWeakGlobal:
        {
            // TODO: implement
            LOGE("weak-global not yet supported\n");
            result = NULL;
            dvmAbort();
        }
        break;
    case kIndirectKindInvalid:
    default:
        LOGW("Invalid indirect reference %p in decodeIndirectRef\n", jobj);
        dvmAbort();
        result = NULL;
        break;
    }

    return result;
}
#else
    /* use trivial inline in JniInternal.h for performance */
#endif

/*
 * Add a local reference for an object to the current stack frame.  When
 * the native function returns, the reference will be discarded.
 *
 * We need to allow the same reference to be added multiple times.
 *
 * This will be called on otherwise unreferenced objects.  We cannot do
 * GC allocations here, and it's best if we don't grab a mutex.
 *
 * Returns the local reference (currently just the same pointer that was
 * passed in), or NULL on failure.
 */
static jobject addLocalReference(JNIEnv* env, Object* obj)
{
    if (obj == NULL)
        return NULL;

    jobject jobj;

#ifdef USE_INDIRECT_REF
    IndirectRefTable* pRefTable = getLocalRefTable(env);
    void* curFrame = ((JNIEnvExt*)env)->self->curFrame;
    u4 cookie = SAVEAREA_FROM_FP(curFrame)->xtra.localRefCookie;

    jobj = (jobject) dvmAddToIndirectRefTable(pRefTable, cookie, obj);
    if (jobj == NULL) {
        dvmDumpIndirectRefTable(pRefTable, "JNI local");
        LOGE("Failed adding to JNI local ref table (has %d entries)\n",
            (int) dvmIndirectRefTableEntries(pRefTable));
        dvmDumpThread(dvmThreadSelf(), false);
        dvmAbort();     // spec says call FatalError; this is equivalent
    } else {
        LOGVV("LREF add %p  (%s.%s) (ent=%d)\n", obj,
            dvmGetCurrentJNIMethod()->clazz->descriptor,
            dvmGetCurrentJNIMethod()->name,
            (int) dvmReferenceTableEntries(pRefTable));
    }
#else
    ReferenceTable* pRefTable = getLocalRefTable(env);

    if (!dvmAddToReferenceTable(pRefTable, obj)) {
        dvmDumpReferenceTable(pRefTable, "JNI local");
        LOGE("Failed adding to JNI local ref table (has %d entries)\n",
            (int) dvmReferenceTableEntries(pRefTable));
        dvmDumpThread(dvmThreadSelf(), false);
        dvmAbort();     // spec says call FatalError; this is equivalent
    } else {
        LOGVV("LREF add %p  (%s.%s) (ent=%d)\n", obj,
            dvmGetCurrentJNIMethod()->clazz->descriptor,
            dvmGetCurrentJNIMethod()->name,
            (int) dvmReferenceTableEntries(pRefTable));
    }

    jobj = (jobject) obj;
#endif

    return jobj;
}

/*
 * Ensure that at least "capacity" references can be held in the local
 * refs table of the current thread.
 */
static bool ensureLocalCapacity(JNIEnv* env, int capacity)
{
#ifdef USE_INDIRECT_REF
    IndirectRefTable* pRefTable = getLocalRefTable(env);
    int numEntries = dvmIndirectRefTableEntries(pRefTable);
    // TODO: this isn't quite right, since "numEntries" includes holes
    return ((kJniLocalRefMax - numEntries) >= capacity);
#else
    ReferenceTable* pRefTable = getLocalRefTable(env);

    return (kJniLocalRefMax - (pRefTable->nextEntry - pRefTable->table) >= capacity);
#endif
}

/*
 * Explicitly delete a reference from the local list.
 */
static void deleteLocalReference(JNIEnv* env, jobject jobj)
{
    if (jobj == NULL)
        return;

#ifdef USE_INDIRECT_REF
    IndirectRefTable* pRefTable = getLocalRefTable(env);
    Thread* self = ((JNIEnvExt*)env)->self;
    u4 cookie = SAVEAREA_FROM_FP(self->curFrame)->xtra.localRefCookie;

    if (!dvmRemoveFromIndirectRefTable(pRefTable, cookie, jobj)) {
        /*
         * Attempting to delete a local reference that is not in the
         * topmost local reference frame is a no-op.  DeleteLocalRef returns
         * void and doesn't throw any exceptions, but we should probably
         * complain about it so the user will notice that things aren't
         * going quite the way they expect.
         */
        LOGW("JNI WARNING: DeleteLocalRef(%p) failed to find entry\n", jobj);
    }
#else
    ReferenceTable* pRefTable = getLocalRefTable(env);
    Thread* self = ((JNIEnvExt*)env)->self;
    Object** bottom = SAVEAREA_FROM_FP(self->curFrame)->xtra.localRefCookie;

    if (!dvmRemoveFromReferenceTable(pRefTable, bottom, (Object*) jobj)) {
        /*
         * Attempting to delete a local reference that is not in the
         * topmost local reference frame is a no-op.  DeleteLocalRef returns
         * void and doesn't throw any exceptions, but we should probably
         * complain about it so the user will notice that things aren't
         * going quite the way they expect.
         */
        LOGW("JNI WARNING: DeleteLocalRef(%p) failed to find entry (valid=%d)\n",
            jobj, dvmIsValidObject((Object*) jobj));
    }
#endif
}

/*
 * Add a global reference for an object.
 *
 * We may add the same object more than once.  Add/remove calls are paired,
 * so it needs to appear on the list multiple times.
 */
static jobject addGlobalReference(Object* obj)
{
    if (obj == NULL)
        return NULL;

    //LOGI("adding obj=%p\n", obj);
    //dvmDumpThread(dvmThreadSelf(), false);

    if (false && ((Object*)obj)->clazz == gDvm.classJavaLangClass) {
        ClassObject* clazz = (ClassObject*) obj;
        LOGI("-------\n");
        LOGI("Adding global ref on class %s\n", clazz->descriptor);
        dvmDumpThread(dvmThreadSelf(), false);
    }
    if (false && ((Object*)obj)->clazz == gDvm.classJavaLangString) {
        StringObject* strObj = (StringObject*) obj;
        char* str = dvmCreateCstrFromString(strObj);
        if (strcmp(str, "sync-response") == 0) {
            LOGI("-------\n");
            LOGI("Adding global ref on string '%s'\n", str);
            dvmDumpThread(dvmThreadSelf(), false);
            //dvmAbort();
        }
        free(str);
    }
    if (false && ((Object*)obj)->clazz == gDvm.classArrayByte) {
        ArrayObject* arrayObj = (ArrayObject*) obj;
        if (arrayObj->length == 8192 /*&&
            dvmReferenceTableEntries(&gDvm.jniGlobalRefTable) > 400*/)
        {
            LOGI("Adding global ref on byte array %p (len=%d)\n",
                arrayObj, arrayObj->length);
            dvmDumpThread(dvmThreadSelf(), false);
        }
    }

    jobject jobj;

    dvmLockMutex(&gDvm.jniGlobalRefLock);

    /*
     * Throwing an exception on failure is problematic, because JNI code
     * may not be expecting an exception, and things sort of cascade.  We
     * want to have a hard limit to catch leaks during debugging, but this
     * otherwise needs to expand until memory is consumed.  As a practical
     * matter, if we have many thousands of global references, chances are
     * we're either leaking global ref table entries or we're going to
     * run out of space in the GC heap.
     */
#ifdef USE_INDIRECT_REF
    jobj = dvmAddToIndirectRefTable(&gDvm.jniGlobalRefTable, IRT_FIRST_SEGMENT,
            obj);
    if (jobj == NULL) {
        dvmDumpIndirectRefTable(&gDvm.jniGlobalRefTable, "JNI global");
        LOGE("Failed adding to JNI global ref table (%d entries)\n",
            (int) dvmIndirectRefTableEntries(&gDvm.jniGlobalRefTable));
        dvmAbort();
    }

    LOGVV("GREF add %p  (%s.%s)\n", obj,
        dvmGetCurrentJNIMethod()->clazz->descriptor,
        dvmGetCurrentJNIMethod()->name);

    /* GREF usage tracking; should probably be disabled for production env */
    if (kTrackGrefUsage && gDvm.jniGrefLimit != 0) {
        int count = dvmIndirectRefTableEntries(&gDvm.jniGlobalRefTable);
        // TODO: adjust for "holes"
        if (count > gDvm.jniGlobalRefHiMark) {
            LOGD("GREF has increased to %d\n", count);
            gDvm.jniGlobalRefHiMark += kGrefWaterInterval;
            gDvm.jniGlobalRefLoMark += kGrefWaterInterval;

            /* watch for "excessive" use; not generally appropriate */
            if (count >= gDvm.jniGrefLimit) {
                JavaVMExt* vm = (JavaVMExt*) gDvm.vmList;
                if (vm->warnError) {
                    dvmDumpIndirectRefTable(&gDvm.jniGlobalRefTable,
                        "JNI global");
                    LOGE("Excessive JNI global references (%d)\n", count);
                    dvmAbort();
                } else {
                    LOGW("Excessive JNI global references (%d)\n", count);
                }
            }
        }
    }
#else
    if (!dvmAddToReferenceTable(&gDvm.jniGlobalRefTable, obj)) {
        dvmDumpReferenceTable(&gDvm.jniGlobalRefTable, "JNI global");
        LOGE("Failed adding to JNI global ref table (%d entries)\n",
            (int) dvmReferenceTableEntries(&gDvm.jniGlobalRefTable));
        dvmAbort();
    }
    jobj = (jobject) obj;

    LOGVV("GREF add %p  (%s.%s)\n", obj,
        dvmGetCurrentJNIMethod()->clazz->descriptor,
        dvmGetCurrentJNIMethod()->name);

    /* GREF usage tracking; should probably be disabled for production env */
    if (kTrackGrefUsage && gDvm.jniGrefLimit != 0) {
        int count = dvmReferenceTableEntries(&gDvm.jniGlobalRefTable);
        if (count > gDvm.jniGlobalRefHiMark) {
            LOGD("GREF has increased to %d\n", count);
            gDvm.jniGlobalRefHiMark += kGrefWaterInterval;
            gDvm.jniGlobalRefLoMark += kGrefWaterInterval;

            /* watch for "excessive" use; not generally appropriate */
            if (count >= gDvm.jniGrefLimit) {
                JavaVMExt* vm = (JavaVMExt*) gDvm.vmList;
                if (vm->warnError) {
                    dvmDumpReferenceTable(&gDvm.jniGlobalRefTable,"JNI global");
                    LOGE("Excessive JNI global references (%d)\n", count);
                    dvmAbort();
                } else {
                    LOGW("Excessive JNI global references (%d)\n", count);
                }
            }
        }
    }
#endif

    dvmUnlockMutex(&gDvm.jniGlobalRefLock);
    return jobj;
}

/*
 * Remove a global reference.  In most cases it's the entry most recently
 * added, which makes this pretty quick.
 *
 * Thought: if it's not the most recent entry, just null it out.  When we
 * fill up, do a compaction pass before we expand the list.
 */
static void deleteGlobalReference(jobject jobj)
{
    if (jobj == NULL)
        return;

    dvmLockMutex(&gDvm.jniGlobalRefLock);

#ifdef USE_INDIRECT_REF
    if (!dvmRemoveFromIndirectRefTable(&gDvm.jniGlobalRefTable,
            IRT_FIRST_SEGMENT, jobj))
    {
        LOGW("JNI: DeleteGlobalRef(%p) failed to find entry\n", jobj);
        goto bail;
    }

    if (kTrackGrefUsage && gDvm.jniGrefLimit != 0) {
        int count = dvmIndirectRefTableEntries(&gDvm.jniGlobalRefTable);
        // TODO: not quite right, need to subtract holes
        if (count < gDvm.jniGlobalRefLoMark) {
            LOGD("GREF has decreased to %d\n", count);
            gDvm.jniGlobalRefHiMark -= kGrefWaterInterval;
            gDvm.jniGlobalRefLoMark -= kGrefWaterInterval;
        }
    }
#else
    if (!dvmRemoveFromReferenceTable(&gDvm.jniGlobalRefTable,
            gDvm.jniGlobalRefTable.table, jobj))
    {
        LOGW("JNI: DeleteGlobalRef(%p) failed to find entry (valid=%d)\n",
            jobj, dvmIsValidObject((Object*) jobj));
        goto bail;
    }

    if (kTrackGrefUsage && gDvm.jniGrefLimit != 0) {
        int count = dvmReferenceTableEntries(&gDvm.jniGlobalRefTable);
        if (count < gDvm.jniGlobalRefLoMark) {
            LOGD("GREF has decreased to %d\n", count);
            gDvm.jniGlobalRefHiMark -= kGrefWaterInterval;
            gDvm.jniGlobalRefLoMark -= kGrefWaterInterval;
        }
    }
#endif

bail:
    dvmUnlockMutex(&gDvm.jniGlobalRefLock);
}

/*
 * We create a PhantomReference that references the object, add a
 * global reference to it, and then flip some bits before returning it.
 * The last step ensures that we detect it as special and that only
 * appropriate calls will accept it.
 *
 * On failure, returns NULL with an exception pending.
 */
static jweak createWeakGlobalRef(JNIEnv* env, jobject jobj)
{
    if (jobj == NULL)
        return NULL;

    Thread* self = ((JNIEnvExt*)env)->self;
    Object* obj = dvmDecodeIndirectRef(env, jobj);
    Object* phantomObj;
    jobject phantomRef;

    /*
     * Allocate a PhantomReference, then call the constructor to set
     * the referent and the reference queue.
     *
     * We use a "magic" reference queue that the GC knows about; it behaves
     * more like a queueless WeakReference, clearing the referent and
     * not calling enqueue().
     */
    if (!dvmIsClassInitialized(gDvm.classJavaLangRefPhantomReference))
        dvmInitClass(gDvm.classJavaLangRefPhantomReference);
    phantomObj = dvmAllocObject(gDvm.classJavaLangRefPhantomReference,
            ALLOC_DEFAULT);
    if (phantomObj == NULL) {
        assert(dvmCheckException(self));
        LOGW("Failed on WeakGlobalRef alloc\n");
        return NULL;
    }

    JValue unused;
    dvmCallMethod(self, gDvm.methJavaLangRefPhantomReference_init, phantomObj,
        &unused, obj, NULL);
    dvmReleaseTrackedAlloc(phantomObj, self);

    if (dvmCheckException(self)) {
        LOGW("PhantomReference init failed\n");
        return NULL;
    }

    LOGV("+++ WGR: created phantom ref %p for object %p\n", phantomObj, obj);

    /*
     * Add it to the global reference table, and mangle the pointer.
     */
    phantomRef = addGlobalReference(phantomObj);
    return dvmObfuscateWeakGlobalRef(phantomRef);
}

/*
 * Delete the global reference that's keeping the PhantomReference around.
 * The PhantomReference will eventually be discarded by the GC.
 */
static void deleteWeakGlobalRef(JNIEnv* env, jweak wref)
{
    if (wref == NULL)
        return;

    jobject phantomRef = dvmNormalizeWeakGlobalRef(wref);
    deleteGlobalReference(phantomRef);
}

/*
 * Extract the referent from a PhantomReference.  Used for weak global
 * references.
 *
 * "jwobj" is a "mangled" WGR pointer.
 */
static Object* getPhantomReferent(JNIEnv* env, jweak jwobj)
{
    jobject jobj = dvmNormalizeWeakGlobalRef(jwobj);
    Object* obj = dvmDecodeIndirectRef(env, jobj);

    if (obj->clazz != gDvm.classJavaLangRefPhantomReference) {
        LOGE("%p is not a phantom reference (%s)\n",
            jwobj, obj->clazz->descriptor);
        return NULL;
    }

    return dvmGetFieldObject(obj, gDvm.offJavaLangRefReference_referent);
}


/*
 * Objects don't currently move, so we just need to create a reference
 * that will ensure the array object isn't collected.
 *
 * We use a separate reference table, which is part of the GC root set.
 */
static void pinPrimitiveArray(ArrayObject* arrayObj)
{
    if (arrayObj == NULL)
        return;

    dvmLockMutex(&gDvm.jniPinRefLock);
    if (!dvmAddToReferenceTable(&gDvm.jniPinRefTable, (Object*)arrayObj)) {
        dvmDumpReferenceTable(&gDvm.jniPinRefTable, "JNI pinned array");
        LOGE("Failed adding to JNI pinned array ref table (%d entries)\n",
            (int) dvmReferenceTableEntries(&gDvm.jniPinRefTable));
        dvmDumpThread(dvmThreadSelf(), false);
        dvmAbort();
    }

    /*
     * If we're watching global ref usage, also keep an eye on these.
     *
     * The total number of pinned primitive arrays should be pretty small.
     * A single array should not be pinned more than once or twice; any
     * more than that is a strong indicator that a Release function is
     * not being called.
     */
    if (kTrackGrefUsage && gDvm.jniGrefLimit != 0) {
        int count = 0;
        Object** ppObj = gDvm.jniPinRefTable.table;
        while (ppObj < gDvm.jniPinRefTable.nextEntry) {
            if (*ppObj++ == (Object*) arrayObj)
                count++;
        }

        if (count > kPinComplainThreshold) {
            LOGW("JNI: pin count on array %p (%s) is now %d\n",
                arrayObj, arrayObj->obj.clazz->descriptor, count);
            /* keep going */
        }
    }

    dvmUnlockMutex(&gDvm.jniPinRefLock);
}

/*
 * Un-pin the array object.  If an object was pinned twice, it must be
 * unpinned twice before it's free to move.
 */
static void unpinPrimitiveArray(ArrayObject* arrayObj)
{
    if (arrayObj == NULL)
        return;

    dvmLockMutex(&gDvm.jniPinRefLock);
    if (!dvmRemoveFromReferenceTable(&gDvm.jniPinRefTable,
            gDvm.jniPinRefTable.table, (Object*) arrayObj))
    {
        LOGW("JNI: unpinPrimitiveArray(%p) failed to find entry (valid=%d)\n",
            arrayObj, dvmIsValidObject((Object*) arrayObj));
        goto bail;
    }

bail:
    dvmUnlockMutex(&gDvm.jniPinRefLock);
}

/*
 * Dump the contents of the JNI reference tables to the log file.
 *
 * We only dump the local refs associated with the current thread.
 */
void dvmDumpJniReferenceTables(void)
{
    Thread* self = dvmThreadSelf();
    JNIEnv* env = self->jniEnv;
    ReferenceTable* pLocalRefs = getLocalRefTable(env);

#ifdef USE_INDIRECT_REF
    dvmDumpIndirectRefTable(pLocalRefs, "JNI local");
    dvmDumpIndirectRefTable(&gDvm.jniGlobalRefTable, "JNI global");
#else
    dvmDumpReferenceTable(pLocalRefs, "JNI local");
    dvmDumpReferenceTable(&gDvm.jniGlobalRefTable, "JNI global");
#endif
    dvmDumpReferenceTable(&gDvm.jniPinRefTable, "JNI pinned array");
}

/*
 * GC helper function to mark all JNI global references.
 *
 * We're currently handling the "pin" table here too.
 */
void dvmGcMarkJniGlobalRefs()
{
    Object** op;

    dvmLockMutex(&gDvm.jniGlobalRefLock);

#ifdef USE_INDIRECT_REF
    IndirectRefTable* pRefTable = &gDvm.jniGlobalRefTable;
    op = pRefTable->table;
    int numEntries = dvmIndirectRefTableEntries(pRefTable);
    int i;

    for (i = 0; i < numEntries; i++) {
        Object* obj = *op;
        if (obj != NULL)
            dvmMarkObjectNonNull(obj);
        op++;
    }
#else
    op = gDvm.jniGlobalRefTable.table;
    while ((uintptr_t)op < (uintptr_t)gDvm.jniGlobalRefTable.nextEntry) {
        dvmMarkObjectNonNull(*(op++));
    }
#endif

    dvmUnlockMutex(&gDvm.jniGlobalRefLock);


    dvmLockMutex(&gDvm.jniPinRefLock);

    op = gDvm.jniPinRefTable.table;
    while ((uintptr_t)op < (uintptr_t)gDvm.jniPinRefTable.nextEntry) {
        dvmMarkObjectNonNull(*(op++));
    }

    dvmUnlockMutex(&gDvm.jniPinRefLock);
}


#ifndef USE_INDIRECT_REF
/*
 * Determine if "obj" appears in the argument list for the native method.
 *
 * We use the "shorty" signature to determine which argument slots hold
 * reference types.
 */
static bool findInArgList(Thread* self, Object* obj)
{
    const Method* meth;
    u4* fp;
    int i;

    fp = self->curFrame;
    while (1) {
        /*
         * Back up over JNI PushLocalFrame frames.  This works because the
         * previous frame on the interpreted stack is either a break frame
         * (if we called here via native code) or an interpreted method (if
         * we called here via the interpreter).  In both cases the method
         * pointer won't match.
         */
        StackSaveArea* saveArea = SAVEAREA_FROM_FP(fp);
        meth = saveArea->method;
        if (meth != SAVEAREA_FROM_FP(saveArea->prevFrame)->method)
            break;
        fp = saveArea->prevFrame;
    }

    LOGVV("+++ scanning %d args in %s (%s)\n",
        meth->insSize, meth->name, meth->shorty);
    const char* shorty = meth->shorty +1;       /* skip return type char */
    for (i = 0; i < meth->insSize; i++) {
        if (i == 0 && !dvmIsStaticMethod(meth)) {
            /* first arg is "this" ref, not represented in "shorty" */
            if (fp[i] == (u4) obj)
                return true;
        } else {
            /* if this is a reference type, see if it matches */
            switch (*shorty) {
            case 'L':
                if (fp[i] == (u4) obj)
                    return true;
                break;
            case 'D':
            case 'J':
                i++;
                break;
            case '\0':
                LOGE("Whoops! ran off the end of %s (%d)\n",
                    meth->shorty, meth->insSize);
                break;
            default:
                if (fp[i] == (u4) obj)
                    LOGI("NOTE: ref %p match on arg type %c\n", obj, *shorty);
                break;
            }
            shorty++;
        }
    }

    /*
     * For static methods, we also pass a class pointer in.
     */
    if (dvmIsStaticMethod(meth)) {
        //LOGI("+++ checking class pointer in %s\n", meth->name);
        if ((void*)obj == (void*)meth->clazz)
            return true;
    }
    return false;
}
#endif

/*
 * Verify that a reference passed in from native code is one that the
 * code is allowed to have.
 *
 * It's okay for native code to pass us a reference that:
 *  - was passed in as an argument when invoked by native code (and hence
 *    is in the JNI local refs table)
 *  - was returned to it from JNI (and is now in the local refs table)
 *  - is present in the JNI global refs table
 *
 * Used by -Xcheck:jni and GetObjectRefType.
 *
 * NOTE: in the current VM, global and local references are identical.  If
 * something is both global and local, we can't tell them apart, and always
 * return "local".
 */
jobjectRefType dvmGetJNIRefType(JNIEnv* env, jobject jobj)
{
#ifdef USE_INDIRECT_REF
    /*
     * IndirectRefKind is currently defined as an exact match of
     * jobjectRefType, so this is easy.  We have to decode it to determine
     * if it's a valid reference and not merely valid-looking.
     */
    Object* obj = dvmDecodeIndirectRef(env, jobj);

    if (obj == NULL) {
        /* invalid ref, or jobj was NULL */
        return JNIInvalidRefType;
    } else {
        return (jobjectRefType) dvmGetIndirectRefType(jobj);
    }
#else
    ReferenceTable* pRefTable = getLocalRefTable(env);
    Thread* self = dvmThreadSelf();

    if (dvmIsWeakGlobalRef(jobj)) {
        return JNIWeakGlobalRefType;
    }

    /* check args */
    if (findInArgList(self, jobj)) {
        //LOGI("--- REF found %p on stack\n", jobj);
        return JNILocalRefType;
    }

    /* check locals */
    if (dvmFindInReferenceTable(pRefTable, pRefTable->table, jobj) != NULL) {
        //LOGI("--- REF found %p in locals\n", jobj);
        return JNILocalRefType;
    }

    /* check globals */
    dvmLockMutex(&gDvm.jniGlobalRefLock);
    if (dvmFindInReferenceTable(&gDvm.jniGlobalRefTable,
            gDvm.jniGlobalRefTable.table, jobj))
    {
        //LOGI("--- REF found %p in globals\n", jobj);
        dvmUnlockMutex(&gDvm.jniGlobalRefLock);
        return JNIGlobalRefType;
    }
    dvmUnlockMutex(&gDvm.jniGlobalRefLock);

    /* not found! */
    return JNIInvalidRefType;
#endif
}

/*
 * Register a method that uses JNI calling conventions.
 */
static bool dvmRegisterJNIMethod(ClassObject* clazz, const char* methodName,
    const char* signature, void* fnPtr)
{
    Method* method;
    bool result = false;

    if (fnPtr == NULL)
        goto bail;

    method = dvmFindDirectMethodByDescriptor(clazz, methodName, signature);
    if (method == NULL)
        method = dvmFindVirtualMethodByDescriptor(clazz, methodName, signature);
    if (method == NULL) {
        LOGW("ERROR: Unable to find decl for native %s.%s:%s\n",
            clazz->descriptor, methodName, signature);
        goto bail;
    }

    if (!dvmIsNativeMethod(method)) {
        LOGW("Unable to register: not native: %s.%s:%s\n",
            clazz->descriptor, methodName, signature);
        goto bail;
    }

    if (method->nativeFunc != dvmResolveNativeMethod) {
        /* this is allowed, but unusual */
        LOGV("Note: %s.%s:%s was already registered\n",
            clazz->descriptor, methodName, signature);
    }

    dvmUseJNIBridge(method, fnPtr);

    LOGV("JNI-registered %s.%s:%s\n", clazz->descriptor, methodName,
        signature);
    result = true;

bail:
    return result;
}

/*
 * Returns "true" if CheckJNI is enabled in the VM.
 */
static bool dvmIsCheckJNIEnabled(void)
{
    JavaVMExt* vm = (JavaVMExt*) gDvm.vmList;
    return vm->useChecked;
}

/*
 * Returns the appropriate JNI bridge for 'method', also taking into account
 * the -Xcheck:jni setting.
 */
static DalvikBridgeFunc dvmSelectJNIBridge(const Method* method)
{
    enum {
        kJNIGeneral = 0,
        kJNISync = 1,
        kJNIVirtualNoRef = 2,
        kJNIStaticNoRef = 3,
    } kind;
    static const DalvikBridgeFunc stdFunc[] = {
        dvmCallJNIMethod_general,
        dvmCallJNIMethod_synchronized,
        dvmCallJNIMethod_virtualNoRef,
        dvmCallJNIMethod_staticNoRef
    };
    static const DalvikBridgeFunc checkFunc[] = {
        dvmCheckCallJNIMethod_general,
        dvmCheckCallJNIMethod_synchronized,
        dvmCheckCallJNIMethod_virtualNoRef,
        dvmCheckCallJNIMethod_staticNoRef
    };

    bool hasRefArg = false;

    if (dvmIsSynchronizedMethod(method)) {
        /* use version with synchronization; calls into general handler */
        kind = kJNISync;
    } else {
        /*
         * Do a quick scan through the "shorty" signature to see if the method
         * takes any reference arguments.
         */
        const char* cp = method->shorty;
        while (*++cp != '\0') {     /* pre-incr to skip return type */
            if (*cp == 'L') {
                /* 'L' used for both object and array references */
                hasRefArg = true;
                break;
            }
        }

        if (hasRefArg) {
            /* use general handler to slurp up reference args */
            kind = kJNIGeneral;
        } else {
            /* virtual methods have a ref in args[0] (not in signature) */
            if (dvmIsStaticMethod(method))
                kind = kJNIStaticNoRef;
            else
                kind = kJNIVirtualNoRef;
        }
    }

    return dvmIsCheckJNIEnabled() ? checkFunc[kind] : stdFunc[kind];
}

/*
 * Trace a call into native code.
 */
static void dvmTraceCallJNIMethod(const u4* args, JValue* pResult,
    const Method* method, Thread* self)
{
    dvmLogNativeMethodEntry(method, args);
    DalvikBridgeFunc bridge = dvmSelectJNIBridge(method);
    (*bridge)(args, pResult, method, self);
    dvmLogNativeMethodExit(method, self, *pResult);
}

/**
 * Returns true if the -Xjnitrace setting implies we should trace 'method'.
 */
static bool shouldTrace(Method* method)
{
    return gDvm.jniTrace && strstr(method->clazz->descriptor, gDvm.jniTrace);
}

/*
 * Point "method->nativeFunc" at the JNI bridge, and overload "method->insns"
 * to point at the actual function.
 */
void dvmUseJNIBridge(Method* method, void* func)
{
    DalvikBridgeFunc bridge = shouldTrace(method)
        ? dvmTraceCallJNIMethod
        : dvmSelectJNIBridge(method);
    dvmSetNativeFunc(method, bridge, func);
}

/*
 * Get the method currently being executed by examining the interp stack.
 */
const Method* dvmGetCurrentJNIMethod(void)
{
    assert(dvmThreadSelf() != NULL);

    void* fp = dvmThreadSelf()->curFrame;
    const Method* meth = SAVEAREA_FROM_FP(fp)->method;

    assert(meth != NULL);
    assert(dvmIsNativeMethod(meth));
    return meth;
}


/*
 * Track a JNI MonitorEnter in the current thread.
 *
 * The goal is to be able to "implicitly" release all JNI-held monitors
 * when the thread detaches.
 *
 * Monitors may be entered multiple times, so we add a new entry for each
 * enter call.  It would be more efficient to keep a counter.  At present
 * there's no real motivation to improve this however.
 */
static void trackMonitorEnter(Thread* self, Object* obj)
{
    static const int kInitialSize = 16;
    ReferenceTable* refTable = &self->jniMonitorRefTable;

    /* init table on first use */
    if (refTable->table == NULL) {
        assert(refTable->maxEntries == 0);

        if (!dvmInitReferenceTable(refTable, kInitialSize, INT_MAX)) {
            LOGE("Unable to initialize monitor tracking table\n");
            dvmAbort();
        }
    }

    if (!dvmAddToReferenceTable(refTable, obj)) {
        /* ran out of memory? could throw exception instead */
        LOGE("Unable to add entry to monitor tracking table\n");
        dvmAbort();
    } else {
        LOGVV("--- added monitor %p\n", obj);
    }
}


/*
 * Track a JNI MonitorExit in the current thread.
 */
static void trackMonitorExit(Thread* self, Object* obj)
{
    ReferenceTable* pRefTable = &self->jniMonitorRefTable;

    if (!dvmRemoveFromReferenceTable(pRefTable, pRefTable->table, obj)) {
        LOGE("JNI monitor %p not found in tracking list\n", obj);
        /* keep going? */
    } else {
        LOGVV("--- removed monitor %p\n", obj);
    }
}

/*
 * Release all monitors held by the jniMonitorRefTable list.
 */
void dvmReleaseJniMonitors(Thread* self)
{
    ReferenceTable* pRefTable = &self->jniMonitorRefTable;
    Object** top = pRefTable->table;

    if (top == NULL)
        return;

    Object** ptr = pRefTable->nextEntry;
    while (--ptr >= top) {
        if (!dvmUnlockObject(self, *ptr)) {
            LOGW("Unable to unlock monitor %p at thread detach\n", *ptr);
        } else {
            LOGVV("--- detach-releasing monitor %p\n", *ptr);
        }
    }

    /* zap it */
    pRefTable->nextEntry = pRefTable->table;
}

/*
 * Determine if the specified class can be instantiated from JNI.  This
 * is used by AllocObject / NewObject, which are documented as throwing
 * an exception for abstract and interface classes, and not accepting
 * array classes.  We also want to reject attempts to create new Class
 * objects, since only DefineClass should do that.
 */
static bool canAllocClass(ClassObject* clazz)
{
    if (dvmIsAbstractClass(clazz) || dvmIsInterfaceClass(clazz)) {
        /* JNI spec defines what this throws */
        dvmThrowExceptionFmt("Ljava/lang/InstantiationException;",
            "Can't instantiate %s (abstract or interface)", clazz->descriptor);
        return false;
    } else if (dvmIsArrayClass(clazz) || clazz == gDvm.classJavaLangClass) {
        /* spec says "must not" for arrays, ignores Class */
        dvmThrowExceptionFmt("Ljava/lang/IllegalArgumentException;",
            "Can't instantiate %s (array or Class) with this JNI function",
            clazz->descriptor);
        return false;
    }

    return true;
}

#ifdef WITH_JNI_STACK_CHECK
/*
 * Compute a CRC on the entire interpreted stack.
 *
 * Would be nice to compute it on "self" as well, but there are parts of
 * the Thread that can be altered by other threads (e.g. prev/next pointers).
 */
static void computeStackSum(Thread* self)
{
    const u1* low = (const u1*)SAVEAREA_FROM_FP(self->curFrame);
    u4 crc = dvmInitCrc32();
    self->stackCrc = 0;
    crc = dvmComputeCrc32(crc, low, self->interpStackStart - low);
    self->stackCrc = crc;
}

/*
 * Compute a CRC on the entire interpreted stack, and compare it to what
 * we previously computed.
 *
 * We can execute JNI directly from native code without calling in from
 * interpreted code during VM initialization and immediately after JNI
 * thread attachment.  Another opportunity exists during JNI_OnLoad.  Rather
 * than catching these cases we just ignore them here, which is marginally
 * less accurate but reduces the amount of code we have to touch with #ifdefs.
 */
static void checkStackSum(Thread* self)
{
    const u1* low = (const u1*)SAVEAREA_FROM_FP(self->curFrame);
    u4 stackCrc, crc;

    stackCrc = self->stackCrc;
    self->stackCrc = 0;
    crc = dvmInitCrc32();
    crc = dvmComputeCrc32(crc, low, self->interpStackStart - low);
    if (crc != stackCrc) {
        const Method* meth = dvmGetCurrentJNIMethod();
        if (dvmComputeExactFrameDepth(self->curFrame) == 1) {
            LOGD("JNI: bad stack CRC (0x%08x) -- okay during init\n",
                stackCrc);
        } else if (strcmp(meth->name, "nativeLoad") == 0 &&
                  (strcmp(meth->clazz->descriptor, "Ljava/lang/Runtime;") == 0))
        {
            LOGD("JNI: bad stack CRC (0x%08x) -- okay during JNI_OnLoad\n",
                stackCrc);
        } else {
            LOGW("JNI: bad stack CRC (%08x vs %08x)\n", crc, stackCrc);
            dvmAbort();
        }
    }
    self->stackCrc = (u4) -1;       /* make logic errors more noticeable */
}
#endif


/*
 * ===========================================================================
 *      JNI call bridge
 * ===========================================================================
 */

/*
 * The functions here form a bridge between interpreted code and JNI native
 * functions.  The basic task is to convert an array of primitives and
 * references into C-style function arguments.  This is architecture-specific
 * and usually requires help from assembly code.
 *
 * The bridge takes four arguments: the array of parameters, a place to
 * store the function result (if any), the method to call, and a pointer
 * to the current thread.
 *
 * These functions aren't called directly from elsewhere in the VM.
 * A pointer in the Method struct points to one of these, and when a native
 * method is invoked the interpreter jumps to it.
 *
 * (The "internal native" methods are invoked the same way, but instead
 * of calling through a bridge, the target method is called directly.)
 *
 * The "args" array should not be modified, but we do so anyway for
 * performance reasons.  We know that it points to the "outs" area on
 * the current method's interpreted stack.  This area is ignored by the
 * precise GC, because there is no register map for a native method (for
 * an interpreted method the args would be listed in the argument set).
 * We know all of the values exist elsewhere on the interpreted stack,
 * because the method call setup copies them right before making the call,
 * so we don't have to worry about concealing stuff from the GC.
 *
 * If we don't want to modify "args", we either have to create a local
 * copy and modify it before calling dvmPlatformInvoke, or we have to do
 * the local reference replacement within dvmPlatformInvoke.  The latter
 * has some performance advantages, though if we can inline the local
 * reference adds we may win when there's a lot of reference args (unless
 * we want to code up some local ref table manipulation in assembly.
 */

/*
 * If necessary, convert the value in pResult from a local/global reference
 * to an object pointer.
 */
static inline void convertReferenceResult(JNIEnv* env, JValue* pResult,
    const Method* method, Thread* self)
{
#ifdef USE_INDIRECT_REF
    if (method->shorty[0] == 'L' && !dvmCheckException(self) &&
            pResult->l != NULL)
    {
        pResult->l = dvmDecodeIndirectRef(env, pResult->l);
    }
#endif
}

/*
 * General form, handles all cases.
 */
void dvmCallJNIMethod_general(const u4* args, JValue* pResult,
    const Method* method, Thread* self)
{
    int oldStatus;
    u4* modArgs = (u4*) args;
    jclass staticMethodClass;
    JNIEnv* env = self->jniEnv;

    //LOGI("JNI calling %p (%s.%s:%s):\n", method->insns,
    //    method->clazz->descriptor, method->name, method->shorty);

#ifdef USE_INDIRECT_REF
    /*
     * Walk the argument list, creating local references for appropriate
     * arguments.
     */
    int idx = 0;
    if (dvmIsStaticMethod(method)) {
        /* add the class object we pass in */
        staticMethodClass = addLocalReference(env, (Object*) method->clazz);
        if (staticMethodClass == NULL) {
            assert(dvmCheckException(self));
            return;
        }
    } else {
        /* add "this" */
        staticMethodClass = NULL;
        jobject thisObj = addLocalReference(env, (Object*) modArgs[0]);
        if (thisObj == NULL) {
            assert(dvmCheckException(self));
            return;
        }
        modArgs[idx] = (u4) thisObj;
        idx = 1;
    }

    const char* shorty = &method->shorty[1];        /* skip return type */
    while (*shorty != '\0') {
        switch (*shorty++) {
        case 'L':
            //LOGI("  local %d: 0x%08x\n", idx, modArgs[idx]);
            if (modArgs[idx] != 0) {
                //if (!dvmIsValidObject((Object*) modArgs[idx]))
                //    dvmAbort();
                jobject argObj = addLocalReference(env, (Object*) modArgs[idx]);
                if (argObj == NULL) {
                    assert(dvmCheckException(self));
                    return;
                }
                modArgs[idx] = (u4) argObj;
            }
            break;
        case 'D':
        case 'J':
            idx++;
            break;
        default:
            /* Z B C S I -- do nothing */
            break;
        }

        idx++;
    }
#else
    staticMethodClass = dvmIsStaticMethod(method) ?
        (jclass) method->clazz : NULL;
#endif

    oldStatus = dvmChangeStatus(self, THREAD_NATIVE);

    ANDROID_MEMBAR_FULL();      /* guarantee ordering on method->insns */
    assert(method->insns != NULL);

    COMPUTE_STACK_SUM(self);
    dvmPlatformInvoke(env, staticMethodClass,
        method->jniArgInfo, method->insSize, modArgs, method->shorty,
        (void*)method->insns, pResult);
    CHECK_STACK_SUM(self);

    dvmChangeStatus(self, oldStatus);

    convertReferenceResult(env, pResult, method, self);
}

/*
 * Handler for the unusual case of a synchronized native method.
 *
 * Lock the object, then call through the general function.
 */
void dvmCallJNIMethod_synchronized(const u4* args, JValue* pResult,
    const Method* method, Thread* self)
{
    Object* lockObj;

    assert(dvmIsSynchronizedMethod(method));

    if (dvmIsStaticMethod(method))
        lockObj = (Object*) method->clazz;
    else
        lockObj = (Object*) args[0];

    LOGVV("Calling %s.%s: locking %p (%s)\n",
        method->clazz->descriptor, method->name,
        lockObj, lockObj->clazz->descriptor);

    dvmLockObject(self, lockObj);
    dvmCallJNIMethod_general(args, pResult, method, self);
    dvmUnlockObject(self, lockObj);
}

/*
 * Virtual method call, no reference arguments.
 *
 * We need to local-ref the "this" argument, found in args[0].
 */
void dvmCallJNIMethod_virtualNoRef(const u4* args, JValue* pResult,
    const Method* method, Thread* self)
{
    u4* modArgs = (u4*) args;
    int oldStatus;

#ifdef USE_INDIRECT_REF
    jobject thisObj = addLocalReference(self->jniEnv, (Object*) args[0]);
    if (thisObj == NULL) {
        assert(dvmCheckException(self));
        return;
    }
    modArgs[0] = (u4) thisObj;
#endif

    oldStatus = dvmChangeStatus(self, THREAD_NATIVE);

    ANDROID_MEMBAR_FULL();      /* guarantee ordering on method->insns */

    COMPUTE_STACK_SUM(self);
    dvmPlatformInvoke(self->jniEnv, NULL,
        method->jniArgInfo, method->insSize, modArgs, method->shorty,
        (void*)method->insns, pResult);
    CHECK_STACK_SUM(self);

    dvmChangeStatus(self, oldStatus);

    convertReferenceResult(self->jniEnv, pResult, method, self);
}

/*
 * Static method call, no reference arguments.
 *
 * We need to local-ref the class reference.
 */
void dvmCallJNIMethod_staticNoRef(const u4* args, JValue* pResult,
    const Method* method, Thread* self)
{
    jclass staticMethodClass;
    int oldStatus;

#ifdef USE_INDIRECT_REF
    staticMethodClass = addLocalReference(self->jniEnv, (Object*)method->clazz);
    if (staticMethodClass == NULL) {
        assert(dvmCheckException(self));
        return;
    }
#else
    staticMethodClass = (jobject) method->clazz;
#endif

    oldStatus = dvmChangeStatus(self, THREAD_NATIVE);

    ANDROID_MEMBAR_FULL();      /* guarantee ordering on method->insns */

    COMPUTE_STACK_SUM(self);
    dvmPlatformInvoke(self->jniEnv, staticMethodClass,
        method->jniArgInfo, method->insSize, args, method->shorty,
        (void*)method->insns, pResult);
    CHECK_STACK_SUM(self);

    dvmChangeStatus(self, oldStatus);

    convertReferenceResult(self->jniEnv, pResult, method, self);
}

/*
 * Extract the return type enum from the "jniArgInfo" field.
 */
DalvikJniReturnType dvmGetArgInfoReturnType(int jniArgInfo)
{
    return (jniArgInfo & DALVIK_JNI_RETURN_MASK) >> DALVIK_JNI_RETURN_SHIFT;
}


/*
 * ===========================================================================
 *      JNI implementation
 * ===========================================================================
 */

/*
 * Return the version of the native method interface.
 */
static jint GetVersion(JNIEnv* env)
{
    JNI_ENTER();
    /*
     * There is absolutely no need to toggle the mode for correct behavior.
     * However, it does provide native code with a simple "suspend self
     * if necessary" call.
     */
    JNI_EXIT();
    return JNI_VERSION_1_6;
}

/*
 * Create a new class from a bag of bytes.
 *
 * This is not currently supported within Dalvik.
 */
static jclass DefineClass(JNIEnv* env, const char *name, jobject loader,
    const jbyte* buf, jsize bufLen)
{
    UNUSED_PARAMETER(name);
    UNUSED_PARAMETER(loader);
    UNUSED_PARAMETER(buf);
    UNUSED_PARAMETER(bufLen);

    JNI_ENTER();
    LOGW("JNI DefineClass is not supported\n");
    JNI_EXIT();
    return NULL;
}

/*
 * Find a class by name.
 *
 * We have to use the "no init" version of FindClass here, because we might
 * be getting the class prior to registering native methods that will be
 * used in <clinit>.
 *
 * We need to get the class loader associated with the current native
 * method.  If there is no native method, e.g. we're calling this from native
 * code right after creating the VM, the spec says we need to use the class
 * loader returned by "ClassLoader.getBaseClassLoader".  There is no such
 * method, but it's likely they meant ClassLoader.getSystemClassLoader.
 * We can't get that until after the VM has initialized though.
 */
static jclass FindClass(JNIEnv* env, const char* name)
{
    JNI_ENTER();

    const Method* thisMethod;
    ClassObject* clazz;
    jclass jclazz = NULL;
    Object* loader;
    Object* trackedLoader = NULL;
    char* descriptor = NULL;

    thisMethod = dvmGetCurrentJNIMethod();
    assert(thisMethod != NULL);

    descriptor = dvmNameToDescriptor(name);
    if (descriptor == NULL) {
        clazz = NULL;
        goto bail;
    }

    //Thread* self = dvmThreadSelf();
    if (_self->classLoaderOverride != NULL) {
        /* hack for JNI_OnLoad */
        assert(strcmp(thisMethod->name, "nativeLoad") == 0);
        loader = _self->classLoaderOverride;
    } else if (thisMethod == gDvm.methFakeNativeEntry) {
        /* start point of invocation interface */
        if (!gDvm.initializing)
            loader = trackedLoader = dvmGetSystemClassLoader();
        else
            loader = NULL;
    } else {
        loader = thisMethod->clazz->classLoader;
    }

    clazz = dvmFindClassNoInit(descriptor, loader);
    jclazz = addLocalReference(env, (Object*) clazz);

    dvmReleaseTrackedAlloc(trackedLoader, _self);

bail:
    free(descriptor);

    JNI_EXIT();
    return jclazz;
}

/*
 * Return the superclass of a class.
 */
static jclass GetSuperclass(JNIEnv* env, jclass jclazz)
{
    JNI_ENTER();
    jclass jsuper = NULL;

    ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(env, jclazz);
    if (clazz != NULL)
        jsuper = addLocalReference(env, (Object*)clazz->super);
    JNI_EXIT();
    return jsuper;
}

/*
 * Determine whether an object of clazz1 can be safely cast to clazz2.
 *
 * Like IsInstanceOf, but with a pair of class objects instead of obj+class.
 */
static jboolean IsAssignableFrom(JNIEnv* env, jclass jclazz1, jclass jclazz2)
{
    JNI_ENTER();

    ClassObject* clazz1 = (ClassObject*) dvmDecodeIndirectRef(env, jclazz1);
    ClassObject* clazz2 = (ClassObject*) dvmDecodeIndirectRef(env, jclazz2);

    jboolean result = dvmInstanceof(clazz1, clazz2);

    JNI_EXIT();
    return result;
}

/*
 * Given a java.lang.reflect.Method or .Constructor, return a methodID.
 */
static jmethodID FromReflectedMethod(JNIEnv* env, jobject jmethod)
{
    JNI_ENTER();
    jmethodID methodID;
    Object* method = dvmDecodeIndirectRef(env, jmethod);
    methodID = (jmethodID) dvmGetMethodFromReflectObj(method);
    JNI_EXIT();
    return methodID;
}

/*
 * Given a java.lang.reflect.Field, return a fieldID.
 */
static jfieldID FromReflectedField(JNIEnv* env, jobject jfield)
{
    JNI_ENTER();
    jfieldID fieldID;
    Object* field = dvmDecodeIndirectRef(env, jfield);
    fieldID = (jfieldID) dvmGetFieldFromReflectObj(field);
    JNI_EXIT();
    return fieldID;
}

/*
 * Convert a methodID to a java.lang.reflect.Method or .Constructor.
 *
 * (The "isStatic" field does not appear in the spec.)
 *
 * Throws OutOfMemory and returns NULL on failure.
 */
static jobject ToReflectedMethod(JNIEnv* env, jclass jcls, jmethodID methodID,
    jboolean isStatic)
{
    JNI_ENTER();
    ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(env, jcls);
    Object* obj = dvmCreateReflectObjForMethod(clazz, (Method*) methodID);
    dvmReleaseTrackedAlloc(obj, NULL);
    jobject jobj = addLocalReference(env, obj);
    JNI_EXIT();
    return jobj;
}

/*
 * Convert a fieldID to a java.lang.reflect.Field.
 *
 * (The "isStatic" field does not appear in the spec.)
 *
 * Throws OutOfMemory and returns NULL on failure.
 */
static jobject ToReflectedField(JNIEnv* env, jclass jcls, jfieldID fieldID,
    jboolean isStatic)
{
    JNI_ENTER();
    ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(env, jcls);
    Object* obj = dvmCreateReflectObjForField(clazz, (Field*) fieldID);
    dvmReleaseTrackedAlloc(obj, NULL);
    jobject jobj = addLocalReference(env, obj);
    JNI_EXIT();
    return jobj;
}

/*
 * Take this exception and throw it.
 */
static jint Throw(JNIEnv* env, jthrowable jobj)
{
    JNI_ENTER();

    jint retval;

    if (jobj != NULL) {
        Object* obj = dvmDecodeIndirectRef(env, jobj);
        dvmSetException(_self, obj);
        retval = JNI_OK;
    } else {
        retval = JNI_ERR;
    }

    JNI_EXIT();
    return retval;
}

/*
 * Constructs an exception object from the specified class with the message
 * specified by "message", and throws it.
 */
static jint ThrowNew(JNIEnv* env, jclass jclazz, const char* message)
{
    JNI_ENTER();

    ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(env, jclazz);
    dvmThrowExceptionByClass(clazz, message);
    // TODO: should return failure if this didn't work (e.g. OOM)

    JNI_EXIT();
    return JNI_OK;
}

/*
 * If an exception is being thrown, return the exception object.  Otherwise,
 * return NULL.
 *
 * TODO: if there is no pending exception, we should be able to skip the
 * enter/exit checks.  If we find one, we need to enter and then re-fetch
 * the exception (in case it got moved by a compacting GC).
 */
static jthrowable ExceptionOccurred(JNIEnv* env)
{
    JNI_ENTER();

    Object* exception;
    jobject localException;

    exception = dvmGetException(_self);
    localException = addLocalReference(env, exception);
    if (localException == NULL && exception != NULL) {
        /*
         * We were unable to add a new local reference, and threw a new
         * exception.  We can't return "exception", because it's not a
         * local reference.  So we have to return NULL, indicating that
         * there was no exception, even though it's pretty much raining
         * exceptions in here.
         */
        LOGW("JNI WARNING: addLocal/exception combo\n");
    }

    JNI_EXIT();
    return localException;
}

/*
 * Print an exception and stack trace to stderr.
 */
static void ExceptionDescribe(JNIEnv* env)
{
    JNI_ENTER();

    Object* exception = dvmGetException(_self);
    if (exception != NULL) {
        dvmPrintExceptionStackTrace();
    } else {
        LOGI("Odd: ExceptionDescribe called, but no exception pending\n");
    }

    JNI_EXIT();
}

/*
 * Clear the exception currently being thrown.
 *
 * TODO: we should be able to skip the enter/exit stuff.
 */
static void ExceptionClear(JNIEnv* env)
{
    JNI_ENTER();
    dvmClearException(_self);
    JNI_EXIT();
}

/*
 * Kill the VM.  This function does not return.
 */
static void FatalError(JNIEnv* env, const char* msg)
{
    //dvmChangeStatus(NULL, THREAD_RUNNING);
    LOGE("JNI posting fatal error: %s\n", msg);
    dvmAbort();
}

/*
 * Push a new JNI frame on the stack, with a new set of locals.
 *
 * The new frame must have the same method pointer.  (If for no other
 * reason than FindClass needs it to get the appropriate class loader.)
 */
static jint PushLocalFrame(JNIEnv* env, jint capacity)
{
    JNI_ENTER();
    int result = JNI_OK;
    if (!ensureLocalCapacity(env, capacity) ||
        !dvmPushLocalFrame(_self /*dvmThreadSelf()*/, dvmGetCurrentJNIMethod()))
    {
        /* yes, OutOfMemoryError, not StackOverflowError */
        dvmClearException(_self);
        dvmThrowException("Ljava/lang/OutOfMemoryError;",
            "out of stack in JNI PushLocalFrame");
        result = JNI_ERR;
    }
    JNI_EXIT();
    return result;
}

/*
 * Pop the local frame off.  If "result" is not null, add it as a
 * local reference on the now-current frame.
 */
static jobject PopLocalFrame(JNIEnv* env, jobject jresult)
{
    JNI_ENTER();
    Object* result = dvmDecodeIndirectRef(env, jresult);
    if (!dvmPopLocalFrame(_self /*dvmThreadSelf()*/)) {
        LOGW("JNI WARNING: too many PopLocalFrame calls\n");
        dvmClearException(_self);
        dvmThrowException("Ljava/lang/RuntimeException;",
            "too many PopLocalFrame calls");
    }
    jresult = addLocalReference(env, result);
    JNI_EXIT();
    return result;
}

/*
 * Add a reference to the global list.
 */
static jobject NewGlobalRef(JNIEnv* env, jobject jobj)
{
    Object* obj;

    JNI_ENTER();
    if (dvmIsWeakGlobalRef(jobj))
        obj = getPhantomReferent(env, (jweak) jobj);
    else
        obj = dvmDecodeIndirectRef(env, jobj);
    jobject retval = addGlobalReference(obj);
    JNI_EXIT();
    return retval;
}

/*
 * Delete a reference from the global list.
 */
static void DeleteGlobalRef(JNIEnv* env, jobject jglobalRef)
{
    JNI_ENTER();
    deleteGlobalReference(jglobalRef);
    JNI_EXIT();
}


/*
 * Add a reference to the local list.
 */
static jobject NewLocalRef(JNIEnv* env, jobject jobj)
{
    Object* obj;

    JNI_ENTER();
    if (dvmIsWeakGlobalRef(jobj))
        obj = getPhantomReferent(env, (jweak) jobj);
    else
        obj = dvmDecodeIndirectRef(env, jobj);
    jobject retval = addLocalReference(env, obj);
    JNI_EXIT();
    return retval;
}

/*
 * Delete a reference from the local list.
 */
static void DeleteLocalRef(JNIEnv* env, jobject jlocalRef)
{
    JNI_ENTER();
    deleteLocalReference(env, jlocalRef);
    JNI_EXIT();
}

/*
 * Ensure that the local references table can hold at least this many
 * references.
 */
static jint EnsureLocalCapacity(JNIEnv* env, jint capacity)
{
    JNI_ENTER();
    bool okay = ensureLocalCapacity(env, capacity);
    if (!okay) {
        dvmThrowException("Ljava/lang/OutOfMemoryError;",
            "can't ensure local reference capacity");
    }
    JNI_EXIT();
    if (okay)
        return 0;
    else
        return -1;
}


/*
 * Determine whether two Object references refer to the same underlying object.
 */
static jboolean IsSameObject(JNIEnv* env, jobject jref1, jobject jref2)
{
    JNI_ENTER();
    Object* obj1 = dvmDecodeIndirectRef(env, jref1);
    Object* obj2 = dvmDecodeIndirectRef(env, jref2);
    jboolean result = (obj1 == obj2);
    JNI_EXIT();
    return result;
}

/*
 * Allocate a new object without invoking any constructors.
 */
static jobject AllocObject(JNIEnv* env, jclass jclazz)
{
    JNI_ENTER();

    ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(env, jclazz);
    jobject result;

    if (!canAllocClass(clazz) ||
        (!dvmIsClassInitialized(clazz) && !dvmInitClass(clazz)))
    {
        assert(dvmCheckException(_self));
        result = NULL;
    } else {
        Object* newObj = dvmAllocObject(clazz, ALLOC_DONT_TRACK);
        result = addLocalReference(env, newObj);
    }

    JNI_EXIT();
    return result;
}

/*
 * Allocate a new object and invoke the supplied constructor.
 */
static jobject NewObject(JNIEnv* env, jclass jclazz, jmethodID methodID, ...)
{
    JNI_ENTER();
    ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(env, jclazz);
    jobject result;

    if (!canAllocClass(clazz) ||
        (!dvmIsClassInitialized(clazz) && !dvmInitClass(clazz)))
    {
        assert(dvmCheckException(_self));
        result = NULL;
    } else {
        Object* newObj = dvmAllocObject(clazz, ALLOC_DONT_TRACK);
        result = addLocalReference(env, newObj);
        if (newObj != NULL) {
            JValue unused;
            va_list args;
            va_start(args, methodID);
            dvmCallMethodV(_self, (Method*) methodID, newObj, true, &unused,
                args);
            va_end(args);
        }
    }

    JNI_EXIT();
    return result;
}
static jobject NewObjectV(JNIEnv* env, jclass jclazz, jmethodID methodID,
    va_list args)
{
    JNI_ENTER();
    ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(env, jclazz);
    jobject result;

    if (!canAllocClass(clazz) ||
        (!dvmIsClassInitialized(clazz) && !dvmInitClass(clazz)))
    {
        assert(dvmCheckException(_self));
        result = NULL;
    } else {
        Object* newObj = dvmAllocObject(clazz, ALLOC_DONT_TRACK);
        result = addLocalReference(env, newObj);
        if (newObj != NULL) {
            JValue unused;
            dvmCallMethodV(_self, (Method*) methodID, newObj, true, &unused,
                args);
        }
    }

    JNI_EXIT();
    return result;
}
static jobject NewObjectA(JNIEnv* env, jclass jclazz, jmethodID methodID,
    jvalue* args)
{
    JNI_ENTER();
    ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(env, jclazz);
    jobject result;

    if (!canAllocClass(clazz) ||
        (!dvmIsClassInitialized(clazz) && !dvmInitClass(clazz)))
    {
        assert(dvmCheckException(_self));
        result = NULL;
    } else {
        Object* newObj = dvmAllocObject(clazz, ALLOC_DONT_TRACK);
        result = addLocalReference(env, newObj);
        if (newObj != NULL) {
            JValue unused;
            dvmCallMethodA(_self, (Method*) methodID, newObj, true, &unused,
                args);
        }
    }

    JNI_EXIT();
    return result;
}

/*
 * Returns the class of an object.
 *
 * JNI spec says: obj must not be NULL.
 */
static jclass GetObjectClass(JNIEnv* env, jobject jobj)
{
    JNI_ENTER();

    assert(jobj != NULL);

    Object* obj = dvmDecodeIndirectRef(env, jobj);
    jclass jclazz = addLocalReference(env, (Object*) obj->clazz);

    JNI_EXIT();
    return jclazz;
}

/*
 * Determine whether "obj" is an instance of "clazz".
 */
static jboolean IsInstanceOf(JNIEnv* env, jobject jobj, jclass jclazz)
{
    JNI_ENTER();

    assert(jclazz != NULL);

    jboolean result;

    if (jobj == NULL) {
        result = true;
    } else {
        Object* obj = dvmDecodeIndirectRef(env, jobj);
        ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(env, jclazz);
        result = dvmInstanceof(obj->clazz, clazz);
    }

    JNI_EXIT();
    return result;
}

/*
 * Get a method ID for an instance method.
 *
 * JNI defines <init> as an instance method, but Dalvik considers it a
 * "direct" method, so we have to special-case it here.
 *
 * Dalvik also puts all private methods into the "direct" list, so we
 * really need to just search both lists.
 */
static jmethodID GetMethodID(JNIEnv* env, jclass jclazz, const char* name,
    const char* sig)
{
    JNI_ENTER();

    ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(env, jclazz);
    jmethodID id = NULL;

    if (!dvmIsClassInitialized(clazz) && !dvmInitClass(clazz)) {
        assert(dvmCheckException(_self));
    } else {
        Method* meth;

        meth = dvmFindVirtualMethodHierByDescriptor(clazz, name, sig);
        if (meth == NULL) {
            /* search private methods and constructors; non-hierarchical */
            meth = dvmFindDirectMethodByDescriptor(clazz, name, sig);
        }
        if (meth != NULL && dvmIsStaticMethod(meth)) {
            IF_LOGD() {
                char* desc = dexProtoCopyMethodDescriptor(&meth->prototype);
                LOGD("GetMethodID: not returning static method %s.%s %s\n",
                    clazz->descriptor, meth->name, desc);
                free(desc);
            }
            meth = NULL;
        }
        if (meth == NULL) {
            LOGD("GetMethodID: method not found: %s.%s:%s\n",
                clazz->descriptor, name, sig);
            dvmThrowException("Ljava/lang/NoSuchMethodError;", name);
        }

        /*
         * The method's class may not be the same as clazz, but if
         * it isn't this must be a virtual method and the class must
         * be a superclass (and, hence, already initialized).
         */
        if (meth != NULL) {
            assert(dvmIsClassInitialized(meth->clazz) ||
                   dvmIsClassInitializing(meth->clazz));
        }
        id = (jmethodID) meth;
    }
    JNI_EXIT();
    return id;
}

/*
 * Get a field ID (instance fields).
 */
static jfieldID GetFieldID(JNIEnv* env, jclass jclazz,
    const char* name, const char* sig)
{
    JNI_ENTER();

    ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(env, jclazz);
    jfieldID id;

    if (!dvmIsClassInitialized(clazz) && !dvmInitClass(clazz)) {
        assert(dvmCheckException(_self));
        id = NULL;
    } else {
        id = (jfieldID) dvmFindInstanceFieldHier(clazz, name, sig);
        if (id == NULL) {
            LOGD("GetFieldID: unable to find field %s.%s:%s\n",
                clazz->descriptor, name, sig);
            dvmThrowException("Ljava/lang/NoSuchFieldError;", name);
        }
    }
    JNI_EXIT();
    return id;
}

/*
 * Get the method ID for a static method in a class.
 */
static jmethodID GetStaticMethodID(JNIEnv* env, jclass jclazz,
    const char* name, const char* sig)
{
    JNI_ENTER();

    ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(env, jclazz);
    jmethodID id;

    if (!dvmIsClassInitialized(clazz) && !dvmInitClass(clazz)) {
        assert(dvmCheckException(_self));
        id = NULL;
    } else {
        Method* meth;

        meth = dvmFindDirectMethodHierByDescriptor(clazz, name, sig);

        /* make sure it's static, not virtual+private */
        if (meth != NULL && !dvmIsStaticMethod(meth)) {
            IF_LOGD() {
                char* desc = dexProtoCopyMethodDescriptor(&meth->prototype);
                LOGD("GetStaticMethodID: "
                    "not returning nonstatic method %s.%s %s\n",
                    clazz->descriptor, meth->name, desc);
                free(desc);
            }
            meth = NULL;
        }

        id = (jmethodID) meth;
        if (id == NULL)
            dvmThrowException("Ljava/lang/NoSuchMethodError;", name);
    }

    JNI_EXIT();
    return id;
}

/*
 * Get a field ID (static fields).
 */
static jfieldID GetStaticFieldID(JNIEnv* env, jclass jclazz,
    const char* name, const char* sig)
{
    JNI_ENTER();

    ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(env, jclazz);
    jfieldID id;

    if (!dvmIsClassInitialized(clazz) && !dvmInitClass(clazz)) {
        assert(dvmCheckException(_self));
        id = NULL;
    } else {
        id = (jfieldID) dvmFindStaticField(clazz, name, sig);
        if (id == NULL)
            dvmThrowException("Ljava/lang/NoSuchFieldError;", name);
    }
    JNI_EXIT();
    return id;
}

/*
 * Get a static field.
 *
 * If we get an object reference, add it to the local refs list.
 */
#define GET_STATIC_TYPE_FIELD(_ctype, _jname, _isref)                       \
    static _ctype GetStatic##_jname##Field(JNIEnv* env, jclass jclazz,      \
        jfieldID fieldID)                                                   \
    {                                                                       \
        UNUSED_PARAMETER(jclazz);                                           \
        JNI_ENTER();                                                        \
        StaticField* sfield = (StaticField*) fieldID;                       \
        _ctype value;                                                       \
        if (dvmIsVolatileField(&sfield->field)) {                           \
            if (_isref) {   /* only when _ctype==jobject */                 \
                Object* obj = dvmGetStaticFieldObjectVolatile(sfield);      \
                value = (_ctype)(u4)addLocalReference(env, obj);            \
            } else {                                                        \
                value = dvmGetStaticField##_jname##Volatile(sfield);        \
            }                                                               \
        } else {                                                            \
            if (_isref) {                                                   \
                Object* obj = dvmGetStaticFieldObject(sfield);              \
                value = (_ctype)(u4)addLocalReference(env, obj);            \
            } else {                                                        \
                value = dvmGetStaticField##_jname(sfield);                  \
            }                                                               \
        }                                                                   \
        JNI_EXIT();                                                         \
        return value;                                                       \
    }
GET_STATIC_TYPE_FIELD(jobject, Object, true);
GET_STATIC_TYPE_FIELD(jboolean, Boolean, false);
GET_STATIC_TYPE_FIELD(jbyte, Byte, false);
GET_STATIC_TYPE_FIELD(jchar, Char, false);
GET_STATIC_TYPE_FIELD(jshort, Short, false);
GET_STATIC_TYPE_FIELD(jint, Int, false);
GET_STATIC_TYPE_FIELD(jlong, Long, false);
GET_STATIC_TYPE_FIELD(jfloat, Float, false);
GET_STATIC_TYPE_FIELD(jdouble, Double, false);

/*
 * Set a static field.
 */
#define SET_STATIC_TYPE_FIELD(_ctype, _jname, _isref)                       \
    static void SetStatic##_jname##Field(JNIEnv* env, jclass jclazz,        \
        jfieldID fieldID, _ctype value)                                     \
    {                                                                       \
        UNUSED_PARAMETER(jclazz);                                           \
        JNI_ENTER();                                                        \
        StaticField* sfield = (StaticField*) fieldID;                       \
        if (dvmIsVolatileField(&sfield->field)) {                           \
            if (_isref) {   /* only when _ctype==jobject */                 \
                Object* valObj =                                            \
                    dvmDecodeIndirectRef(env, (jobject)(u4)value);          \
                dvmSetStaticFieldObjectVolatile(sfield, valObj);            \
            } else {                                                        \
                dvmSetStaticField##_jname##Volatile(sfield, value);         \
            }                                                               \
        } else {                                                            \
            if (_isref) {                                                   \
                Object* valObj =                                            \
                    dvmDecodeIndirectRef(env, (jobject)(u4)value);          \
                dvmSetStaticFieldObject(sfield, valObj);                    \
            } else {                                                        \
                dvmSetStaticField##_jname(sfield, value);                   \
            }                                                               \
        }                                                                   \
        JNI_EXIT();                                                         \
    }
SET_STATIC_TYPE_FIELD(jobject, Object, true);
SET_STATIC_TYPE_FIELD(jboolean, Boolean, false);
SET_STATIC_TYPE_FIELD(jbyte, Byte, false);
SET_STATIC_TYPE_FIELD(jchar, Char, false);
SET_STATIC_TYPE_FIELD(jshort, Short, false);
SET_STATIC_TYPE_FIELD(jint, Int, false);
SET_STATIC_TYPE_FIELD(jlong, Long, false);
SET_STATIC_TYPE_FIELD(jfloat, Float, false);
SET_STATIC_TYPE_FIELD(jdouble, Double, false);

/*
 * Get an instance field.
 *
 * If we get an object reference, add it to the local refs list.
 */
#define GET_TYPE_FIELD(_ctype, _jname, _isref)                              \
    static _ctype Get##_jname##Field(JNIEnv* env, jobject jobj,             \
        jfieldID fieldID)                                                   \
    {                                                                       \
        JNI_ENTER();                                                        \
        Object* obj = dvmDecodeIndirectRef(env, jobj);                      \
        InstField* field = (InstField*) fieldID;                            \
        _ctype value;                                                       \
        if (dvmIsVolatileField(&field->field)) {                            \
            if (_isref) {   /* only when _ctype==jobject */                 \
                Object* valObj =                                            \
                    dvmGetFieldObjectVolatile(obj, field->byteOffset);      \
                value = (_ctype)(u4)addLocalReference(env, valObj);         \
            } else {                                                        \
                value =                                                     \
                    dvmGetField##_jname##Volatile(obj, field->byteOffset);  \
            }                                                               \
        } else {                                                            \
            if (_isref) {                                                   \
                Object* valObj = dvmGetFieldObject(obj, field->byteOffset); \
                value = (_ctype)(u4)addLocalReference(env, valObj);         \
            } else {                                                        \
                value = dvmGetField##_jname(obj, field->byteOffset);        \
            }                                                               \
        }                                                                   \
        JNI_EXIT();                                                         \
        return value;                                                       \
    }
GET_TYPE_FIELD(jobject, Object, true);
GET_TYPE_FIELD(jboolean, Boolean, false);
GET_TYPE_FIELD(jbyte, Byte, false);
GET_TYPE_FIELD(jchar, Char, false);
GET_TYPE_FIELD(jshort, Short, false);
GET_TYPE_FIELD(jint, Int, false);
GET_TYPE_FIELD(jlong, Long, false);
GET_TYPE_FIELD(jfloat, Float, false);
GET_TYPE_FIELD(jdouble, Double, false);

/*
 * Set an instance field.
 */
#define SET_TYPE_FIELD(_ctype, _jname, _isref)                              \
    static void Set##_jname##Field(JNIEnv* env, jobject jobj,               \
        jfieldID fieldID, _ctype value)                                     \
    {                                                                       \
        JNI_ENTER();                                                        \
        Object* obj = dvmDecodeIndirectRef(env, jobj);                      \
        InstField* field = (InstField*) fieldID;                            \
        if (dvmIsVolatileField(&field->field)) {                            \
            if (_isref) {   /* only when _ctype==jobject */                 \
                Object* valObj =                                            \
                    dvmDecodeIndirectRef(env, (jobject)(u4)value);          \
                dvmSetFieldObjectVolatile(obj, field->byteOffset, valObj);  \
            } else {                                                        \
                dvmSetField##_jname##Volatile(obj,                          \
                    field->byteOffset, value);                              \
            }                                                               \
        } else {                                                            \
            if (_isref) {                                                   \
                Object* valObj =                                            \
                    dvmDecodeIndirectRef(env, (jobject)(u4)value);          \
                dvmSetFieldObject(obj, field->byteOffset, valObj);          \
            } else {                                                        \
                dvmSetField##_jname(obj, field->byteOffset, value);         \
            }                                                               \
        }                                                                   \
        JNI_EXIT();                                                         \
    }
SET_TYPE_FIELD(jobject, Object, true);
SET_TYPE_FIELD(jboolean, Boolean, false);
SET_TYPE_FIELD(jbyte, Byte, false);
SET_TYPE_FIELD(jchar, Char, false);
SET_TYPE_FIELD(jshort, Short, false);
SET_TYPE_FIELD(jint, Int, false);
SET_TYPE_FIELD(jlong, Long, false);
SET_TYPE_FIELD(jfloat, Float, false);
SET_TYPE_FIELD(jdouble, Double, false);

/*
 * Make a virtual method call.
 *
 * Three versions (..., va_list, jvalue[]) for each return type.  If we're
 * returning an Object, we have to add it to the local references table.
 */
#define CALL_VIRTUAL(_ctype, _jname, _retfail, _retok, _isref)              \
    static _ctype Call##_jname##Method(JNIEnv* env, jobject jobj,           \
        jmethodID methodID, ...)                                            \
    {                                                                       \
        JNI_ENTER();                                                        \
        Object* obj = dvmDecodeIndirectRef(env, jobj);                      \
        const Method* meth;                                                 \
        va_list args;                                                       \
        JValue result;                                                      \
        meth = dvmGetVirtualizedMethod(obj->clazz, (Method*)methodID);      \
        if (meth == NULL) {                                                 \
            JNI_EXIT();                                                     \
            return _retfail;                                                \
        }                                                                   \
        va_start(args, methodID);                                           \
        dvmCallMethodV(_self, meth, obj, true, &result, args);              \
        va_end(args);                                                       \
        if (_isref && !dvmCheckException(_self))                            \
            result.l = addLocalReference(env, result.l);                    \
        JNI_EXIT();                                                         \
        return _retok;                                                      \
    }                                                                       \
    static _ctype Call##_jname##MethodV(JNIEnv* env, jobject jobj,          \
        jmethodID methodID, va_list args)                                   \
    {                                                                       \
        JNI_ENTER();                                                        \
        Object* obj = dvmDecodeIndirectRef(env, jobj);                      \
        const Method* meth;                                                 \
        JValue result;                                                      \
        meth = dvmGetVirtualizedMethod(obj->clazz, (Method*)methodID);      \
        if (meth == NULL) {                                                 \
            JNI_EXIT();                                                     \
            return _retfail;                                                \
        }                                                                   \
        dvmCallMethodV(_self, meth, obj, true, &result, args);              \
        if (_isref && !dvmCheckException(_self))                            \
            result.l = addLocalReference(env, result.l);                    \
        JNI_EXIT();                                                         \
        return _retok;                                                      \
    }                                                                       \
    static _ctype Call##_jname##MethodA(JNIEnv* env, jobject jobj,          \
        jmethodID methodID, jvalue* args)                                   \
    {                                                                       \
        JNI_ENTER();                                                        \
        Object* obj = dvmDecodeIndirectRef(env, jobj);                      \
        const Method* meth;                                                 \
        JValue result;                                                      \
        meth = dvmGetVirtualizedMethod(obj->clazz, (Method*)methodID);      \
        if (meth == NULL) {                                                 \
            JNI_EXIT();                                                     \
            return _retfail;                                                \
        }                                                                   \
        dvmCallMethodA(_self, meth, obj, true, &result, args);              \
        if (_isref && !dvmCheckException(_self))                            \
            result.l = addLocalReference(env, result.l);                    \
        JNI_EXIT();                                                         \
        return _retok;                                                      \
    }
CALL_VIRTUAL(jobject, Object, NULL, result.l, true);
CALL_VIRTUAL(jboolean, Boolean, 0, result.z, false);
CALL_VIRTUAL(jbyte, Byte, 0, result.b, false);
CALL_VIRTUAL(jchar, Char, 0, result.c, false);
CALL_VIRTUAL(jshort, Short, 0, result.s, false);
CALL_VIRTUAL(jint, Int, 0, result.i, false);
CALL_VIRTUAL(jlong, Long, 0, result.j, false);
CALL_VIRTUAL(jfloat, Float, 0.0f, result.f, false);
CALL_VIRTUAL(jdouble, Double, 0.0, result.d, false);
CALL_VIRTUAL(void, Void, , , false);

/*
 * Make a "non-virtual" method call.  We're still calling a virtual method,
 * but this time we're not doing an indirection through the object's vtable.
 * The "clazz" parameter defines which implementation of a method we want.
 *
 * Three versions (..., va_list, jvalue[]) for each return type.
 */
#define CALL_NONVIRTUAL(_ctype, _jname, _retfail, _retok, _isref)           \
    static _ctype CallNonvirtual##_jname##Method(JNIEnv* env, jobject jobj, \
        jclass jclazz, jmethodID methodID, ...)                             \
    {                                                                       \
        JNI_ENTER();                                                        \
        Object* obj = dvmDecodeIndirectRef(env, jobj);                      \
        ClassObject* clazz =                                                \
            (ClassObject*) dvmDecodeIndirectRef(env, jclazz);               \
        const Method* meth;                                                 \
        va_list args;                                                       \
        JValue result;                                                      \
        meth = dvmGetVirtualizedMethod(clazz, (Method*)methodID);           \
        if (meth == NULL) {                                                 \
            JNI_EXIT();                                                     \
            return _retfail;                                                \
        }                                                                   \
        va_start(args, methodID);                                           \
        dvmCallMethodV(_self, meth, obj, true, &result, args);              \
        if (_isref && !dvmCheckException(_self))                            \
            result.l = addLocalReference(env, result.l);                    \
        va_end(args);                                                       \
        JNI_EXIT();                                                         \
        return _retok;                                                      \
    }                                                                       \
    static _ctype CallNonvirtual##_jname##MethodV(JNIEnv* env, jobject jobj,\
        jclass jclazz, jmethodID methodID, va_list args)                    \
    {                                                                       \
        JNI_ENTER();                                                        \
        Object* obj = dvmDecodeIndirectRef(env, jobj);                      \
        ClassObject* clazz =                                                \
            (ClassObject*) dvmDecodeIndirectRef(env, jclazz);               \
        const Method* meth;                                                 \
        JValue result;                                                      \
        meth = dvmGetVirtualizedMethod(clazz, (Method*)methodID);           \
        if (meth == NULL) {                                                 \
            JNI_EXIT();                                                     \
            return _retfail;                                                \
        }                                                                   \
        dvmCallMethodV(_self, meth, obj, true, &result, args);              \
        if (_isref && !dvmCheckException(_self))                            \
            result.l = addLocalReference(env, result.l);                    \
        JNI_EXIT();                                                         \
        return _retok;                                                      \
    }                                                                       \
    static _ctype CallNonvirtual##_jname##MethodA(JNIEnv* env, jobject jobj,\
        jclass jclazz, jmethodID methodID, jvalue* args)                    \
    {                                                                       \
        JNI_ENTER();                                                        \
        Object* obj = dvmDecodeIndirectRef(env, jobj);                      \
        ClassObject* clazz =                                                \
            (ClassObject*) dvmDecodeIndirectRef(env, jclazz);               \
        const Method* meth;                                                 \
        JValue result;                                                      \
        meth = dvmGetVirtualizedMethod(clazz, (Method*)methodID);           \
        if (meth == NULL) {                                                 \
            JNI_EXIT();                                                     \
            return _retfail;                                                \
        }                                                                   \
        dvmCallMethodA(_self, meth, obj, true, &result, args);              \
        if (_isref && !dvmCheckException(_self))                            \
            result.l = addLocalReference(env, result.l);                    \
        JNI_EXIT();                                                         \
        return _retok;                                                      \
    }
CALL_NONVIRTUAL(jobject, Object, NULL, result.l, true);
CALL_NONVIRTUAL(jboolean, Boolean, 0, result.z, false);
CALL_NONVIRTUAL(jbyte, Byte, 0, result.b, false);
CALL_NONVIRTUAL(jchar, Char, 0, result.c, false);
CALL_NONVIRTUAL(jshort, Short, 0, result.s, false);
CALL_NONVIRTUAL(jint, Int, 0, result.i, false);
CALL_NONVIRTUAL(jlong, Long, 0, result.j, false);
CALL_NONVIRTUAL(jfloat, Float, 0.0f, result.f, false);
CALL_NONVIRTUAL(jdouble, Double, 0.0, result.d, false);
CALL_NONVIRTUAL(void, Void, , , false);


/*
 * Call a static method.
 */
#define CALL_STATIC(_ctype, _jname, _retfail, _retok, _isref)               \
    static _ctype CallStatic##_jname##Method(JNIEnv* env, jclass jclazz,    \
        jmethodID methodID, ...)                                            \
    {                                                                       \
        UNUSED_PARAMETER(jclazz);                                           \
        JNI_ENTER();                                                        \
        JValue result;                                                      \
        va_list args;                                                       \
        va_start(args, methodID);                                           \
        dvmCallMethodV(_self, (Method*)methodID, NULL, true, &result, args);\
        va_end(args);                                                       \
        if (_isref && !dvmCheckException(_self))                            \
            result.l = addLocalReference(env, result.l);                    \
        JNI_EXIT();                                                         \
        return _retok;                                                      \
    }                                                                       \
    static _ctype CallStatic##_jname##MethodV(JNIEnv* env, jclass jclazz,   \
        jmethodID methodID, va_list args)                                   \
    {                                                                       \
        UNUSED_PARAMETER(jclazz);                                           \
        JNI_ENTER();                                                        \
        JValue result;                                                      \
        dvmCallMethodV(_self, (Method*)methodID, NULL, true, &result, args);\
        if (_isref && !dvmCheckException(_self))                            \
            result.l = addLocalReference(env, result.l);                    \
        JNI_EXIT();                                                         \
        return _retok;                                                      \
    }                                                                       \
    static _ctype CallStatic##_jname##MethodA(JNIEnv* env, jclass jclazz,   \
        jmethodID methodID, jvalue* args)                                   \
    {                                                                       \
        UNUSED_PARAMETER(jclazz);                                           \
        JNI_ENTER();                                                        \
        JValue result;                                                      \
        dvmCallMethodA(_self, (Method*)methodID, NULL, true, &result, args);\
        if (_isref && !dvmCheckException(_self))                            \
            result.l = addLocalReference(env, result.l);                    \
        JNI_EXIT();                                                         \
        return _retok;                                                      \
    }
CALL_STATIC(jobject, Object, NULL, result.l, true);
CALL_STATIC(jboolean, Boolean, 0, result.z, false);
CALL_STATIC(jbyte, Byte, 0, result.b, false);
CALL_STATIC(jchar, Char, 0, result.c, false);
CALL_STATIC(jshort, Short, 0, result.s, false);
CALL_STATIC(jint, Int, 0, result.i, false);
CALL_STATIC(jlong, Long, 0, result.j, false);
CALL_STATIC(jfloat, Float, 0.0f, result.f, false);
CALL_STATIC(jdouble, Double, 0.0, result.d, false);
CALL_STATIC(void, Void, , , false);

/*
 * Create a new String from Unicode data.
 *
 * If "len" is zero, we will return an empty string even if "unicodeChars"
 * is NULL.  (The JNI spec is vague here.)
 */
static jstring NewString(JNIEnv* env, const jchar* unicodeChars, jsize len)
{
    JNI_ENTER();
    jobject retval;

    StringObject* jstr = dvmCreateStringFromUnicode(unicodeChars, len);
    if (jstr == NULL) {
        retval = NULL;
    } else {
        dvmReleaseTrackedAlloc((Object*) jstr, NULL);
        retval = addLocalReference(env, (Object*) jstr);
    }

    JNI_EXIT();
    return retval;
}

/*
 * Return the length of a String in Unicode character units.
 */
static jsize GetStringLength(JNIEnv* env, jstring jstr)
{
    JNI_ENTER();

    StringObject* strObj = (StringObject*) dvmDecodeIndirectRef(env, jstr);
    jsize len = dvmStringLen(strObj);

    JNI_EXIT();
    return len;
}


/*
 * Get a string's character data.
 *
 * The result is guaranteed to be valid until ReleaseStringChars is
 * called, which means we have to pin it or return a copy.
 */
static const jchar* GetStringChars(JNIEnv* env, jstring jstr, jboolean* isCopy)
{
    JNI_ENTER();

    StringObject* strObj = (StringObject*) dvmDecodeIndirectRef(env, jstr);
    ArrayObject* strChars = dvmStringCharArray(strObj);

    pinPrimitiveArray(strChars);

    const u2* data = dvmStringChars(strObj);
    if (isCopy != NULL)
        *isCopy = JNI_FALSE;

    JNI_EXIT();
    return (jchar*)data;
}

/*
 * Release our grip on some characters from a string.
 */
static void ReleaseStringChars(JNIEnv* env, jstring jstr, const jchar* chars)
{
    JNI_ENTER();
    StringObject* strObj = (StringObject*) dvmDecodeIndirectRef(env, jstr);
    ArrayObject* strChars = dvmStringCharArray(strObj);
    unpinPrimitiveArray(strChars);
    JNI_EXIT();
}

/*
 * Create a new java.lang.String object from chars in modified UTF-8 form.
 *
 * The spec doesn't say how to handle a NULL string.  Popular desktop VMs
 * accept it and return a NULL pointer in response.
 */
static jstring NewStringUTF(JNIEnv* env, const char* bytes)
{
    JNI_ENTER();

    jstring result;

    if (bytes == NULL) {
        result = NULL;
    } else {
        /* note newStr could come back NULL on OOM */
        StringObject* newStr = dvmCreateStringFromCstr(bytes);
        result = addLocalReference(env, (Object*) newStr);
        dvmReleaseTrackedAlloc((Object*)newStr, NULL);
    }

    JNI_EXIT();
    return result;
}

/*
 * Return the length in bytes of the modified UTF-8 form of the string.
 */
static jsize GetStringUTFLength(JNIEnv* env, jstring jstr)
{
    JNI_ENTER();

    StringObject* strObj = (StringObject*) dvmDecodeIndirectRef(env, jstr);
    jsize len = dvmStringUtf8ByteLen(strObj);

    JNI_EXIT();
    return len;
}

/*
 * Convert "string" to modified UTF-8 and return a pointer.  The returned
 * value must be released with ReleaseStringUTFChars.
 *
 * According to the JNI reference, "Returns a pointer to a UTF-8 string,
 * or NULL if the operation fails. Returns NULL if and only if an invocation
 * of this function has thrown an exception."
 *
 * The behavior here currently follows that of other open-source VMs, which
 * quietly return NULL if "string" is NULL.  We should consider throwing an
 * NPE.  (The CheckJNI code blows up if you try to pass in a NULL string,
 * which should catch this sort of thing during development.)  Certain other
 * VMs will crash with a segmentation fault.
 */
static const char* GetStringUTFChars(JNIEnv* env, jstring jstr,
    jboolean* isCopy)
{
    JNI_ENTER();
    char* newStr;

    if (jstr == NULL) {
        /* this shouldn't happen; throw NPE? */
        newStr = NULL;
    } else {
        if (isCopy != NULL)
            *isCopy = JNI_TRUE;

        StringObject* strObj = (StringObject*) dvmDecodeIndirectRef(env, jstr);
        newStr = dvmCreateCstrFromString(strObj);
        if (newStr == NULL) {
            /* assume memory failure */
            dvmThrowException("Ljava/lang/OutOfMemoryError;",
                "native heap string alloc failed");
        }
    }

    JNI_EXIT();
    return newStr;
}

/*
 * Release a string created by GetStringUTFChars().
 */
static void ReleaseStringUTFChars(JNIEnv* env, jstring jstr, const char* utf)
{
    JNI_ENTER();
    free((char*)utf);
    JNI_EXIT();
}

/*
 * Return the capacity of the array.
 */
static jsize GetArrayLength(JNIEnv* env, jarray jarr)
{
    JNI_ENTER();

    ArrayObject* arrObj = (ArrayObject*) dvmDecodeIndirectRef(env, jarr);
    jsize length = arrObj->length;

    JNI_EXIT();
    return length;
}

/*
 * Construct a new array that holds objects from class "elementClass".
 */
static jobjectArray NewObjectArray(JNIEnv* env, jsize length,
    jclass jelementClass, jobject jinitialElement)
{
    JNI_ENTER();

    jobjectArray newArray = NULL;
    ClassObject* elemClassObj =
        (ClassObject*) dvmDecodeIndirectRef(env, jelementClass);

    if (elemClassObj == NULL) {
        dvmThrowException("Ljava/lang/NullPointerException;",
            "JNI NewObjectArray");
        goto bail;
    }

    ArrayObject* newObj =
        dvmAllocObjectArray(elemClassObj, length, ALLOC_DEFAULT);
    if (newObj == NULL) {
        assert(dvmCheckException(_self));
        goto bail;
    }
    newArray = addLocalReference(env, (Object*) newObj);
    dvmReleaseTrackedAlloc((Object*) newObj, NULL);

    /*
     * Initialize the array.  Trashes "length".
     */
    if (jinitialElement != NULL) {
        Object* initialElement = dvmDecodeIndirectRef(env, jinitialElement);
        Object** arrayData = (Object**) newObj->contents;

        while (length--)
            *arrayData++ = initialElement;
    }


bail:
    JNI_EXIT();
    return newArray;
}

/*
 * Get one element of an Object array.
 *
 * Add the object to the local references table in case the array goes away.
 */
static jobject GetObjectArrayElement(JNIEnv* env, jobjectArray jarr,
    jsize index)
{
    JNI_ENTER();

    ArrayObject* arrayObj = (ArrayObject*) dvmDecodeIndirectRef(env, jarr);
    jobject retval = NULL;

    assert(arrayObj != NULL);

    /* check the array bounds */
    if (index < 0 || index >= (int) arrayObj->length) {
        dvmThrowException("Ljava/lang/ArrayIndexOutOfBoundsException;",
            arrayObj->obj.clazz->descriptor);
        goto bail;
    }

    Object* value = ((Object**) arrayObj->contents)[index];
    retval = addLocalReference(env, value);

bail:
    JNI_EXIT();
    return retval;
}

/*
 * Set one element of an Object array.
 */
static void SetObjectArrayElement(JNIEnv* env, jobjectArray jarr,
    jsize index, jobject jobj)
{
    JNI_ENTER();

    ArrayObject* arrayObj = (ArrayObject*) dvmDecodeIndirectRef(env, jarr);

    assert(arrayObj != NULL);

    /* check the array bounds */
    if (index < 0 || index >= (int) arrayObj->length) {
        dvmThrowException("Ljava/lang/ArrayIndexOutOfBoundsException;",
            arrayObj->obj.clazz->descriptor);
        goto bail;
    }

    //LOGV("JNI: set element %d in array %p to %p\n", index, array, value);

    Object* obj = dvmDecodeIndirectRef(env, jobj);
    dvmSetObjectArrayElement(arrayObj, index, obj);

bail:
    JNI_EXIT();
}

/*
 * Create a new array of primitive elements.
 */
#define NEW_PRIMITIVE_ARRAY(_artype, _jname, _typechar)                     \
    static _artype New##_jname##Array(JNIEnv* env, jsize length)            \
    {                                                                       \
        JNI_ENTER();                                                        \
        ArrayObject* arrayObj;                                              \
        arrayObj = dvmAllocPrimitiveArray(_typechar, length,                \
            ALLOC_DEFAULT);                                                 \
        jarray jarr = NULL;                                                 \
        if (arrayObj != NULL) {                                             \
            jarr = addLocalReference(env, (Object*) arrayObj);              \
            dvmReleaseTrackedAlloc((Object*) arrayObj, NULL);               \
        }                                                                   \
        JNI_EXIT();                                                         \
        return (_artype)jarr;                                               \
    }
NEW_PRIMITIVE_ARRAY(jbooleanArray, Boolean, 'Z');
NEW_PRIMITIVE_ARRAY(jbyteArray, Byte, 'B');
NEW_PRIMITIVE_ARRAY(jcharArray, Char, 'C');
NEW_PRIMITIVE_ARRAY(jshortArray, Short, 'S');
NEW_PRIMITIVE_ARRAY(jintArray, Int, 'I');
NEW_PRIMITIVE_ARRAY(jlongArray, Long, 'J');
NEW_PRIMITIVE_ARRAY(jfloatArray, Float, 'F');
NEW_PRIMITIVE_ARRAY(jdoubleArray, Double, 'D');

/*
 * Get a pointer to a C array of primitive elements from an array object
 * of the matching type.
 *
 * In a compacting GC, we either need to return a copy of the elements or
 * "pin" the memory.  Otherwise we run the risk of native code using the
 * buffer as the destination of e.g. a blocking read() call that wakes up
 * during a GC.
 */
#define GET_PRIMITIVE_ARRAY_ELEMENTS(_ctype, _jname)                        \
    static _ctype* Get##_jname##ArrayElements(JNIEnv* env,                  \
        _ctype##Array jarr, jboolean* isCopy)                               \
    {                                                                       \
        JNI_ENTER();                                                        \
        _ctype* data;                                                       \
        ArrayObject* arrayObj =                                             \
            (ArrayObject*) dvmDecodeIndirectRef(env, jarr);                 \
        pinPrimitiveArray(arrayObj);                                        \
        data = (_ctype*) arrayObj->contents;                                \
        if (isCopy != NULL)                                                 \
            *isCopy = JNI_FALSE;                                            \
        JNI_EXIT();                                                         \
        return data;                                                        \
    }

/*
 * Release the storage locked down by the "get" function.
 *
 * The spec says, "'mode' has no effect if 'elems' is not a copy of the
 * elements in 'array'."  They apparently did not anticipate the need to
 * un-pin memory.
 */
#define RELEASE_PRIMITIVE_ARRAY_ELEMENTS(_ctype, _jname)                    \
    static void Release##_jname##ArrayElements(JNIEnv* env,                 \
        _ctype##Array jarr, _ctype* elems, jint mode)                       \
    {                                                                       \
        UNUSED_PARAMETER(elems);                                            \
        JNI_ENTER();                                                        \
        if (mode != JNI_COMMIT) {                                           \
            ArrayObject* arrayObj =                                         \
                (ArrayObject*) dvmDecodeIndirectRef(env, jarr);             \
            unpinPrimitiveArray(arrayObj);                                  \
        }                                                                   \
        JNI_EXIT();                                                         \
    }

/*
 * Copy a section of a primitive array to a buffer.
 */
#define GET_PRIMITIVE_ARRAY_REGION(_ctype, _jname)                          \
    static void Get##_jname##ArrayRegion(JNIEnv* env,                       \
        _ctype##Array jarr, jsize start, jsize len, _ctype* buf)            \
    {                                                                       \
        JNI_ENTER();                                                        \
        ArrayObject* arrayObj =                                             \
            (ArrayObject*) dvmDecodeIndirectRef(env, jarr);                 \
        _ctype* data = (_ctype*) arrayObj->contents;                        \
        if (start < 0 || len < 0 || start + len > (int) arrayObj->length) { \
            dvmThrowException("Ljava/lang/ArrayIndexOutOfBoundsException;", \
                arrayObj->obj.clazz->descriptor);                           \
        } else {                                                            \
            memcpy(buf, data + start, len * sizeof(_ctype));                \
        }                                                                   \
        JNI_EXIT();                                                         \
    }

/*
 * Copy a section of a primitive array from a buffer.
 */
#define SET_PRIMITIVE_ARRAY_REGION(_ctype, _jname)                          \
    static void Set##_jname##ArrayRegion(JNIEnv* env,                       \
        _ctype##Array jarr, jsize start, jsize len, const _ctype* buf)      \
    {                                                                       \
        JNI_ENTER();                                                        \
        ArrayObject* arrayObj =                                             \
            (ArrayObject*) dvmDecodeIndirectRef(env, jarr);                 \
        _ctype* data = (_ctype*) arrayObj->contents;                        \
        if (start < 0 || len < 0 || start + len > (int) arrayObj->length) { \
            dvmThrowException("Ljava/lang/ArrayIndexOutOfBoundsException;", \
                arrayObj->obj.clazz->descriptor);                           \
        } else {                                                            \
            memcpy(data + start, buf, len * sizeof(_ctype));                \
        }                                                                   \
        JNI_EXIT();                                                         \
    }

/*
 * 4-in-1:
 *  Get<Type>ArrayElements
 *  Release<Type>ArrayElements
 *  Get<Type>ArrayRegion
 *  Set<Type>ArrayRegion
 */
#define PRIMITIVE_ARRAY_FUNCTIONS(_ctype, _jname)                           \
    GET_PRIMITIVE_ARRAY_ELEMENTS(_ctype, _jname);                           \
    RELEASE_PRIMITIVE_ARRAY_ELEMENTS(_ctype, _jname);                       \
    GET_PRIMITIVE_ARRAY_REGION(_ctype, _jname);                             \
    SET_PRIMITIVE_ARRAY_REGION(_ctype, _jname);

PRIMITIVE_ARRAY_FUNCTIONS(jboolean, Boolean);
PRIMITIVE_ARRAY_FUNCTIONS(jbyte, Byte);
PRIMITIVE_ARRAY_FUNCTIONS(jchar, Char);
PRIMITIVE_ARRAY_FUNCTIONS(jshort, Short);
PRIMITIVE_ARRAY_FUNCTIONS(jint, Int);
PRIMITIVE_ARRAY_FUNCTIONS(jlong, Long);
PRIMITIVE_ARRAY_FUNCTIONS(jfloat, Float);
PRIMITIVE_ARRAY_FUNCTIONS(jdouble, Double);

/*
 * Register one or more native functions in one class.
 *
 * This can be called multiple times on the same method, allowing the
 * caller to redefine the method implementation at will.
 */
static jint RegisterNatives(JNIEnv* env, jclass jclazz,
    const JNINativeMethod* methods, jint nMethods)
{
    JNI_ENTER();

    ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(env, jclazz);
    jint retval = JNI_OK;
    int i;

    if (gDvm.verboseJni) {
        LOGI("[Registering JNI native methods for class %s]\n",
            clazz->descriptor);
    }

    for (i = 0; i < nMethods; i++) {
        if (!dvmRegisterJNIMethod(clazz, methods[i].name,
                methods[i].signature, methods[i].fnPtr))
        {
            retval = JNI_ERR;
        }
    }

    JNI_EXIT();
    return retval;
}

/*
 * Un-register all native methods associated with the class.
 *
 * The JNI docs refer to this as a way to reload/relink native libraries,
 * and say it "should not be used in normal native code".  In particular,
 * there is no need to do this during shutdown, and you do not need to do
 * this before redefining a method implementation with RegisterNatives.
 *
 * It's chiefly useful for a native "plugin"-style library that wasn't
 * loaded with System.loadLibrary() (since there's no way to unload those).
 * For example, the library could upgrade itself by:
 *
 *  1. call UnregisterNatives to unbind the old methods
 *  2. ensure that no code is still executing inside it (somehow)
 *  3. dlclose() the library
 *  4. dlopen() the new library
 *  5. use RegisterNatives to bind the methods from the new library
 *
 * The above can work correctly without the UnregisterNatives call, but
 * creates a window of opportunity in which somebody might try to call a
 * method that is pointing at unmapped memory, crashing the VM.  In theory
 * the same guards that prevent dlclose() from unmapping executing code could
 * prevent that anyway, but with this we can be more thorough and also deal
 * with methods that only exist in the old or new form of the library (maybe
 * the lib wants to try the call and catch the UnsatisfiedLinkError).
 */
static jint UnregisterNatives(JNIEnv* env, jclass jclazz)
{
    JNI_ENTER();

    ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(env, jclazz);
    if (gDvm.verboseJni) {
        LOGI("[Unregistering JNI native methods for class %s]\n",
            clazz->descriptor);
    }
    dvmUnregisterJNINativeMethods(clazz);

    JNI_EXIT();
    return JNI_OK;
}

/*
 * Lock the monitor.
 *
 * We have to track all monitor enters and exits, so that we can undo any
 * outstanding synchronization before the thread exits.
 */
static jint MonitorEnter(JNIEnv* env, jobject jobj)
{
    JNI_ENTER();
    Object* obj = dvmDecodeIndirectRef(env, jobj);
    dvmLockObject(_self, obj);
    trackMonitorEnter(_self, obj);
    JNI_EXIT();
    return JNI_OK;
}

/*
 * Unlock the monitor.
 *
 * Throws an IllegalMonitorStateException if the current thread
 * doesn't own the monitor.  (dvmUnlockObject() takes care of the throw.)
 *
 * According to the 1.6 spec, it's legal to call here with an exception
 * pending.  If this fails, we'll stomp the original exception.
 */
static jint MonitorExit(JNIEnv* env, jobject jobj)
{
    JNI_ENTER();
    Object* obj = dvmDecodeIndirectRef(env, jobj);
    bool success = dvmUnlockObject(_self, obj);
    if (success)
        trackMonitorExit(_self, obj);
    JNI_EXIT();
    return success ? JNI_OK : JNI_ERR;
}

/*
 * Return the JavaVM interface associated with the current thread.
 */
static jint GetJavaVM(JNIEnv* env, JavaVM** vm)
{
    JNI_ENTER();
    //*vm = gDvm.vmList;
    *vm = (JavaVM*) ((JNIEnvExt*)env)->vm;
    JNI_EXIT();
    if (*vm == NULL)
        return JNI_ERR;
    else
        return JNI_OK;
}

/*
 * Copies "len" Unicode characters, from offset "start".
 */
static void GetStringRegion(JNIEnv* env, jstring jstr, jsize start, jsize len,
    jchar* buf)
{
    JNI_ENTER();
    StringObject* strObj = (StringObject*) dvmDecodeIndirectRef(env, jstr);
    if (start + len > dvmStringLen(strObj))
        dvmThrowException("Ljava/lang/StringIndexOutOfBoundsException;", NULL);
    else
        memcpy(buf, dvmStringChars(strObj) + start, len * sizeof(u2));
    JNI_EXIT();
}

/*
 * Translates "len" Unicode characters, from offset "start", into
 * modified UTF-8 encoding.
 */
static void GetStringUTFRegion(JNIEnv* env, jstring jstr, jsize start,
    jsize len, char* buf)
{
    JNI_ENTER();
    StringObject* strObj = (StringObject*) dvmDecodeIndirectRef(env, jstr);
    if (start + len > dvmStringLen(strObj))
        dvmThrowException("Ljava/lang/StringIndexOutOfBoundsException;", NULL);
    else
        dvmCreateCstrFromStringRegion(strObj, start, len, buf);
    JNI_EXIT();
}

/*
 * Get a raw pointer to array data.
 *
 * The caller is expected to call "release" before doing any JNI calls
 * or blocking I/O operations.
 *
 * We need to pin the memory or block GC.
 */
static void* GetPrimitiveArrayCritical(JNIEnv* env, jarray jarr,
    jboolean* isCopy)
{
    JNI_ENTER();
    void* data;
    ArrayObject* arrayObj = (ArrayObject*) dvmDecodeIndirectRef(env, jarr);
    pinPrimitiveArray(arrayObj);
    data = arrayObj->contents;
    if (isCopy != NULL)
        *isCopy = JNI_FALSE;
    JNI_EXIT();
    return data;
}

/*
 * Release an array obtained with GetPrimitiveArrayCritical.
 */
static void ReleasePrimitiveArrayCritical(JNIEnv* env, jarray jarr,
    void* carray, jint mode)
{
    JNI_ENTER();
    if (mode != JNI_COMMIT) {
        ArrayObject* arrayObj = (ArrayObject*) dvmDecodeIndirectRef(env, jarr);
        unpinPrimitiveArray(arrayObj);
    }
    JNI_EXIT();
}

/*
 * Like GetStringChars, but with restricted use.
 */
static const jchar* GetStringCritical(JNIEnv* env, jstring jstr,
    jboolean* isCopy)
{
    JNI_ENTER();
    StringObject* strObj = (StringObject*) dvmDecodeIndirectRef(env, jstr);
    ArrayObject* strChars = dvmStringCharArray(strObj);

    pinPrimitiveArray(strChars);

    const u2* data = dvmStringChars(strObj);
    if (isCopy != NULL)
        *isCopy = JNI_FALSE;

    JNI_EXIT();
    return (jchar*)data;
}

/*
 * Like ReleaseStringChars, but with restricted use.
 */
static void ReleaseStringCritical(JNIEnv* env, jstring jstr,
    const jchar* carray)
{
    JNI_ENTER();
    StringObject* strObj = (StringObject*) dvmDecodeIndirectRef(env, jstr);
    ArrayObject* strChars = dvmStringCharArray(strObj);
    unpinPrimitiveArray(strChars);
    JNI_EXIT();
}

/*
 * Create a new weak global reference.
 */
static jweak NewWeakGlobalRef(JNIEnv* env, jobject obj)
{
    JNI_ENTER();
    jweak wref = createWeakGlobalRef(env, obj);
    JNI_EXIT();
    return wref;
}

/*
 * Delete the specified weak global reference.
 */
static void DeleteWeakGlobalRef(JNIEnv* env, jweak wref)
{
    JNI_ENTER();
    deleteWeakGlobalRef(env, wref);
    JNI_EXIT();
}

/*
 * Quick check for pending exceptions.
 *
 * TODO: we should be able to skip the enter/exit macros here.
 */
static jboolean ExceptionCheck(JNIEnv* env)
{
    JNI_ENTER();
    bool result = dvmCheckException(_self);
    JNI_EXIT();
    return result;
}

/*
 * Returns the type of the object referred to by "obj".  It can be local,
 * global, or weak global.
 *
 * In the current implementation, references can be global and local at
 * the same time, so while the return value is accurate it may not tell
 * the whole story.
 */
static jobjectRefType GetObjectRefType(JNIEnv* env, jobject jobj)
{
    JNI_ENTER();
    jobjectRefType type = dvmGetJNIRefType(env, jobj);
    JNI_EXIT();
    return type;
}

/*
 * Allocate and return a new java.nio.ByteBuffer for this block of memory.
 *
 * "address" may not be NULL, and "capacity" must be > 0.  (These are only
 * verified when CheckJNI is enabled.)
 */
static jobject NewDirectByteBuffer(JNIEnv* env, void* address, jlong capacity)
{
    JNI_ENTER();

    Thread* self = _self /*dvmThreadSelf()*/;
    JValue unused;
    jobject result = NULL;
    ClassObject* bufferClazz = gDvm.classJavaNioReadWriteDirectByteBuffer;

    /* create an instance of java.nio.ReadWriteDirectByteBuffer */
    if (!dvmIsClassInitialized(bufferClazz) && !dvmInitClass(bufferClazz))
        goto bail;
    Object* newObj = dvmAllocObject(bufferClazz, ALLOC_DONT_TRACK);
    if (newObj != NULL) {
        /* call the constructor */
        result = addLocalReference(env, newObj);
        dvmCallMethod(self, gDvm.methJavaNioReadWriteDirectByteBuffer_init,
                newObj, &unused, (jint) address, (jint) capacity);
        if (dvmGetException(self) != NULL) {
            deleteLocalReference(env, result);
            result = NULL;
            goto bail;
        }
    }

bail:
    JNI_EXIT();
    return result;
}

/*
 * Get the starting address of the buffer for the specified java.nio.Buffer.
 *
 * If this is not a "direct" buffer, we return NULL.
 */
static void* GetDirectBufferAddress(JNIEnv* env, jobject jbuf)
{
    JNI_ENTER();

    Object* bufObj = dvmDecodeIndirectRef(env, jbuf);

    /*
     * All Buffer objects have an effectiveDirectAddress field.
     */
    void* result = (void*) dvmGetFieldInt(bufObj,
            gDvm.offJavaNioBuffer_effectiveDirectAddress);

    JNI_EXIT();
    return result;
}

/*
 * Get the capacity of the buffer for the specified java.nio.Buffer.
 *
 * Returns -1 if the object is not a direct buffer.  (We actually skip
 * this check, since it's expensive to determine, and just return the
 * capacity regardless.)
 */
static jlong GetDirectBufferCapacity(JNIEnv* env, jobject jbuf)
{
    JNI_ENTER();

    /*
     * The capacity is always in the Buffer.capacity field.
     *
     * (The "check" version should verify that this is actually a Buffer,
     * but we're not required to do so here.)
     */
    Object* buf = dvmDecodeIndirectRef(env, jbuf);
    jlong result = dvmGetFieldInt(buf, gDvm.offJavaNioBuffer_capacity);

    JNI_EXIT();
    return result;
}


/*
 * ===========================================================================
 *      JNI invocation functions
 * ===========================================================================
 */

/*
 * Handle AttachCurrentThread{AsDaemon}.
 *
 * We need to make sure the VM is actually running.  For example, if we start
 * up, issue an Attach, and the VM exits almost immediately, by the time the
 * attaching happens the VM could already be shutting down.
 *
 * It's hard to avoid a race condition here because we don't want to hold
 * a lock across the entire operation.  What we can do is temporarily
 * increment the thread count to prevent a VM exit.
 *
 * This could potentially still have problems if a daemon thread calls here
 * while the VM is shutting down.  dvmThreadSelf() will work, since it just
 * uses pthread TLS, but dereferencing "vm" could fail.  Such is life when
 * you shut down a VM while threads are still running inside it.
 *
 * Remember that some code may call this as a way to find the per-thread
 * JNIEnv pointer.  Don't do excess work for that case.
 */
static jint attachThread(JavaVM* vm, JNIEnv** p_env, void* thr_args,
    bool isDaemon)
{
    JavaVMAttachArgs* args = (JavaVMAttachArgs*) thr_args;
    Thread* self;
    bool result = false;

    /*
     * Return immediately if we're already one with the VM.
     */
    self = dvmThreadSelf();
    if (self != NULL) {
        *p_env = self->jniEnv;
        return JNI_OK;
    }

    /*
     * No threads allowed in zygote mode.
     */
    if (gDvm.zygote) {
        return JNI_ERR;
    }

    /* increment the count to keep the VM from bailing while we run */
    dvmLockThreadList(NULL);
    if (gDvm.nonDaemonThreadCount == 0) {
        // dead or dying
        LOGV("Refusing to attach thread '%s' -- VM is shutting down\n",
            (thr_args == NULL) ? "(unknown)" : args->name);
        dvmUnlockThreadList();
        return JNI_ERR;
    }
    gDvm.nonDaemonThreadCount++;
    dvmUnlockThreadList();

    /* tweak the JavaVMAttachArgs as needed */
    JavaVMAttachArgs argsCopy;
    if (args == NULL) {
        /* allow the v1.1 calling convention */
        argsCopy.version = JNI_VERSION_1_2;
        argsCopy.name = NULL;
        argsCopy.group = dvmGetMainThreadGroup();
    } else {
        assert(args->version >= JNI_VERSION_1_2);

        argsCopy.version = args->version;
        argsCopy.name = args->name;
        if (args->group != NULL)
            argsCopy.group = args->group;
        else
            argsCopy.group = dvmGetMainThreadGroup();
    }

    result = dvmAttachCurrentThread(&argsCopy, isDaemon);

    /* restore the count */
    dvmLockThreadList(NULL);
    gDvm.nonDaemonThreadCount--;
    dvmUnlockThreadList();

    /*
     * Change the status to indicate that we're out in native code.  This
     * call is not guarded with state-change macros, so we have to do it
     * by hand.
     */
    if (result) {
        self = dvmThreadSelf();
        assert(self != NULL);
        dvmChangeStatus(self, THREAD_NATIVE);
        *p_env = self->jniEnv;
        return JNI_OK;
    } else {
        return JNI_ERR;
    }
}

/*
 * Attach the current thread to the VM.  If the thread is already attached,
 * this is a no-op.
 */
static jint AttachCurrentThread(JavaVM* vm, JNIEnv** p_env, void* thr_args)
{
    return attachThread(vm, p_env, thr_args, false);
}

/*
 * Like AttachCurrentThread, but set the "daemon" flag.
 */
static jint AttachCurrentThreadAsDaemon(JavaVM* vm, JNIEnv** p_env,
    void* thr_args)
{
    return attachThread(vm, p_env, thr_args, true);
}

/*
 * Dissociate the current thread from the VM.
 */
static jint DetachCurrentThread(JavaVM* vm)
{
    Thread* self = dvmThreadSelf();

    if (self == NULL)               /* not attached, can't do anything */
        return JNI_ERR;

    /* switch to "running" to check for suspension */
    dvmChangeStatus(self, THREAD_RUNNING);

    /* detach the thread */
    dvmDetachCurrentThread();

    /* (no need to change status back -- we have no status) */
    return JNI_OK;
}

/*
 * If current thread is attached to VM, return the associated JNIEnv.
 * Otherwise, stuff NULL in and return JNI_EDETACHED.
 *
 * JVMTI overloads this by specifying a magic value for "version", so we
 * do want to check that here.
 */
static jint GetEnv(JavaVM* vm, void** env, jint version)
{
    Thread* self = dvmThreadSelf();

    if (version < JNI_VERSION_1_1 || version > JNI_VERSION_1_6)
        return JNI_EVERSION;

    if (self == NULL) {
        *env = NULL;
    } else {
        /* TODO: status change is probably unnecessary */
        dvmChangeStatus(self, THREAD_RUNNING);
        *env = (void*) dvmGetThreadJNIEnv(self);
        dvmChangeStatus(self, THREAD_NATIVE);
    }
    if (*env == NULL)
        return JNI_EDETACHED;
    else
        return JNI_OK;
}

/*
 * Destroy the VM.  This may be called from any thread.
 *
 * If the current thread is attached, wait until the current thread is
 * the only non-daemon user-level thread.  If the current thread is not
 * attached, we attach it and do the processing as usual.  (If the attach
 * fails, it's probably because all the non-daemon threads have already
 * exited and the VM doesn't want to let us back in.)
 *
 * TODO: we don't really deal with the situation where more than one thread
 * has called here.  One thread wins, the other stays trapped waiting on
 * the condition variable forever.  Not sure this situation is interesting
 * in real life.
 */
static jint DestroyJavaVM(JavaVM* vm)
{
    JavaVMExt* ext = (JavaVMExt*) vm;
    Thread* self;

    if (ext == NULL)
        return JNI_ERR;

    if (gDvm.verboseShutdown)
        LOGD("DestroyJavaVM waiting for non-daemon threads to exit\n");

    /*
     * Sleep on a condition variable until it's okay to exit.
     */
    self = dvmThreadSelf();
    if (self == NULL) {
        JNIEnv* tmpEnv;
        if (AttachCurrentThread(vm, &tmpEnv, NULL) != JNI_OK) {
            LOGV("Unable to reattach main for Destroy; assuming VM is "
                 "shutting down (count=%d)\n",
                gDvm.nonDaemonThreadCount);
            goto shutdown;
        } else {
            LOGV("Attached to wait for shutdown in Destroy\n");
        }
    }
    dvmChangeStatus(self, THREAD_VMWAIT);

    dvmLockThreadList(self);
    gDvm.nonDaemonThreadCount--;    // remove current thread from count

    while (gDvm.nonDaemonThreadCount > 0)
        pthread_cond_wait(&gDvm.vmExitCond, &gDvm.threadListLock);

    dvmUnlockThreadList();
    self = NULL;

shutdown:
    // TODO: call System.exit() to run any registered shutdown hooks
    // (this may not return -- figure out how this should work)

    if (gDvm.verboseShutdown)
        LOGD("DestroyJavaVM shutting VM down\n");
    dvmShutdown();

    // TODO - free resources associated with JNI-attached daemon threads
    free(ext->envList);
    free(ext);

    return JNI_OK;
}


/*
 * ===========================================================================
 *      Function tables
 * ===========================================================================
 */

static const struct JNINativeInterface gNativeInterface = {
    NULL,
    NULL,
    NULL,
    NULL,

    GetVersion,

    DefineClass,
    FindClass,

    FromReflectedMethod,
    FromReflectedField,
    ToReflectedMethod,

    GetSuperclass,
    IsAssignableFrom,

    ToReflectedField,

    Throw,
    ThrowNew,
    ExceptionOccurred,
    ExceptionDescribe,
    ExceptionClear,
    FatalError,

    PushLocalFrame,
    PopLocalFrame,

    NewGlobalRef,
    DeleteGlobalRef,
    DeleteLocalRef,
    IsSameObject,
    NewLocalRef,
    EnsureLocalCapacity,

    AllocObject,
    NewObject,
    NewObjectV,
    NewObjectA,

    GetObjectClass,
    IsInstanceOf,

    GetMethodID,

    CallObjectMethod,
    CallObjectMethodV,
    CallObjectMethodA,
    CallBooleanMethod,
    CallBooleanMethodV,
    CallBooleanMethodA,
    CallByteMethod,
    CallByteMethodV,
    CallByteMethodA,
    CallCharMethod,
    CallCharMethodV,
    CallCharMethodA,
    CallShortMethod,
    CallShortMethodV,
    CallShortMethodA,
    CallIntMethod,
    CallIntMethodV,
    CallIntMethodA,
    CallLongMethod,
    CallLongMethodV,
    CallLongMethodA,
    CallFloatMethod,
    CallFloatMethodV,
    CallFloatMethodA,
    CallDoubleMethod,
    CallDoubleMethodV,
    CallDoubleMethodA,
    CallVoidMethod,
    CallVoidMethodV,
    CallVoidMethodA,

    CallNonvirtualObjectMethod,
    CallNonvirtualObjectMethodV,
    CallNonvirtualObjectMethodA,
    CallNonvirtualBooleanMethod,
    CallNonvirtualBooleanMethodV,
    CallNonvirtualBooleanMethodA,
    CallNonvirtualByteMethod,
    CallNonvirtualByteMethodV,
    CallNonvirtualByteMethodA,
    CallNonvirtualCharMethod,
    CallNonvirtualCharMethodV,
    CallNonvirtualCharMethodA,
    CallNonvirtualShortMethod,
    CallNonvirtualShortMethodV,
    CallNonvirtualShortMethodA,
    CallNonvirtualIntMethod,
    CallNonvirtualIntMethodV,
    CallNonvirtualIntMethodA,
    CallNonvirtualLongMethod,
    CallNonvirtualLongMethodV,
    CallNonvirtualLongMethodA,
    CallNonvirtualFloatMethod,
    CallNonvirtualFloatMethodV,
    CallNonvirtualFloatMethodA,
    CallNonvirtualDoubleMethod,
    CallNonvirtualDoubleMethodV,
    CallNonvirtualDoubleMethodA,
    CallNonvirtualVoidMethod,
    CallNonvirtualVoidMethodV,
    CallNonvirtualVoidMethodA,

    GetFieldID,

    GetObjectField,
    GetBooleanField,
    GetByteField,
    GetCharField,
    GetShortField,
    GetIntField,
    GetLongField,
    GetFloatField,
    GetDoubleField,
    SetObjectField,
    SetBooleanField,
    SetByteField,
    SetCharField,
    SetShortField,
    SetIntField,
    SetLongField,
    SetFloatField,
    SetDoubleField,

    GetStaticMethodID,

    CallStaticObjectMethod,
    CallStaticObjectMethodV,
    CallStaticObjectMethodA,
    CallStaticBooleanMethod,
    CallStaticBooleanMethodV,
    CallStaticBooleanMethodA,
    CallStaticByteMethod,
    CallStaticByteMethodV,
    CallStaticByteMethodA,
    CallStaticCharMethod,
    CallStaticCharMethodV,
    CallStaticCharMethodA,
    CallStaticShortMethod,
    CallStaticShortMethodV,
    CallStaticShortMethodA,
    CallStaticIntMethod,
    CallStaticIntMethodV,
    CallStaticIntMethodA,
    CallStaticLongMethod,
    CallStaticLongMethodV,
    CallStaticLongMethodA,
    CallStaticFloatMethod,
    CallStaticFloatMethodV,
    CallStaticFloatMethodA,
    CallStaticDoubleMethod,
    CallStaticDoubleMethodV,
    CallStaticDoubleMethodA,
    CallStaticVoidMethod,
    CallStaticVoidMethodV,
    CallStaticVoidMethodA,

    GetStaticFieldID,

    GetStaticObjectField,
    GetStaticBooleanField,
    GetStaticByteField,
    GetStaticCharField,
    GetStaticShortField,
    GetStaticIntField,
    GetStaticLongField,
    GetStaticFloatField,
    GetStaticDoubleField,

    SetStaticObjectField,
    SetStaticBooleanField,
    SetStaticByteField,
    SetStaticCharField,
    SetStaticShortField,
    SetStaticIntField,
    SetStaticLongField,
    SetStaticFloatField,
    SetStaticDoubleField,

    NewString,

    GetStringLength,
    GetStringChars,
    ReleaseStringChars,

    NewStringUTF,
    GetStringUTFLength,
    GetStringUTFChars,
    ReleaseStringUTFChars,

    GetArrayLength,
    NewObjectArray,
    GetObjectArrayElement,
    SetObjectArrayElement,

    NewBooleanArray,
    NewByteArray,
    NewCharArray,
    NewShortArray,
    NewIntArray,
    NewLongArray,
    NewFloatArray,
    NewDoubleArray,

    GetBooleanArrayElements,
    GetByteArrayElements,
    GetCharArrayElements,
    GetShortArrayElements,
    GetIntArrayElements,
    GetLongArrayElements,
    GetFloatArrayElements,
    GetDoubleArrayElements,

    ReleaseBooleanArrayElements,
    ReleaseByteArrayElements,
    ReleaseCharArrayElements,
    ReleaseShortArrayElements,
    ReleaseIntArrayElements,
    ReleaseLongArrayElements,
    ReleaseFloatArrayElements,
    ReleaseDoubleArrayElements,

    GetBooleanArrayRegion,
    GetByteArrayRegion,
    GetCharArrayRegion,
    GetShortArrayRegion,
    GetIntArrayRegion,
    GetLongArrayRegion,
    GetFloatArrayRegion,
    GetDoubleArrayRegion,
    SetBooleanArrayRegion,
    SetByteArrayRegion,
    SetCharArrayRegion,
    SetShortArrayRegion,
    SetIntArrayRegion,
    SetLongArrayRegion,
    SetFloatArrayRegion,
    SetDoubleArrayRegion,

    RegisterNatives,
    UnregisterNatives,

    MonitorEnter,
    MonitorExit,

    GetJavaVM,

    GetStringRegion,
    GetStringUTFRegion,

    GetPrimitiveArrayCritical,
    ReleasePrimitiveArrayCritical,

    GetStringCritical,
    ReleaseStringCritical,

    NewWeakGlobalRef,
    DeleteWeakGlobalRef,

    ExceptionCheck,

    NewDirectByteBuffer,
    GetDirectBufferAddress,
    GetDirectBufferCapacity,

    GetObjectRefType
};
static const struct JNIInvokeInterface gInvokeInterface = {
    NULL,
    NULL,
    NULL,

    DestroyJavaVM,
    AttachCurrentThread,
    DetachCurrentThread,

    GetEnv,

    AttachCurrentThreadAsDaemon,
};


/*
 * ===========================================================================
 *      VM/Env creation
 * ===========================================================================
 */

/*
 * Enable "checked JNI" after the VM has partially started.  This must
 * only be called in "zygote" mode, when we have one thread running.
 *
 * This doesn't attempt to rewrite the JNI call bridge associated with
 * native methods, so we won't get those checks for any methods that have
 * already been resolved.
 */
void dvmLateEnableCheckedJni(void)
{
    JNIEnvExt* extEnv;
    JavaVMExt* extVm;

    extEnv = dvmGetJNIEnvForThread();
    if (extEnv == NULL) {
        LOGE("dvmLateEnableCheckedJni: thread has no JNIEnv\n");
        return;
    }
    extVm = extEnv->vm;
    assert(extVm != NULL);

    if (!extVm->useChecked) {
        LOGD("Late-enabling CheckJNI\n");
        dvmUseCheckedJniVm(extVm);
        extVm->useChecked = true;
        dvmUseCheckedJniEnv(extEnv);

        /* currently no way to pick up jniopts features */
    } else {
        LOGD("Not late-enabling CheckJNI (already on)\n");
    }
}

/*
 * Not supported.
 */
jint JNI_GetDefaultJavaVMInitArgs(void* vm_args)
{
    return JNI_ERR;
}

/*
 * Return a buffer full of created VMs.
 *
 * We always have zero or one.
 */
jint JNI_GetCreatedJavaVMs(JavaVM** vmBuf, jsize bufLen, jsize* nVMs)
{
    if (gDvm.vmList != NULL) {
        *nVMs = 1;

        if (bufLen > 0)
            *vmBuf++ = gDvm.vmList;
    } else {
        *nVMs = 0;
    }

    return JNI_OK;
}


/*
 * Create a new VM instance.
 *
 * The current thread becomes the main VM thread.  We return immediately,
 * which effectively means the caller is executing in a native method.
 */
jint JNI_CreateJavaVM(JavaVM** p_vm, JNIEnv** p_env, void* vm_args)
{
    const JavaVMInitArgs* args = (JavaVMInitArgs*) vm_args;
    JNIEnvExt* pEnv = NULL;
    JavaVMExt* pVM = NULL;
    const char** argv;
    int argc = 0;
    int i, curOpt;
    int result = JNI_ERR;
    bool checkJni = false;
    bool warnError = true;
    bool forceDataCopy = false;

    if (args->version < JNI_VERSION_1_2)
        return JNI_EVERSION;

    // TODO: don't allow creation of multiple VMs -- one per customer for now

    /* zero globals; not strictly necessary the first time a VM is started */
    memset(&gDvm, 0, sizeof(gDvm));

    /*
     * Set up structures for JNIEnv and VM.
     */
    //pEnv = (JNIEnvExt*) malloc(sizeof(JNIEnvExt));
    pVM = (JavaVMExt*) malloc(sizeof(JavaVMExt));

    //memset(pEnv, 0, sizeof(JNIEnvExt));
    //pEnv->funcTable = &gNativeInterface;
    //pEnv->vm = pVM;
    memset(pVM, 0, sizeof(JavaVMExt));
    pVM->funcTable = &gInvokeInterface;
    pVM->envList = pEnv;
    dvmInitMutex(&pVM->envListLock);

    argv = (const char**) malloc(sizeof(char*) * (args->nOptions));
    memset(argv, 0, sizeof(char*) * (args->nOptions));

    curOpt = 0;

    /*
     * Convert JNI args to argv.
     *
     * We have to pull out vfprintf/exit/abort, because they use the
     * "extraInfo" field to pass function pointer "hooks" in.  We also
     * look for the -Xcheck:jni stuff here.
     */
    for (i = 0; i < args->nOptions; i++) {
        const char* optStr = args->options[i].optionString;

        if (optStr == NULL) {
            fprintf(stderr, "ERROR: arg %d string was null\n", i);
            goto bail;
        } else if (strcmp(optStr, "vfprintf") == 0) {
            gDvm.vfprintfHook = args->options[i].extraInfo;
        } else if (strcmp(optStr, "exit") == 0) {
            gDvm.exitHook = args->options[i].extraInfo;
        } else if (strcmp(optStr, "abort") == 0) {
            gDvm.abortHook = args->options[i].extraInfo;
        } else if (strcmp(optStr, "-Xcheck:jni") == 0) {
            checkJni = true;
        } else if (strncmp(optStr, "-Xjniopts:", 10) == 0) {
            const char* jniOpts = optStr + 9;
            while (jniOpts != NULL) {
                jniOpts++;      /* skip past ':' or ',' */
                if (strncmp(jniOpts, "warnonly", 8) == 0) {
                    warnError = false;
                } else if (strncmp(jniOpts, "forcecopy", 9) == 0) {
                    forceDataCopy = true;
                } else {
                    LOGW("unknown jni opt starting at '%s'\n", jniOpts);
                }
                jniOpts = strchr(jniOpts, ',');
            }
        } else {
            /* regular option */
            argv[curOpt++] = optStr;
        }
    }
    argc = curOpt;

    if (checkJni) {
        dvmUseCheckedJniVm(pVM);
        pVM->useChecked = true;
    }
    pVM->warnError = warnError;
    pVM->forceDataCopy = forceDataCopy;

    /* set this up before initializing VM, so it can create some JNIEnvs */
    gDvm.vmList = (JavaVM*) pVM;

    /*
     * Create an env for main thread.  We need to have something set up
     * here because some of the class initialization we do when starting
     * up the VM will call into native code.
     */
    pEnv = (JNIEnvExt*) dvmCreateJNIEnv(NULL);

    /* initialize VM */
    gDvm.initializing = true;
    if (dvmStartup(argc, argv, args->ignoreUnrecognized, (JNIEnv*)pEnv) != 0) {
        free(pEnv);
        free(pVM);
        goto bail;
    }

    /*
     * Success!  Return stuff to caller.
     */
    dvmChangeStatus(NULL, THREAD_NATIVE);
    *p_env = (JNIEnv*) pEnv;
    *p_vm = (JavaVM*) pVM;
    result = JNI_OK;

bail:
    gDvm.initializing = false;
    if (result == JNI_OK)
        LOGV("JNI_CreateJavaVM succeeded\n");
    else
        LOGW("JNI_CreateJavaVM failed\n");
    free(argv);
    return result;
}
