diff --git a/build/Android.common.mk b/build/Android.common.mk
index a801889..bd8a83b 100644
--- a/build/Android.common.mk
+++ b/build/Android.common.mk
@@ -41,6 +41,7 @@
 LIBART_COMMON_SRC_FILES := \
 	src/assembler.cc \
 	src/calling_convention.cc \
+	src/check_jni.cc \
 	src/class_linker.cc \
 	src/compiler.cc \
 	src/compiler/Dataflow.cc \
diff --git a/src/check_jni.cc b/src/check_jni.cc
new file mode 100644
index 0000000..130acef
--- /dev/null
+++ b/src/check_jni.cc
@@ -0,0 +1,2235 @@
+/*
+ * 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.
+ */
+
+#include "jni_internal.h"
+
+#include <sys/mman.h>
+#include <zlib.h>
+
+#include "class_linker.h"
+#include "logging.h"
+#include "thread.h"
+
+namespace art {
+
+void JniAbort(const char* jni_function_name) {
+  std::stringstream os;
+
+  // dvmDumpThread(dvmThreadSelf(), false);
+  os << "JNI app bug detected";
+
+  if (jni_function_name != NULL) {
+    os << "\n             in call to " << jni_function_name;
+  }
+  // TODO: say what native method we're in...
+  //const Method* method = dvmGetCurrentJNIMethod();
+  //os << "\n             in " << PrettyMethod(method);
+
+  JavaVMExt* vm = Runtime::Current()->GetJavaVM();
+  if (vm->check_jni_abort_hook != NULL) {
+    vm->check_jni_abort_hook(os.str());
+  } else {
+    LOG(FATAL) << os.str();
+  }
+}
+
+/*
+ * ===========================================================================
+ *      JNI function helpers
+ * ===========================================================================
+ */
+
+// TODO: remove this ODR violation!
+class ScopedJniThreadState {
+ public:
+  explicit ScopedJniThreadState(JNIEnv* env)
+  : env_(reinterpret_cast<JNIEnvExt*>(env)) {
+    self_ = ThreadForEnv(env);
+    self_->SetState(Thread::kRunnable);
+  }
+
+  ~ScopedJniThreadState() {
+    self_->SetState(Thread::kNative);
+  }
+
+  JNIEnvExt* Env() {
+    return env_;
+  }
+
+  Thread* Self() {
+    return self_;
+  }
+
+  JavaVMExt* Vm() {
+    return env_->vm;
+  }
+
+ private:
+  static Thread* ThreadForEnv(JNIEnv* env) {
+    // TODO: need replacement for gDvmJni.
+    bool workAroundAppJniBugs = true;
+    Thread* env_self = reinterpret_cast<JNIEnvExt*>(env)->self;
+    Thread* self = workAroundAppJniBugs ? Thread::Current() : env_self;
+    if (self != env_self) {
+      LOG(ERROR) << "JNI ERROR: JNIEnv for " << *env_self
+                 << " used on " << *self;
+      // TODO: dump stack
+    }
+    return self;
+  }
+
+  JNIEnvExt* env_;
+  Thread* self_;
+  DISALLOW_COPY_AND_ASSIGN(ScopedJniThreadState);
+};
+
+template<typename T>
+T Decode(ScopedJniThreadState& ts, jobject obj) {
+  return reinterpret_cast<T>(ts.Self()->DecodeJObject(obj));
+}
+
+/* for IsValidMemberNameUtf8(), a bit vector indicating valid low ascii */
+uint32_t DEX_MEMBER_VALID_LOW_ASCII[4] = {
+  0x00000000, // 00..1f low control characters; nothing valid
+  0x03ff2010, // 20..3f digits and symbols; valid: '0'..'9', '$', '-'
+  0x87fffffe, // 40..5f uppercase etc.; valid: 'A'..'Z', '_'
+  0x07fffffe  // 60..7f lowercase etc.; valid: 'a'..'z'
+};
+
+/* Helper for IsValidMemberNameUtf8(); do not call directly. */
+bool IsValidMemberNameUtf8Slow(const char** pUtf8Ptr) {
+  /*
+   * It's a multibyte encoded character. Decode it and analyze. We
+   * accept anything that isn't (a) an improperly encoded low value,
+   * (b) an improper surrogate pair, (c) an encoded '\0', (d) a high
+   * control character, or (e) a high space, layout, or special
+   * character (U+00a0, U+2000..U+200f, U+2028..U+202f,
+   * U+fff0..U+ffff). This is all specified in the dex format
+   * document.
+   */
+
+  uint16_t utf16 = GetUtf16FromUtf8(pUtf8Ptr);
+
+  // Perform follow-up tests based on the high 8 bits.
+  switch (utf16 >> 8) {
+  case 0x00:
+    // It's only valid if it's above the ISO-8859-1 high space (0xa0).
+    return (utf16 > 0x00a0);
+  case 0xd8:
+  case 0xd9:
+  case 0xda:
+  case 0xdb:
+    // It's a leading surrogate. Check to see that a trailing
+    // surrogate follows.
+    utf16 = GetUtf16FromUtf8(pUtf8Ptr);
+    return (utf16 >= 0xdc00) && (utf16 <= 0xdfff);
+  case 0xdc:
+  case 0xdd:
+  case 0xde:
+  case 0xdf:
+    // It's a trailing surrogate, which is not valid at this point.
+    return false;
+  case 0x20:
+  case 0xff:
+    // It's in the range that has spaces, controls, and specials.
+    switch (utf16 & 0xfff8) {
+    case 0x2000:
+    case 0x2008:
+    case 0x2028:
+    case 0xfff0:
+    case 0xfff8:
+      return false;
+    }
+    break;
+  }
+  return true;
+}
+
+/* Return whether the pointed-at modified-UTF-8 encoded character is
+ * valid as part of a member name, updating the pointer to point past
+ * the consumed character. This will consume two encoded UTF-16 code
+ * points if the character is encoded as a surrogate pair. Also, if
+ * this function returns false, then the given pointer may only have
+ * been partially advanced.
+ */
+bool IsValidMemberNameUtf8(const char** pUtf8Ptr) {
+  uint8_t c = (uint8_t) **pUtf8Ptr;
+  if (c <= 0x7f) {
+    // It's low-ascii, so check the table.
+    uint32_t wordIdx = c >> 5;
+    uint32_t bitIdx = c & 0x1f;
+    (*pUtf8Ptr)++;
+    return (DEX_MEMBER_VALID_LOW_ASCII[wordIdx] & (1 << bitIdx)) != 0;
+  }
+
+  // It's a multibyte encoded character. Call a non-inline function
+  // for the heavy lifting.
+  return IsValidMemberNameUtf8Slow(pUtf8Ptr);
+}
+
+bool IsValidClassName(const char* s, bool isClassName, bool dotSeparator) {
+  int arrayCount = 0;
+
+  while (*s == '[') {
+    arrayCount++;
+    s++;
+  }
+
+  if (arrayCount > 255) {
+    // Arrays may have no more than 255 dimensions.
+    return false;
+  }
+
+  if (arrayCount != 0) {
+    /*
+     * If we're looking at an array of some sort, then it doesn't
+     * matter if what is being asked for is a class name; the
+     * format looks the same as a type descriptor in that case, so
+     * treat it as such.
+     */
+    isClassName = false;
+  }
+
+  if (!isClassName) {
+    /*
+     * We are looking for a descriptor. Either validate it as a
+     * single-character primitive type, or continue on to check the
+     * embedded class name (bracketed by "L" and ";").
+     */
+    switch (*(s++)) {
+    case 'B':
+    case 'C':
+    case 'D':
+    case 'F':
+    case 'I':
+    case 'J':
+    case 'S':
+    case 'Z':
+      // These are all single-character descriptors for primitive types.
+      return (*s == '\0');
+    case 'V':
+      // Non-array void is valid, but you can't have an array of void.
+      return (arrayCount == 0) && (*s == '\0');
+    case 'L':
+      // Class name: Break out and continue below.
+      break;
+    default:
+      // Oddball descriptor character.
+      return false;
+    }
+  }
+
+  /*
+   * We just consumed the 'L' that introduces a class name as part
+   * of a type descriptor, or we are looking for an unadorned class
+   * name.
+   */
+
+  bool sepOrFirst = true; // first character or just encountered a separator.
+  for (;;) {
+    uint8_t c = (uint8_t) *s;
+    switch (c) {
+    case '\0':
+      /*
+       * Premature end for a type descriptor, but valid for
+       * a class name as long as we haven't encountered an
+       * empty component (including the degenerate case of
+       * the empty string "").
+       */
+      return isClassName && !sepOrFirst;
+    case ';':
+      /*
+       * Invalid character for a class name, but the
+       * legitimate end of a type descriptor. In the latter
+       * case, make sure that this is the end of the string
+       * and that it doesn't end with an empty component
+       * (including the degenerate case of "L;").
+       */
+      return !isClassName && !sepOrFirst && (s[1] == '\0');
+    case '/':
+    case '.':
+      if (dotSeparator != (c == '.')) {
+        // The wrong separator character.
+        return false;
+      }
+      if (sepOrFirst) {
+        // Separator at start or two separators in a row.
+        return false;
+      }
+      sepOrFirst = true;
+      s++;
+      break;
+    default:
+      if (!IsValidMemberNameUtf8(&s)) {
+        return false;
+      }
+      sepOrFirst = false;
+      break;
+    }
+  }
+}
+
+/*
+ * Hack to allow forcecopy to work with jniGetNonMovableArrayElements.
+ * The code deliberately uses an invalid sequence of operations, so we
+ * need to pass it through unmodified.  Review that code before making
+ * any changes here.
+ */
+#define kNoCopyMagic    0xd5aab57f
+
+/*
+ * Flags passed into ScopedCheck.
+ */
+#define kFlag_Default       0x0000
+
+#define kFlag_CritBad       0x0000      /* calling while in critical is bad */
+#define kFlag_CritOkay      0x0001      /* ...okay */
+#define kFlag_CritGet       0x0002      /* this is a critical "get" */
+#define kFlag_CritRelease   0x0003      /* this is a critical "release" */
+#define kFlag_CritMask      0x0003      /* bit mask to get "crit" value */
+
+#define kFlag_ExcepBad      0x0000      /* raised exceptions are bad */
+#define kFlag_ExcepOkay     0x0004      /* ...okay */
+
+#define kFlag_Release       0x0010      /* are we in a non-critical release function? */
+#define kFlag_NullableUtf   0x0020      /* are our UTF parameters nullable? */
+
+#define kFlag_Invocation    0x8000      /* Part of the invocation interface (JavaVM*) */
+
+class ScopedCheck {
+public:
+  // For JNIEnv* functions.
+  explicit ScopedCheck(JNIEnv* env, int flags, const char* functionName) {
+    init(env, flags, functionName, true);
+    checkThread(flags);
+  }
+
+  // For JavaVM* functions.
+  explicit ScopedCheck(bool hasMethod, const char* functionName) {
+    init(NULL, kFlag_Invocation, functionName, hasMethod);
+  }
+
+  bool forceCopy() {
+    return Runtime::Current()->GetJavaVM()->force_copy;
+  }
+
+  /*
+   * In some circumstances the VM will screen class names, but it doesn't
+   * for class lookup.  When things get bounced through a class loader, they
+   * can actually get normalized a couple of times; as a result, passing in
+   * a class name like "java.lang.Thread" instead of "java/lang/Thread" will
+   * work in some circumstances.
+   *
+   * This is incorrect and could cause strange behavior or compatibility
+   * problems, so we want to screen that out here.
+   *
+   * We expect "fully-qualified" class names, like "java/lang/Thread" or
+   * "[Ljava/lang/Object;".
+   */
+  void checkClassName(const char* className) {
+    if (!IsValidClassName(className, true, false)) {
+      LOG(ERROR) << "JNI ERROR: illegal class name '" << className << "' (" << mFunctionName << ")\n"
+                 << "           (should be of the form 'java/lang/String', [Ljava/lang/String;' or '[[B')\n";
+      JniAbort();
+    }
+  }
+
+  /*
+   * Verify that the field is of the appropriate type.  If the field has an
+   * object type, "java_object" is the object we're trying to assign into it.
+   *
+   * Works for both static and instance fields.
+   */
+  void checkFieldType(jobject java_object, jfieldID fid, char prim, bool isStatic) {
+    if (fid == NULL) {
+      LOG(ERROR) << "JNI ERROR: null jfieldID";
+      JniAbort();
+      return;
+    }
+
+    ScopedJniThreadState ts(mEnv);
+    Field* f = DecodeField(ts, fid);
+    if ((f->GetType() == 'L' || f->GetType() == '[') && java_object != NULL) {
+      Object* obj = Decode<Object*>(ts, java_object);
+      /*
+       * If java_object is a weak global ref whose referent has been cleared,
+       * obj will be NULL.  Otherwise, obj should always be non-NULL
+       * and valid.
+       */
+      if (obj != NULL && !Heap::IsHeapAddress(obj)) {
+        LOG(ERROR) << "JNI ERROR: field operation on invalid " << GetIndirectRefKind(java_object) << ": " << java_object;
+        JniAbort();
+        return;
+      } else {
+#if 0
+        Class* field_class = dvmFindLoadedClass(f->signature);
+        if (!obj->GetClass()->InstanceOf(field_class)) {
+          LOG(ERROR) << "JNI ERROR: attempt to set field " << PrettyField(f) << " with value of wrong type: " << PrettyType(java_object);
+          JniAbort();
+          return;
+        }
+#else
+        UNIMPLEMENTED(WARNING) << "need way to get Class* for a given Field*'s type";
+#endif
+      }
+    } else if (f->GetType() != prim) {
+      LOG(ERROR) << "JNI ERROR: attempt to set field " << PrettyField(f) << " with value of wrong type: " << prim;
+      JniAbort();
+      return;
+    } else if (isStatic && !f->IsStatic()) {
+      if (isStatic) {
+        LOG(ERROR) << "JNI ERROR: accessing non-static field " << PrettyField(f) << " as static";
+      } else {
+        LOG(ERROR) << "JNI ERROR: accessing static field " << PrettyField(f) << " as non-static";
+      }
+      JniAbort();
+      return;
+    }
+  }
+
+  /*
+   * Verify that this instance field ID is valid for this object.
+   *
+   * Assumes "jobj" has already been validated.
+   */
+  void checkInstanceFieldID(jobject java_object, jfieldID fid) {
+    ScopedJniThreadState ts(mEnv);
+
+    Object* o = Decode<Object*>(ts, java_object);
+    if (!Heap::IsHeapAddress(o)) {
+      LOG(ERROR) << "JNI ERROR: field operation on invalid " << GetIndirectRefKind(java_object) << ": " << java_object;
+      JniAbort();
+      return;
+    }
+
+    Field* f = DecodeField(ts, fid);
+    Class* c = o->GetClass();
+    if (c->FindInstanceField(f->GetName()->ToModifiedUtf8(), f->GetDescriptor()) == NULL) {
+      LOG(ERROR) << "JNI ERROR: jfieldID " << PrettyField(f) << " not valid for an object of class " << PrettyType(o);
+      JniAbort();
+    }
+  }
+
+  /*
+   * Verify that the pointer value is non-NULL.
+   */
+  void checkNonNull(const void* ptr) {
+    if (ptr == NULL) {
+      LOG(ERROR) << "JNI ERROR: invalid null pointer";
+      JniAbort();
+    }
+  }
+
+  /*
+   * Verify that the method's return type matches the type of call.
+   * 'expectedType' will be "L" for all objects, including arrays.
+   */
+  void checkSig(jmethodID mid, const char* expectedType, bool isStatic) {
+    ScopedJniThreadState ts(mEnv);
+    const Method* m = DecodeMethod(ts, mid);
+    if (*expectedType != m->GetShorty()[0]) {
+      LOG(ERROR) << "JNI ERROR: expected return type '%s' calling " << PrettyMethod(m);
+      JniAbort();
+    } else if (isStatic && !m->IsStatic()) {
+      if (isStatic) {
+        LOG(ERROR) << "JNI ERROR: calling non-static method " << PrettyMethod(m) << " with static call";
+      } else {
+        LOG(ERROR) << "JNI ERROR: calling static method " << PrettyMethod(m) << " with non-static call";
+      }
+      JniAbort();
+    }
+  }
+
+  /*
+   * Verify that this static field ID is valid for this class.
+   *
+   * Assumes "java_class" has already been validated.
+   */
+  void checkStaticFieldID(jclass java_class, jfieldID fid) {
+    ScopedJniThreadState ts(mEnv);
+    Class* c = Decode<Class*>(ts, java_class);
+    const Field* f = DecodeField(ts, fid);
+    if (f->GetDeclaringClass() != c) {
+      LOG(ERROR) << "JNI ERROR: static jfieldID " << fid << " not valid for class " << PrettyDescriptor(c->GetDescriptor());
+      JniAbort();
+    }
+  }
+
+  /*
+   * Verify that "mid" is appropriate for "clazz".
+   *
+   * A mismatch isn't dangerous, because the jmethodID defines the class.  In
+   * fact, jclazz is unused in the implementation.  It's best if we don't
+   * allow bad code in the system though.
+   *
+   * Instances of "jclazz" must be instances of the method's declaring class.
+   */
+  void checkStaticMethod(jclass java_class, jmethodID mid) {
+    ScopedJniThreadState ts(mEnv);
+    Class* c = Decode<Class*>(ts, java_class);
+    const Method* m = DecodeMethod(ts, mid);
+    if (!c->IsAssignableFrom(m->GetDeclaringClass())) {
+      LOG(ERROR) << "JNI ERROR: can't call static " << PrettyMethod(m) << " on class " << PrettyDescriptor(c->GetDescriptor());
+      JniAbort();
+    }
+  }
+
+  /*
+   * Verify that "mid" is appropriate for "jobj".
+   *
+   * Make sure the object is an instance of the method's declaring class.
+   * (Note the mid might point to a declaration in an interface; this
+   * will be handled automatically by the instanceof check.)
+   */
+  void checkVirtualMethod(jobject java_object, jmethodID mid) {
+    ScopedJniThreadState ts(mEnv);
+    Object* o = Decode<Object*>(ts, java_object);
+    const Method* m = DecodeMethod(ts, mid);
+    if (!o->InstanceOf(m->GetDeclaringClass())) {
+      LOG(ERROR) << "JNI ERROR: can't call " << PrettyMethod(m) << " on instance of " << PrettyType(o);
+      JniAbort();
+    }
+  }
+
+  /**
+   * The format string is a sequence of the following characters,
+   * and must be followed by arguments of the corresponding types
+   * in the same order.
+   *
+   * Java primitive types:
+   * B - jbyte
+   * C - jchar
+   * D - jdouble
+   * F - jfloat
+   * I - jint
+   * J - jlong
+   * S - jshort
+   * Z - jboolean (shown as true and false)
+   * V - void
+   *
+   * Java reference types:
+   * L - jobject
+   * a - jarray
+   * c - jclass
+   * s - jstring
+   *
+   * JNI types:
+   * b - jboolean (shown as JNI_TRUE and JNI_FALSE)
+   * f - jfieldID
+   * m - jmethodID
+   * p - void*
+   * r - jint (for release mode arguments)
+   * u - const char* (modified UTF-8)
+   * z - jsize (for lengths; use i if negative values are okay)
+   * v - JavaVM*
+   * E - JNIEnv*
+   * . - no argument; just print "..." (used for varargs JNI calls)
+   *
+   * Use the kFlag_NullableUtf flag where 'u' field(s) are nullable.
+   */
+  void check(bool entry, const char* fmt0, ...) {
+    va_list ap;
+
+    bool shouldTrace = false;
+    const Method* method = NULL;
+#if 0
+    if ((gDvm.jniTrace || gDvmJni.logThirdPartyJni) && mHasMethod) {
+      // We need to guard some of the invocation interface's calls: a bad caller might
+      // use DetachCurrentThread or GetEnv on a thread that's not yet attached.
+      if ((mFlags & kFlag_Invocation) == 0 || dvmThreadSelf() != NULL) {
+        method = dvmGetCurrentJNIMethod();
+      }
+    }
+    if (method != NULL) {
+      // If both "-Xcheck:jni" and "-Xjnitrace:" are enabled, we print trace messages
+      // when a native method that matches the Xjnitrace argument calls a JNI function
+      // such as NewByteArray.
+      if (gDvm.jniTrace && strstr(method->clazz->descriptor, gDvm.jniTrace) != NULL) {
+        shouldTrace = true;
+      }
+      // If -Xjniopts:logThirdPartyJni is on, we want to log any JNI function calls
+      // made by a third-party native method.
+      if (gDvmJni.logThirdPartyJni) {
+        shouldTrace |= method->shouldTrace;
+      }
+    }
+#endif
+    if (shouldTrace) {
+      va_start(ap, fmt0);
+      std::string msg;
+      for (const char* fmt = fmt0; *fmt;) {
+        char ch = *fmt++;
+        if (ch == 'B') { // jbyte
+          jbyte b = va_arg(ap, int);
+          if (b >= 0 && b < 10) {
+            StringAppendF(&msg, "%d", b);
+          } else {
+            StringAppendF(&msg, "%#x (%d)", b, b);
+          }
+        } else if (ch == 'C') { // jchar
+          jchar c = va_arg(ap, int);
+          if (c < 0x7f && c >= ' ') {
+            StringAppendF(&msg, "U+%x ('%c')", c, c);
+          } else {
+            StringAppendF(&msg, "U+%x", c);
+          }
+        } else if (ch == 'F' || ch == 'D') { // jfloat, jdouble
+          StringAppendF(&msg, "%g", va_arg(ap, double));
+        } else if (ch == 'I' || ch == 'S') { // jint, jshort
+          StringAppendF(&msg, "%d", va_arg(ap, int));
+        } else if (ch == 'J') { // jlong
+          StringAppendF(&msg, "%lld", va_arg(ap, jlong));
+        } else if (ch == 'Z') { // jboolean
+          StringAppendF(&msg, "%s", va_arg(ap, int) ? "true" : "false");
+        } else if (ch == 'V') { // void
+          msg += "void";
+        } else if (ch == 'v') { // JavaVM*
+          JavaVM* vm = va_arg(ap, JavaVM*);
+          StringAppendF(&msg, "(JavaVM*)%p", vm);
+        } else if (ch == 'E') { // JNIEnv*
+          JNIEnv* env = va_arg(ap, JNIEnv*);
+          StringAppendF(&msg, "(JNIEnv*)%p", env);
+        } else if (ch == 'L' || ch == 'a' || ch == 's') { // jobject, jarray, jstring
+          // For logging purposes, these are identical.
+          jobject o = va_arg(ap, jobject);
+          if (o == NULL) {
+            msg += "NULL";
+          } else {
+            StringAppendF(&msg, "%p", o);
+          }
+        } else if (ch == 'b') { // jboolean (JNI-style)
+          jboolean b = va_arg(ap, int);
+          msg += (b ? "JNI_TRUE" : "JNI_FALSE");
+        } else if (ch == 'c') { // jclass
+          jclass jc = va_arg(ap, jclass);
+          Class* c = reinterpret_cast<Class*>(Thread::Current()->DecodeJObject(jc));
+          if (c == NULL) {
+            msg += "NULL";
+          } else if (c == kInvalidIndirectRefObject || !Heap::IsHeapAddress(c)) {
+            StringAppendF(&msg, "%p(INVALID)", jc);
+          } else {
+            msg += PrettyDescriptor(c->GetDescriptor());
+            if (!entry) {
+              StringAppendF(&msg, " (%p)", jc);
+            }
+          }
+        } else if (ch == 'f') { // jfieldID
+          jfieldID fid = va_arg(ap, jfieldID);
+          Field* f = reinterpret_cast<Field*>(Thread::Current()->DecodeJObject(reinterpret_cast<jweak>(fid)));
+          msg += PrettyField(f);
+          if (!entry) {
+            StringAppendF(&msg, " (%p)", fid);
+          }
+        } else if (ch == 'z') { // non-negative jsize
+          // You might expect jsize to be size_t, but it's not; it's the same as jint.
+          // We only treat this specially so we can do the non-negative check.
+          // TODO: maybe this wasn't worth it?
+          jint i = va_arg(ap, jint);
+          StringAppendF(&msg, "%d", i);
+        } else if (ch == 'm') { // jmethodID
+          jmethodID mid = va_arg(ap, jmethodID);
+          Method* m = reinterpret_cast<Method*>(Thread::Current()->DecodeJObject(reinterpret_cast<jweak>(mid)));
+          msg += PrettyMethod(m);
+          if (!entry) {
+            StringAppendF(&msg, " (%p)", mid);
+          }
+        } else if (ch == 'p') { // void* ("pointer")
+          void* p = va_arg(ap, void*);
+          if (p == NULL) {
+            msg += "NULL";
+          } else {
+            StringAppendF(&msg, "(void*) %p", p);
+          }
+        } else if (ch == 'r') { // jint (release mode)
+          jint releaseMode = va_arg(ap, jint);
+          if (releaseMode == 0) {
+            msg += "0";
+          } else if (releaseMode == JNI_ABORT) {
+            msg += "JNI_ABORT";
+          } else if (releaseMode == JNI_COMMIT) {
+            msg += "JNI_COMMIT";
+          } else {
+            StringAppendF(&msg, "invalid release mode %d", releaseMode);
+          }
+        } else if (ch == 'u') { // const char* (modified UTF-8)
+          const char* utf = va_arg(ap, const char*);
+          if (utf == NULL) {
+            msg += "NULL";
+          } else {
+            StringAppendF(&msg, "\"%s\"", utf);
+          }
+        } else if (ch == '.') {
+          msg += "...";
+        } else {
+          LOG(ERROR) << "unknown trace format specifier: " << ch;
+          JniAbort();
+          return;
+        }
+        if (*fmt) {
+          StringAppendF(&msg, ", ");
+        }
+      }
+      va_end(ap);
+
+      if (entry) {
+        if (mHasMethod) {
+          std::string methodName(PrettyMethod(method, false));
+          LOG(INFO) << "JNI: " << methodName << " -> " << mFunctionName << "(" << msg << ")";
+          mIndent = methodName.size() + 1;
+        } else {
+          LOG(INFO) << "JNI: -> " << mFunctionName << "(" << msg << ")";
+          mIndent = 0;
+        }
+      } else {
+        LOG(INFO) << StringPrintf("JNI: %*s<- %s returned %s", mIndent, "", mFunctionName, msg.c_str());
+      }
+    }
+
+    // We always do the thorough checks on entry, and never on exit...
+    if (entry) {
+      va_start(ap, fmt0);
+      for (const char* fmt = fmt0; *fmt; ++fmt) {
+        char ch = *fmt;
+        if (ch == 'a') {
+          checkArray(va_arg(ap, jarray));
+        } else if (ch == 'c') {
+          checkInstance(kClass, va_arg(ap, jclass));
+        } else if (ch == 'L') {
+          checkObject(va_arg(ap, jobject));
+        } else if (ch == 'r') {
+          checkReleaseMode(va_arg(ap, jint));
+        } else if (ch == 's') {
+          checkInstance(kString, va_arg(ap, jstring));
+        } else if (ch == 'u') {
+          if ((mFlags & kFlag_Release) != 0) {
+            checkNonNull(va_arg(ap, const char*));
+          } else {
+            bool nullable = ((mFlags & kFlag_NullableUtf) != 0);
+            checkUtfString(va_arg(ap, const char*), nullable);
+          }
+        } else if (ch == 'z') {
+          checkLengthPositive(va_arg(ap, jsize));
+        } else if (strchr("BCISZbfmpEv", ch) != NULL) {
+          va_arg(ap, int); // Skip this argument.
+        } else if (ch == 'D' || ch == 'F') {
+          va_arg(ap, double); // Skip this argument.
+        } else if (ch == 'J') {
+          va_arg(ap, long); // Skip this argument.
+        } else if (ch == '.') {
+        } else {
+          LOG(FATAL) << "unknown check format specifier: " << ch;
+        }
+      }
+      va_end(ap);
+    }
+  }
+
+private:
+  Field* DecodeField(ScopedJniThreadState& ts, jfieldID fid) {
+    return Decode<Field*>(ts, reinterpret_cast<jweak>(fid));
+  }
+
+  Method* DecodeMethod(ScopedJniThreadState& ts, jmethodID mid) {
+    return Decode<Method*>(ts, reinterpret_cast<jweak>(mid));
+  }
+
+  void init(JNIEnv* env, int flags, const char* functionName, bool hasMethod) {
+    mEnv = reinterpret_cast<JNIEnvExt*>(env);
+    mFlags = flags;
+    mFunctionName = functionName;
+
+    // Set "hasMethod" to true if we have a valid thread with a method pointer.
+    // We won't have one before attaching a thread, after detaching a thread, or
+    // after destroying the VM.
+    mHasMethod = hasMethod;
+  }
+
+  /*
+   * Verify that "array" is non-NULL and points to an Array object.
+   *
+   * Since we're dealing with objects, switch to "running" mode.
+   */
+  void checkArray(jarray java_array) {
+    if (java_array == NULL) {
+      LOG(ERROR) << "JNI ERROR: received null array";
+      JniAbort();
+      return;
+    }
+
+    ScopedJniThreadState ts(mEnv);
+    Array* a = Decode<Array*>(ts, java_array);
+    if (!Heap::IsHeapAddress(a)) {
+      LOG(ERROR) << "JNI ERROR: jarray is an invalid " << GetIndirectRefKind(java_array) << ": " << reinterpret_cast<void*>(java_array);
+      JniAbort();
+    } else if (!a->IsArrayInstance()) {
+      LOG(ERROR) << "JNI ERROR: jarray argument has non-array type: " << PrettyType(a);
+      JniAbort();
+    }
+  }
+
+  void checkLengthPositive(jsize length) {
+    if (length < 0) {
+      LOG(ERROR) << "JNI ERROR: negative jsize: " << length;
+      JniAbort();
+    }
+  }
+
+  /*
+   * Verify that "jobj" is a valid object, and that it's an object that JNI
+   * is allowed to know about.  We allow NULL references.
+   *
+   * Switches to "running" mode before performing checks.
+   */
+  void checkObject(jobject java_object) {
+    if (java_object == NULL) {
+      return;
+    }
+
+    ScopedJniThreadState ts(mEnv);
+
+    Object* o = Decode<Object*>(ts, java_object);
+    if (o != NULL && !Heap::IsHeapAddress(o)) {
+      // TODO: when we remove workAroundAppJniBugs, this should be impossible.
+      LOG(ERROR) << "JNI ERROR: native code passing in reference to invalid " << GetIndirectRefKind(java_object) << ": " << java_object;
+      JniAbort();
+    }
+  }
+
+  /*
+   * Verify that the "mode" argument passed to a primitive array Release
+   * function is one of the valid values.
+   */
+  void checkReleaseMode(jint mode) {
+    if (mode != 0 && mode != JNI_COMMIT && mode != JNI_ABORT) {
+      LOG(ERROR) << "JNI ERROR: bad value for release mode: " << mode;
+      JniAbort();
+    }
+  }
+
+  void checkThread(int flags) {
+    Thread* self = Thread::Current();
+    if (self == NULL) {
+      LOG(ERROR) << "JNI ERROR: non-VM thread making JNI calls";
+      JniAbort();
+      return;
+    }
+
+    // Get the *correct* JNIEnv by going through our TLS pointer.
+    JNIEnvExt* threadEnv = self->GetJniEnv();
+
+    /*
+     * Verify that the current thread is (a) attached and (b) associated with
+     * this particular instance of JNIEnv.
+     */
+    if (mEnv != threadEnv) {
+      LOG(ERROR) << "JNI ERROR: thread " << *self << " using JNIEnv* from thread " << *mEnv->self;
+      // If we're keeping broken code limping along, we need to suppress the abort...
+      if (true/* TODO: !gDvmJni.workAroundAppJniBugs*/) {
+        JniAbort();
+        return;
+      }
+    }
+
+    /*
+     * Verify that, if this thread previously made a critical "get" call, we
+     * do the corresponding "release" call before we try anything else.
+     */
+    switch (flags & kFlag_CritMask) {
+    case kFlag_CritOkay:    // okay to call this method
+      break;
+    case kFlag_CritBad:     // not okay to call
+      if (threadEnv->critical) {
+        LOG(ERROR) << "JNI ERROR: thread " << *self << " using JNI after critical get";
+        JniAbort();
+        return;
+      }
+      break;
+    case kFlag_CritGet:     // this is a "get" call
+      /* don't check here; we allow nested gets */
+      threadEnv->critical++;
+      break;
+    case kFlag_CritRelease: // this is a "release" call
+      threadEnv->critical--;
+      if (threadEnv->critical < 0) {
+        LOG(ERROR) << "JNI ERROR: thread " << *self << " called too many critical releases";
+        JniAbort();
+        return;
+      }
+      break;
+    default:
+      LOG(FATAL) << "bad flags (internal error): " << flags;
+    }
+
+    /*
+     * Verify that, if an exception has been raised, the native code doesn't
+     * make any JNI calls other than the Exception* methods.
+     */
+    if ((flags & kFlag_ExcepOkay) == 0 && self->IsExceptionPending()) {
+      LOG(ERROR) << "JNI ERROR: JNI method called with exception pending";
+      LOG(ERROR) << "Pending exception is: TODO"; // TODO
+      // TODO: dvmLogExceptionStackTrace();
+      JniAbort();
+      return;
+    }
+  }
+
+  /*
+   * Verify that "bytes" points to valid "modified UTF-8" data.
+   */
+  void checkUtfString(const char* bytes, bool nullable) {
+    if (bytes == NULL) {
+      if (!nullable) {
+        LOG(ERROR) << "JNI ERROR: non-nullable const char* was NULL";
+        JniAbort();
+        return;
+      }
+      return;
+    }
+
+    const char* errorKind = NULL;
+    uint8_t utf8 = checkUtfBytes(bytes, &errorKind);
+    if (errorKind != NULL) {
+      LOG(ERROR) << "JNI ERROR: input is not valid UTF-8: illegal " << errorKind << " byte " << StringPrintf("%#x", utf8);
+      LOG(ERROR) << "           string: '" << bytes << "'";
+      JniAbort();
+      return;
+    }
+  }
+
+  enum InstanceKind {
+    kClass,
+    kDirectByteBuffer,
+    kString,
+    kThrowable,
+  };
+
+  /*
+   * Verify that "jobj" is a valid non-NULL object reference, and points to
+   * an instance of expectedClass.
+   *
+   * Because we're looking at an object on the GC heap, we have to switch
+   * to "running" mode before doing the checks.
+   */
+  void checkInstance(InstanceKind kind, jobject java_object) {
+    const char* what;
+    switch (kind) {
+    case kClass:
+      what = "jclass";
+      break;
+    case kDirectByteBuffer:
+      what = "direct ByteBuffer";
+      break;
+    case kString:
+      what = "jstring";
+      break;
+    case kThrowable:
+      what = "jthrowable";
+      break;
+    default:
+      CHECK(false) << static_cast<int>(kind);
+    }
+
+    if (java_object == NULL) {
+      LOG(ERROR) << "JNI ERROR: received null " << what;
+      JniAbort();
+      return;
+    }
+
+    ScopedJniThreadState ts(mEnv);
+    Object* obj = Decode<Object*>(ts, java_object);
+    if (!Heap::IsHeapAddress(obj)) {
+      LOG(ERROR) << "JNI ERROR: " << what << " is an invalid  " << GetIndirectRefKind(java_object) << ": " << java_object;
+      JniAbort();
+      return;
+    }
+
+    bool okay = true;
+    switch (kind) {
+    case kClass:
+      okay = obj->IsClass();
+      break;
+    case kDirectByteBuffer:
+      // TODO
+      break;
+    case kString:
+      okay = obj->IsString();
+      break;
+    case kThrowable:
+      // TODO
+      break;
+    }
+    if (!okay) {
+      LOG(ERROR) << "JNI ERROR: " << what << " has wrong type: " << PrettyType(obj);
+      JniAbort();
+    }
+  }
+
+  static uint8_t checkUtfBytes(const char* bytes, const char** errorKind) {
+    while (*bytes != '\0') {
+      uint8_t utf8 = *(bytes++);
+      // Switch on the high four bits.
+      switch (utf8 >> 4) {
+      case 0x00:
+      case 0x01:
+      case 0x02:
+      case 0x03:
+      case 0x04:
+      case 0x05:
+      case 0x06:
+      case 0x07:
+        // Bit pattern 0xxx. No need for any extra bytes.
+        break;
+      case 0x08:
+      case 0x09:
+      case 0x0a:
+      case 0x0b:
+      case 0x0f:
+        /*
+         * Bit pattern 10xx or 1111, which are illegal start bytes.
+         * Note: 1111 is valid for normal UTF-8, but not the
+         * modified UTF-8 used here.
+         */
+        *errorKind = "start";
+        return utf8;
+      case 0x0e:
+        // Bit pattern 1110, so there are two additional bytes.
+        utf8 = *(bytes++);
+        if ((utf8 & 0xc0) != 0x80) {
+          *errorKind = "continuation";
+          return utf8;
+        }
+        // Fall through to take care of the final byte.
+      case 0x0c:
+      case 0x0d:
+        // Bit pattern 110x, so there is one additional byte.
+        utf8 = *(bytes++);
+        if ((utf8 & 0xc0) != 0x80) {
+          *errorKind = "continuation";
+          return utf8;
+        }
+        break;
+      }
+    }
+    return 0;
+  }
+
+  void JniAbort() {
+    ::art::JniAbort(mFunctionName);
+  }
+
+  JNIEnvExt* mEnv;
+  const char* mFunctionName;
+  int mFlags;
+  bool mHasMethod;
+  size_t mIndent;
+
+  DISALLOW_COPY_AND_ASSIGN(ScopedCheck);
+};
+
+#define CHECK_JNI_ENTRY(flags, types, args...) \
+  ScopedCheck sc(env, flags, __FUNCTION__); \
+  sc.check(true, types, ##args)
+
+#define CHECK_JNI_EXIT(type, exp) ({ \
+  typeof (exp) _rc = (exp); \
+  sc.check(false, type, _rc); \
+  _rc; })
+#define CHECK_JNI_EXIT_VOID() \
+  sc.check(false, "V")
+
+/*
+ * ===========================================================================
+ *      Guarded arrays
+ * ===========================================================================
+ */
+
+#define kGuardLen       512         /* must be multiple of 2 */
+#define kGuardPattern   0xd5e3      /* uncommon values; d5e3d5e3 invalid addr */
+#define kGuardMagic     0xffd5aa96
+
+/* this gets tucked in at the start of the buffer; struct size must be even */
+struct GuardedCopy {
+  uint32_t magic;
+  uLong adler;
+  size_t originalLen;
+  const void* originalPtr;
+
+  /* find the GuardedCopy given the pointer into the "live" data */
+  static inline const GuardedCopy* fromData(const void* dataBuf) {
+    return reinterpret_cast<const GuardedCopy*>(actualBuffer(dataBuf));
+  }
+
+  /*
+   * Create an over-sized buffer to hold the contents of "buf".  Copy it in,
+   * filling in the area around it with guard data.
+   *
+   * We use a 16-bit pattern to make a rogue memset less likely to elude us.
+   */
+  static void* create(const void* buf, size_t len, bool modOkay) {
+    size_t newLen = actualLength(len);
+    uint8_t* newBuf = debugAlloc(newLen);
+
+    /* fill it in with a pattern */
+    uint16_t* pat = (uint16_t*) newBuf;
+    for (size_t i = 0; i < newLen / 2; i++) {
+      *pat++ = kGuardPattern;
+    }
+
+    /* copy the data in; note "len" could be zero */
+    memcpy(newBuf + kGuardLen / 2, buf, len);
+
+    /* if modification is not expected, grab a checksum */
+    uLong adler = 0;
+    if (!modOkay) {
+      adler = adler32(0L, Z_NULL, 0);
+      adler = adler32(adler, (const Bytef*)buf, len);
+      *(uLong*)newBuf = adler;
+    }
+
+    GuardedCopy* pExtra = reinterpret_cast<GuardedCopy*>(newBuf);
+    pExtra->magic = kGuardMagic;
+    pExtra->adler = adler;
+    pExtra->originalPtr = buf;
+    pExtra->originalLen = len;
+
+    return newBuf + kGuardLen / 2;
+  }
+
+  /*
+   * Free up the guard buffer, scrub it, and return the original pointer.
+   */
+  static void* destroy(void* dataBuf) {
+    const GuardedCopy* pExtra = GuardedCopy::fromData(dataBuf);
+    void* originalPtr = (void*) pExtra->originalPtr;
+    size_t len = pExtra->originalLen;
+    debugFree(dataBuf, len);
+    return originalPtr;
+  }
+
+  /*
+   * Verify the guard area and, if "modOkay" is false, that the data itself
+   * has not been altered.
+   *
+   * The caller has already checked that "dataBuf" is non-NULL.
+   */
+  static void check(const char* functionName, const void* dataBuf, bool modOkay) {
+    static const uint32_t kMagicCmp = kGuardMagic;
+    const uint8_t* fullBuf = actualBuffer(dataBuf);
+    const GuardedCopy* pExtra = GuardedCopy::fromData(dataBuf);
+
+    /*
+     * Before we do anything with "pExtra", check the magic number.  We
+     * do the check with memcmp rather than "==" in case the pointer is
+     * unaligned.  If it points to completely bogus memory we're going
+     * to crash, but there's no easy way around that.
+     */
+    if (memcmp(&pExtra->magic, &kMagicCmp, 4) != 0) {
+      uint8_t buf[4];
+      memcpy(buf, &pExtra->magic, 4);
+      LOG(ERROR) << StringPrintf("JNI: guard magic does not match "
+          "(found 0x%02x%02x%02x%02x) -- incorrect data pointer %p?",
+          buf[3], buf[2], buf[1], buf[0], dataBuf); /* assume little endian */
+      JniAbort(functionName);
+    }
+
+    size_t len = pExtra->originalLen;
+
+    /* check bottom half of guard; skip over optional checksum storage */
+    const uint16_t* pat = (uint16_t*) fullBuf;
+    for (size_t i = sizeof(GuardedCopy) / 2; i < (kGuardLen / 2 - sizeof(GuardedCopy)) / 2; i++) {
+      if (pat[i] != kGuardPattern) {
+        LOG(ERROR) << "JNI: guard pattern(1) disturbed at " << (void*) fullBuf << " + " << (i*2);
+        JniAbort(functionName);
+      }
+    }
+
+    int offset = kGuardLen / 2 + len;
+    if (offset & 0x01) {
+      /* odd byte; expected value depends on endian-ness of host */
+      const uint16_t patSample = kGuardPattern;
+      if (fullBuf[offset] != ((const uint8_t*) &patSample)[1]) {
+        LOG(ERROR) << "JNI: guard pattern disturbed in odd byte after "
+                   << (void*) fullBuf << " (+" << offset << ") "
+                   << StringPrintf("0x%02x 0x%02x", fullBuf[offset], ((const uint8_t*) &patSample)[1]);
+        JniAbort(functionName);
+      }
+      offset++;
+    }
+
+    /* check top half of guard */
+    pat = (uint16_t*) (fullBuf + offset);
+    for (size_t i = 0; i < kGuardLen / 4; i++) {
+      if (pat[i] != kGuardPattern) {
+        LOG(ERROR) << "JNI: guard pattern(2) disturbed at " << (void*) fullBuf << " + " << (offset + i*2);
+        JniAbort(functionName);
+      }
+    }
+
+    /*
+     * If modification is not expected, verify checksum.  Strictly speaking
+     * this is wrong: if we told the client that we made a copy, there's no
+     * reason they can't alter the buffer.
+     */
+    if (!modOkay) {
+      uLong adler = adler32(0L, Z_NULL, 0);
+      adler = adler32(adler, (const Bytef*)dataBuf, len);
+      if (pExtra->adler != adler) {
+        LOG(ERROR) << StringPrintf("JNI: buffer modified (0x%08lx vs 0x%08lx) at addr %p", pExtra->adler, adler, dataBuf);
+        JniAbort(functionName);
+      }
+    }
+  }
+
+ private:
+  static uint8_t* debugAlloc(size_t len) {
+    void* result = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0);
+    if (result == MAP_FAILED) {
+      PLOG(FATAL) << "GuardedCopy::create mmap(" << len << ") failed";
+    }
+    return reinterpret_cast<uint8_t*>(result);
+  }
+
+  static void debugFree(void* dataBuf, size_t len) {
+    uint8_t* fullBuf = actualBuffer(dataBuf);
+    size_t totalByteCount = actualLength(len);
+    // TODO: we could mprotect instead, and keep the allocation around for a while.
+    // This would be even more expensive, but it might catch more errors.
+    // if (mprotect(fullBuf, totalByteCount, PROT_NONE) != 0) {
+    //     LOGW("mprotect(PROT_NONE) failed: %s", strerror(errno));
+    // }
+    if (munmap(fullBuf, totalByteCount) != 0) {
+      PLOG(FATAL) << "munmap(" << (void*) fullBuf << ", " << totalByteCount << ") failed";
+    }
+  }
+
+  static const uint8_t* actualBuffer(const void* dataBuf) {
+    return reinterpret_cast<const uint8_t*>(dataBuf) - kGuardLen / 2;
+  }
+
+  static uint8_t* actualBuffer(void* dataBuf) {
+    return reinterpret_cast<uint8_t*>(dataBuf) - kGuardLen / 2;
+  }
+
+  // Underlying length of a user allocation of 'length' bytes.
+  static size_t actualLength(size_t length) {
+    return (length + kGuardLen + 1) & ~0x01;
+  }
+};
+
+/*
+ * Create a guarded copy of a primitive array.  Modifications to the copied
+ * data are allowed.  Returns a pointer to the copied data.
+ */
+void* CreateGuardedPACopy(JNIEnv* env, const jarray java_array, jboolean* isCopy) {
+  ScopedJniThreadState ts(env);
+
+  Array* a = Decode<Array*>(ts, java_array);
+  size_t byte_count = a->GetLength() * a->GetClass()->GetComponentSize();
+  void* result = GuardedCopy::create(reinterpret_cast<ByteArray*>(a)->GetData(), byte_count, true);
+  if (isCopy != NULL) {
+    *isCopy = JNI_TRUE;
+  }
+  return result;
+}
+
+/*
+ * Perform the array "release" operation, which may or may not copy data
+ * back into the VM, and may or may not release the underlying storage.
+ */
+void ReleaseGuardedPACopy(JNIEnv* env, jarray java_array, void* dataBuf, int mode) {
+  if (reinterpret_cast<uintptr_t>(dataBuf) == kNoCopyMagic) {
+    return;
+  }
+
+  ScopedJniThreadState ts(env);
+  Array* a = Decode<Array*>(ts, java_array);
+
+  GuardedCopy::check(__FUNCTION__, dataBuf, true);
+
+  if (mode != JNI_ABORT) {
+    size_t len = GuardedCopy::fromData(dataBuf)->originalLen;
+    memcpy(reinterpret_cast<ByteArray*>(a)->GetData(), dataBuf, len);
+  }
+  if (mode != JNI_COMMIT) {
+    GuardedCopy::destroy(dataBuf);
+  }
+}
+
+/*
+ * ===========================================================================
+ *      JNI functions
+ * ===========================================================================
+ */
+
+class CheckJNI {
+ public:
+  static jint GetVersion(JNIEnv* env) {
+    CHECK_JNI_ENTRY(kFlag_Default, "E", env);
+    return CHECK_JNI_EXIT("I", baseEnv(env)->GetVersion(env));
+  }
+
+  static jclass DefineClass(JNIEnv* env, const char* name, jobject loader, const jbyte* buf, jsize bufLen) {
+    CHECK_JNI_ENTRY(kFlag_Default, "EuLpz", env, name, loader, buf, bufLen);
+    sc.checkClassName(name);
+    return CHECK_JNI_EXIT("c", baseEnv(env)->DefineClass(env, name, loader, buf, bufLen));
+  }
+
+  static jclass FindClass(JNIEnv* env, const char* name) {
+    CHECK_JNI_ENTRY(kFlag_Default, "Eu", env, name);
+    sc.checkClassName(name);
+    return CHECK_JNI_EXIT("c", baseEnv(env)->FindClass(env, name));
+  }
+
+  static jclass GetSuperclass(JNIEnv* env, jclass clazz) {
+    CHECK_JNI_ENTRY(kFlag_Default, "Ec", env, clazz);
+    return CHECK_JNI_EXIT("c", baseEnv(env)->GetSuperclass(env, clazz));
+  }
+
+  static jboolean IsAssignableFrom(JNIEnv* env, jclass clazz1, jclass clazz2) {
+    CHECK_JNI_ENTRY(kFlag_Default, "Ecc", env, clazz1, clazz2);
+    return CHECK_JNI_EXIT("b", baseEnv(env)->IsAssignableFrom(env, clazz1, clazz2));
+  }
+
+  static jmethodID FromReflectedMethod(JNIEnv* env, jobject method) {
+    CHECK_JNI_ENTRY(kFlag_Default, "EL", env, method);
+    // TODO: check that 'field' is a java.lang.reflect.Method.
+    return CHECK_JNI_EXIT("m", baseEnv(env)->FromReflectedMethod(env, method));
+  }
+
+  static jfieldID FromReflectedField(JNIEnv* env, jobject field) {
+    CHECK_JNI_ENTRY(kFlag_Default, "EL", env, field);
+    // TODO: check that 'field' is a java.lang.reflect.Field.
+    return CHECK_JNI_EXIT("f", baseEnv(env)->FromReflectedField(env, field));
+  }
+
+  static jobject ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID mid, jboolean isStatic) {
+    CHECK_JNI_ENTRY(kFlag_Default, "Ecmb", env, cls, mid, isStatic);
+    return CHECK_JNI_EXIT("L", baseEnv(env)->ToReflectedMethod(env, cls, mid, isStatic));
+  }
+
+  static jobject ToReflectedField(JNIEnv* env, jclass cls, jfieldID fid, jboolean isStatic) {
+    CHECK_JNI_ENTRY(kFlag_Default, "Ecfb", env, cls, fid, isStatic);
+    return CHECK_JNI_EXIT("L", baseEnv(env)->ToReflectedField(env, cls, fid, isStatic));
+  }
+
+  static jint Throw(JNIEnv* env, jthrowable obj) {
+    CHECK_JNI_ENTRY(kFlag_Default, "EL", env, obj);
+    // TODO: check that 'obj' is a java.lang.Throwable.
+    return CHECK_JNI_EXIT("I", baseEnv(env)->Throw(env, obj));
+  }
+
+  static jint ThrowNew(JNIEnv* env, jclass clazz, const char* message) {
+    CHECK_JNI_ENTRY(kFlag_NullableUtf, "Ecu", env, clazz, message);
+    return CHECK_JNI_EXIT("I", baseEnv(env)->ThrowNew(env, clazz, message));
+  }
+
+  static jthrowable ExceptionOccurred(JNIEnv* env) {
+    CHECK_JNI_ENTRY(kFlag_ExcepOkay, "E", env);
+    return CHECK_JNI_EXIT("L", baseEnv(env)->ExceptionOccurred(env));
+  }
+
+  static void ExceptionDescribe(JNIEnv* env) {
+    CHECK_JNI_ENTRY(kFlag_ExcepOkay, "E", env);
+    baseEnv(env)->ExceptionDescribe(env);
+    CHECK_JNI_EXIT_VOID();
+  }
+
+  static void ExceptionClear(JNIEnv* env) {
+    CHECK_JNI_ENTRY(kFlag_ExcepOkay, "E", env);
+    baseEnv(env)->ExceptionClear(env);
+    CHECK_JNI_EXIT_VOID();
+  }
+
+  static void FatalError(JNIEnv* env, const char* msg) {
+    CHECK_JNI_ENTRY(kFlag_NullableUtf, "Eu", env, msg);
+    baseEnv(env)->FatalError(env, msg);
+    CHECK_JNI_EXIT_VOID();
+  }
+
+  static jint PushLocalFrame(JNIEnv* env, jint capacity) {
+    CHECK_JNI_ENTRY(kFlag_Default | kFlag_ExcepOkay, "EI", env, capacity);
+    return CHECK_JNI_EXIT("I", baseEnv(env)->PushLocalFrame(env, capacity));
+  }
+
+  static jobject PopLocalFrame(JNIEnv* env, jobject res) {
+    CHECK_JNI_ENTRY(kFlag_Default | kFlag_ExcepOkay, "EL", env, res);
+    return CHECK_JNI_EXIT("L", baseEnv(env)->PopLocalFrame(env, res));
+  }
+
+  static jobject NewGlobalRef(JNIEnv* env, jobject obj) {
+    CHECK_JNI_ENTRY(kFlag_Default, "EL", env, obj);
+    return CHECK_JNI_EXIT("L", baseEnv(env)->NewGlobalRef(env, obj));
+  }
+
+  static jobject NewLocalRef(JNIEnv* env, jobject ref) {
+    CHECK_JNI_ENTRY(kFlag_Default, "EL", env, ref);
+    return CHECK_JNI_EXIT("L", baseEnv(env)->NewLocalRef(env, ref));
+  }
+
+  static void DeleteGlobalRef(JNIEnv* env, jobject globalRef) {
+    CHECK_JNI_ENTRY(kFlag_Default | kFlag_ExcepOkay, "EL", env, globalRef);
+    if (globalRef != NULL && GetIndirectRefKind(globalRef) != kGlobal) {
+      LOG(ERROR) << "JNI ERROR: DeleteGlobalRef on " << GetIndirectRefKind(globalRef) << ": " << globalRef;
+      JniAbort(__FUNCTION__);
+    } else {
+      baseEnv(env)->DeleteGlobalRef(env, globalRef);
+      CHECK_JNI_EXIT_VOID();
+    }
+  }
+
+  static void DeleteWeakGlobalRef(JNIEnv* env, jweak weakGlobalRef) {
+    CHECK_JNI_ENTRY(kFlag_Default | kFlag_ExcepOkay, "EL", env, weakGlobalRef);
+    if (weakGlobalRef != NULL && GetIndirectRefKind(weakGlobalRef) != kWeakGlobal) {
+      LOG(ERROR) << "JNI ERROR: DeleteWeakGlobalRef on " << GetIndirectRefKind(weakGlobalRef) << ": " << weakGlobalRef;
+      JniAbort(__FUNCTION__);
+    } else {
+      baseEnv(env)->DeleteWeakGlobalRef(env, weakGlobalRef);
+      CHECK_JNI_EXIT_VOID();
+    }
+  }
+
+  static void DeleteLocalRef(JNIEnv* env, jobject localRef) {
+    CHECK_JNI_ENTRY(kFlag_Default | kFlag_ExcepOkay, "EL", env, localRef);
+    if (localRef != NULL && GetIndirectRefKind(localRef) != kLocal) {
+      LOG(ERROR) << "JNI ERROR: DeleteLocalRef on " << GetIndirectRefKind(localRef) << ": " << localRef;
+      JniAbort(__FUNCTION__);
+    } else {
+      baseEnv(env)->DeleteLocalRef(env, localRef);
+      CHECK_JNI_EXIT_VOID();
+    }
+  }
+
+  static jint EnsureLocalCapacity(JNIEnv *env, jint capacity) {
+    CHECK_JNI_ENTRY(kFlag_Default, "EI", env, capacity);
+    return CHECK_JNI_EXIT("I", baseEnv(env)->EnsureLocalCapacity(env, capacity));
+  }
+
+  static jboolean IsSameObject(JNIEnv* env, jobject ref1, jobject ref2) {
+    CHECK_JNI_ENTRY(kFlag_Default, "ELL", env, ref1, ref2);
+    return CHECK_JNI_EXIT("b", baseEnv(env)->IsSameObject(env, ref1, ref2));
+  }
+
+  static jobject AllocObject(JNIEnv* env, jclass clazz) {
+    CHECK_JNI_ENTRY(kFlag_Default, "Ec", env, clazz);
+    return CHECK_JNI_EXIT("L", baseEnv(env)->AllocObject(env, clazz));
+  }
+
+  static jobject NewObject(JNIEnv* env, jclass clazz, jmethodID mid, ...) {
+    CHECK_JNI_ENTRY(kFlag_Default, "Ecm.", env, clazz, mid);
+    va_list args;
+    va_start(args, mid);
+    jobject result = baseEnv(env)->NewObjectV(env, clazz, mid, args);
+    va_end(args);
+    return CHECK_JNI_EXIT("L", result);
+  }
+
+  static jobject NewObjectV(JNIEnv* env, jclass clazz, jmethodID mid, va_list args) {
+    CHECK_JNI_ENTRY(kFlag_Default, "Ecm.", env, clazz, mid);
+    return CHECK_JNI_EXIT("L", baseEnv(env)->NewObjectV(env, clazz, mid, args));
+  }
+
+  static jobject NewObjectA(JNIEnv* env, jclass clazz, jmethodID mid, jvalue* args) {
+    CHECK_JNI_ENTRY(kFlag_Default, "Ecm.", env, clazz, mid);
+    return CHECK_JNI_EXIT("L", baseEnv(env)->NewObjectA(env, clazz, mid, args));
+  }
+
+  static jclass GetObjectClass(JNIEnv* env, jobject obj) {
+    CHECK_JNI_ENTRY(kFlag_Default, "EL", env, obj);
+    return CHECK_JNI_EXIT("c", baseEnv(env)->GetObjectClass(env, obj));
+  }
+
+  static jboolean IsInstanceOf(JNIEnv* env, jobject obj, jclass clazz) {
+    CHECK_JNI_ENTRY(kFlag_Default, "ELc", env, obj, clazz);
+    return CHECK_JNI_EXIT("b", baseEnv(env)->IsInstanceOf(env, obj, clazz));
+  }
+
+  static jmethodID GetMethodID(JNIEnv* env, jclass clazz, const char* name, const char* sig) {
+    CHECK_JNI_ENTRY(kFlag_Default, "Ecuu", env, clazz, name, sig);
+    return CHECK_JNI_EXIT("m", baseEnv(env)->GetMethodID(env, clazz, name, sig));
+  }
+
+  static jfieldID GetFieldID(JNIEnv* env, jclass clazz, const char* name, const char* sig) {
+    CHECK_JNI_ENTRY(kFlag_Default, "Ecuu", env, clazz, name, sig);
+    return CHECK_JNI_EXIT("f", baseEnv(env)->GetFieldID(env, clazz, name, sig));
+  }
+
+  static jmethodID GetStaticMethodID(JNIEnv* env, jclass clazz, const char* name, const char* sig) {
+    CHECK_JNI_ENTRY(kFlag_Default, "Ecuu", env, clazz, name, sig);
+    return CHECK_JNI_EXIT("m", baseEnv(env)->GetStaticMethodID(env, clazz, name, sig));
+  }
+
+  static jfieldID GetStaticFieldID(JNIEnv* env, jclass clazz, const char* name, const char* sig) {
+    CHECK_JNI_ENTRY(kFlag_Default, "Ecuu", env, clazz, name, sig);
+    return CHECK_JNI_EXIT("f", baseEnv(env)->GetStaticFieldID(env, clazz, name, sig));
+  }
+
+#define FIELD_ACCESSORS(_ctype, _jname, _type) \
+    static _ctype GetStatic##_jname##Field(JNIEnv* env, jclass clazz, jfieldID fid) { \
+        CHECK_JNI_ENTRY(kFlag_Default, "Ecf", env, clazz, fid); \
+        sc.checkStaticFieldID(clazz, fid); \
+        return CHECK_JNI_EXIT(_type, baseEnv(env)->GetStatic##_jname##Field(env, clazz, fid)); \
+    } \
+    static _ctype Get##_jname##Field(JNIEnv* env, jobject obj, jfieldID fid) { \
+        CHECK_JNI_ENTRY(kFlag_Default, "ELf", env, obj, fid); \
+        sc.checkInstanceFieldID(obj, fid); \
+        return CHECK_JNI_EXIT(_type, baseEnv(env)->Get##_jname##Field(env, obj, fid)); \
+    } \
+    static void SetStatic##_jname##Field(JNIEnv* env, jclass clazz, jfieldID fid, _ctype value) { \
+        CHECK_JNI_ENTRY(kFlag_Default, "Ecf" _type, env, clazz, fid, value); \
+        sc.checkStaticFieldID(clazz, fid); \
+        /* "value" arg only used when type == ref */ \
+        sc.checkFieldType((jobject)(uint32_t)value, fid, _type[0], true); \
+        baseEnv(env)->SetStatic##_jname##Field(env, clazz, fid, value); \
+        CHECK_JNI_EXIT_VOID(); \
+    } \
+    static void Set##_jname##Field(JNIEnv* env, jobject obj, jfieldID fid, _ctype value) { \
+        CHECK_JNI_ENTRY(kFlag_Default, "ELf" _type, env, obj, fid, value); \
+        sc.checkInstanceFieldID(obj, fid); \
+        /* "value" arg only used when type == ref */ \
+        sc.checkFieldType((jobject)(uint32_t) value, fid, _type[0], false); \
+        baseEnv(env)->Set##_jname##Field(env, obj, fid, value); \
+        CHECK_JNI_EXIT_VOID(); \
+    }
+
+FIELD_ACCESSORS(jobject, Object, "L");
+FIELD_ACCESSORS(jboolean, Boolean, "Z");
+FIELD_ACCESSORS(jbyte, Byte, "B");
+FIELD_ACCESSORS(jchar, Char, "C");
+FIELD_ACCESSORS(jshort, Short, "S");
+FIELD_ACCESSORS(jint, Int, "I");
+FIELD_ACCESSORS(jlong, Long, "J");
+FIELD_ACCESSORS(jfloat, Float, "F");
+FIELD_ACCESSORS(jdouble, Double, "D");
+
+#define CALL(_ctype, _jname, _retdecl, _retasgn, _retok, _retsig) \
+    /* Virtual... */ \
+    static _ctype Call##_jname##Method(JNIEnv* env, jobject obj, \
+        jmethodID mid, ...) \
+    { \
+        CHECK_JNI_ENTRY(kFlag_Default, "ELm.", env, obj, mid); /* TODO: args! */ \
+        sc.checkSig(mid, _retsig, false); \
+        sc.checkVirtualMethod(obj, mid); \
+        _retdecl; \
+        va_list args; \
+        va_start(args, mid); \
+        _retasgn baseEnv(env)->Call##_jname##MethodV(env, obj, mid, args); \
+        va_end(args); \
+        _retok; \
+    } \
+    static _ctype Call##_jname##MethodV(JNIEnv* env, jobject obj, \
+        jmethodID mid, va_list args) \
+    { \
+        CHECK_JNI_ENTRY(kFlag_Default, "ELm.", env, obj, mid); /* TODO: args! */ \
+        sc.checkSig(mid, _retsig, false); \
+        sc.checkVirtualMethod(obj, mid); \
+        _retdecl; \
+        _retasgn baseEnv(env)->Call##_jname##MethodV(env, obj, mid, args); \
+        _retok; \
+    } \
+    static _ctype Call##_jname##MethodA(JNIEnv* env, jobject obj, \
+        jmethodID mid, jvalue* args) \
+    { \
+        CHECK_JNI_ENTRY(kFlag_Default, "ELm.", env, obj, mid); /* TODO: args! */ \
+        sc.checkSig(mid, _retsig, false); \
+        sc.checkVirtualMethod(obj, mid); \
+        _retdecl; \
+        _retasgn baseEnv(env)->Call##_jname##MethodA(env, obj, mid, args); \
+        _retok; \
+    } \
+    /* Non-virtual... */ \
+    static _ctype CallNonvirtual##_jname##Method(JNIEnv* env, \
+        jobject obj, jclass clazz, jmethodID mid, ...) \
+    { \
+        CHECK_JNI_ENTRY(kFlag_Default, "ELcm.", env, obj, clazz, mid); /* TODO: args! */ \
+        sc.checkSig(mid, _retsig, false); \
+        sc.checkVirtualMethod(obj, mid); \
+        _retdecl; \
+        va_list args; \
+        va_start(args, mid); \
+        _retasgn baseEnv(env)->CallNonvirtual##_jname##MethodV(env, obj, clazz, mid, args); \
+        va_end(args); \
+        _retok; \
+    } \
+    static _ctype CallNonvirtual##_jname##MethodV(JNIEnv* env, \
+        jobject obj, jclass clazz, jmethodID mid, va_list args) \
+    { \
+        CHECK_JNI_ENTRY(kFlag_Default, "ELcm.", env, obj, clazz, mid); /* TODO: args! */ \
+        sc.checkSig(mid, _retsig, false); \
+        sc.checkVirtualMethod(obj, mid); \
+        _retdecl; \
+        _retasgn baseEnv(env)->CallNonvirtual##_jname##MethodV(env, obj, clazz, mid, args); \
+        _retok; \
+    } \
+    static _ctype CallNonvirtual##_jname##MethodA(JNIEnv* env, \
+        jobject obj, jclass clazz, jmethodID mid, jvalue* args) \
+    { \
+        CHECK_JNI_ENTRY(kFlag_Default, "ELcm.", env, obj, clazz, mid); /* TODO: args! */ \
+        sc.checkSig(mid, _retsig, false); \
+        sc.checkVirtualMethod(obj, mid); \
+        _retdecl; \
+        _retasgn baseEnv(env)->CallNonvirtual##_jname##MethodA(env, obj, clazz, mid, args); \
+        _retok; \
+    } \
+    /* Static... */ \
+    static _ctype CallStatic##_jname##Method(JNIEnv* env, \
+        jclass clazz, jmethodID mid, ...) \
+    { \
+        CHECK_JNI_ENTRY(kFlag_Default, "Ecm.", env, clazz, mid); /* TODO: args! */ \
+        sc.checkSig(mid, _retsig, true); \
+        sc.checkStaticMethod(clazz, mid); \
+        _retdecl; \
+        va_list args; \
+        va_start(args, mid); \
+        _retasgn baseEnv(env)->CallStatic##_jname##MethodV(env, clazz, mid, args); \
+        va_end(args); \
+        _retok; \
+    } \
+    static _ctype CallStatic##_jname##MethodV(JNIEnv* env, \
+        jclass clazz, jmethodID mid, va_list args) \
+    { \
+        CHECK_JNI_ENTRY(kFlag_Default, "Ecm.", env, clazz, mid); /* TODO: args! */ \
+        sc.checkSig(mid, _retsig, true); \
+        sc.checkStaticMethod(clazz, mid); \
+        _retdecl; \
+        _retasgn baseEnv(env)->CallStatic##_jname##MethodV(env, clazz, mid, args); \
+        _retok; \
+    } \
+    static _ctype CallStatic##_jname##MethodA(JNIEnv* env, \
+        jclass clazz, jmethodID mid, jvalue* args) \
+    { \
+        CHECK_JNI_ENTRY(kFlag_Default, "Ecm.", env, clazz, mid); /* TODO: args! */ \
+        sc.checkSig(mid, _retsig, true); \
+        sc.checkStaticMethod(clazz, mid); \
+        _retdecl; \
+        _retasgn baseEnv(env)->CallStatic##_jname##MethodA(env, clazz, mid, args); \
+        _retok; \
+    }
+
+#define NON_VOID_RETURN(_retsig, _ctype) return CHECK_JNI_EXIT(_retsig, (_ctype) result)
+#define VOID_RETURN CHECK_JNI_EXIT_VOID()
+
+CALL(jobject, Object, Object* result, result=(Object*), NON_VOID_RETURN("L", jobject), "L");
+CALL(jboolean, Boolean, jboolean result, result=, NON_VOID_RETURN("Z", jboolean), "Z");
+CALL(jbyte, Byte, jbyte result, result=, NON_VOID_RETURN("B", jbyte), "B");
+CALL(jchar, Char, jchar result, result=, NON_VOID_RETURN("C", jchar), "C");
+CALL(jshort, Short, jshort result, result=, NON_VOID_RETURN("S", jshort), "S");
+CALL(jint, Int, jint result, result=, NON_VOID_RETURN("I", jint), "I");
+CALL(jlong, Long, jlong result, result=, NON_VOID_RETURN("J", jlong), "J");
+CALL(jfloat, Float, jfloat result, result=, NON_VOID_RETURN("F", jfloat), "F");
+CALL(jdouble, Double, jdouble result, result=, NON_VOID_RETURN("D", jdouble), "D");
+CALL(void, Void, , , VOID_RETURN, "V");
+
+  static jstring NewString(JNIEnv* env, const jchar* unicodeChars, jsize len) {
+    CHECK_JNI_ENTRY(kFlag_Default, "Epz", env, unicodeChars, len);
+    return CHECK_JNI_EXIT("s", baseEnv(env)->NewString(env, unicodeChars, len));
+  }
+
+  static jsize GetStringLength(JNIEnv* env, jstring string) {
+    CHECK_JNI_ENTRY(kFlag_CritOkay, "Es", env, string);
+    return CHECK_JNI_EXIT("I", baseEnv(env)->GetStringLength(env, string));
+  }
+
+  static const jchar* GetStringChars(JNIEnv* env, jstring java_string, jboolean* isCopy) {
+    CHECK_JNI_ENTRY(kFlag_CritOkay, "Esp", env, java_string, isCopy);
+    const jchar* result = baseEnv(env)->GetStringChars(env, java_string, isCopy);
+    if (sc.forceCopy() && result != NULL) {
+      ScopedJniThreadState ts(env);
+      String* s = Decode<String*>(ts, java_string);
+      int byteCount = s->GetLength() * 2;
+      result = (const jchar*) GuardedCopy::create(result, byteCount, false);
+      if (isCopy != NULL) {
+        *isCopy = JNI_TRUE;
+      }
+    }
+    return CHECK_JNI_EXIT("p", result);
+  }
+
+  static void ReleaseStringChars(JNIEnv* env, jstring string, const jchar* chars) {
+    CHECK_JNI_ENTRY(kFlag_Default | kFlag_ExcepOkay, "Esp", env, string, chars);
+    sc.checkNonNull(chars);
+    if (sc.forceCopy()) {
+      GuardedCopy::check(__FUNCTION__, chars, false);
+      chars = (const jchar*) GuardedCopy::destroy((jchar*)chars);
+    }
+    baseEnv(env)->ReleaseStringChars(env, string, chars);
+    CHECK_JNI_EXIT_VOID();
+  }
+
+  static jstring NewStringUTF(JNIEnv* env, const char* bytes) {
+    CHECK_JNI_ENTRY(kFlag_NullableUtf, "Eu", env, bytes); // TODO: show pointer and truncate string.
+    return CHECK_JNI_EXIT("s", baseEnv(env)->NewStringUTF(env, bytes));
+  }
+
+  static jsize GetStringUTFLength(JNIEnv* env, jstring string) {
+    CHECK_JNI_ENTRY(kFlag_CritOkay, "Es", env, string);
+    return CHECK_JNI_EXIT("I", baseEnv(env)->GetStringUTFLength(env, string));
+  }
+
+  static const char* GetStringUTFChars(JNIEnv* env, jstring string, jboolean* isCopy) {
+    CHECK_JNI_ENTRY(kFlag_CritOkay, "Esp", env, string, isCopy);
+    const char* result = baseEnv(env)->GetStringUTFChars(env, string, isCopy);
+    if (sc.forceCopy() && result != NULL) {
+      result = (const char*) GuardedCopy::create(result, strlen(result) + 1, false);
+      if (isCopy != NULL) {
+        *isCopy = JNI_TRUE;
+      }
+    }
+    return CHECK_JNI_EXIT("u", result); // TODO: show pointer and truncate string.
+  }
+
+  static void ReleaseStringUTFChars(JNIEnv* env, jstring string, const char* utf) {
+    CHECK_JNI_ENTRY(kFlag_ExcepOkay | kFlag_Release, "Esu", env, string, utf); // TODO: show pointer and truncate string.
+    if (sc.forceCopy()) {
+      GuardedCopy::check(__FUNCTION__, utf, false);
+      utf = (const char*) GuardedCopy::destroy((char*)utf);
+    }
+    baseEnv(env)->ReleaseStringUTFChars(env, string, utf);
+    CHECK_JNI_EXIT_VOID();
+  }
+
+  static jsize GetArrayLength(JNIEnv* env, jarray array) {
+    CHECK_JNI_ENTRY(kFlag_CritOkay, "Ea", env, array);
+    return CHECK_JNI_EXIT("I", baseEnv(env)->GetArrayLength(env, array));
+  }
+
+  static jobjectArray NewObjectArray(JNIEnv* env, jsize length, jclass elementClass, jobject initialElement) {
+    CHECK_JNI_ENTRY(kFlag_Default, "EzcL", env, length, elementClass, initialElement);
+    return CHECK_JNI_EXIT("a", baseEnv(env)->NewObjectArray(env, length, elementClass, initialElement));
+  }
+
+  static jobject GetObjectArrayElement(JNIEnv* env, jobjectArray array, jsize index) {
+    CHECK_JNI_ENTRY(kFlag_Default, "EaI", env, array, index);
+    return CHECK_JNI_EXIT("L", baseEnv(env)->GetObjectArrayElement(env, array, index));
+  }
+
+  static void SetObjectArrayElement(JNIEnv* env, jobjectArray array, jsize index, jobject value) {
+    CHECK_JNI_ENTRY(kFlag_Default, "EaIL", env, array, index, value);
+    baseEnv(env)->SetObjectArrayElement(env, array, index, value);
+    CHECK_JNI_EXIT_VOID();
+  }
+
+#define NEW_PRIMITIVE_ARRAY(_artype, _jname) \
+    static _artype New##_jname##Array(JNIEnv* env, jsize length) { \
+        CHECK_JNI_ENTRY(kFlag_Default, "Ez", env, length); \
+        return CHECK_JNI_EXIT("a", baseEnv(env)->New##_jname##Array(env, length)); \
+    }
+NEW_PRIMITIVE_ARRAY(jbooleanArray, Boolean);
+NEW_PRIMITIVE_ARRAY(jbyteArray, Byte);
+NEW_PRIMITIVE_ARRAY(jcharArray, Char);
+NEW_PRIMITIVE_ARRAY(jshortArray, Short);
+NEW_PRIMITIVE_ARRAY(jintArray, Int);
+NEW_PRIMITIVE_ARRAY(jlongArray, Long);
+NEW_PRIMITIVE_ARRAY(jfloatArray, Float);
+NEW_PRIMITIVE_ARRAY(jdoubleArray, Double);
+
+class ForceCopyGetChecker {
+public:
+  ForceCopyGetChecker(ScopedCheck& sc, jboolean* isCopy) {
+    forceCopy = sc.forceCopy();
+    noCopy = 0;
+    if (forceCopy && isCopy != NULL) {
+      /* capture this before the base call tramples on it */
+      noCopy = *(uint32_t*) isCopy;
+    }
+  }
+
+  template<typename ResultT>
+  ResultT check(JNIEnv* env, jarray array, jboolean* isCopy, ResultT result) {
+    if (forceCopy && result != NULL) {
+      if (noCopy != kNoCopyMagic) {
+        result = reinterpret_cast<ResultT>(CreateGuardedPACopy(env, array, isCopy));
+      }
+    }
+    return result;
+  }
+
+  uint32_t noCopy;
+  bool forceCopy;
+};
+
+#define GET_PRIMITIVE_ARRAY_ELEMENTS(_ctype, _jname) \
+  static _ctype* Get##_jname##ArrayElements(JNIEnv* env, _ctype##Array array, jboolean* isCopy) { \
+    CHECK_JNI_ENTRY(kFlag_Default, "Eap", env, array, isCopy); \
+    _ctype* result = ForceCopyGetChecker(sc, isCopy).check(env, array, isCopy, baseEnv(env)->Get##_jname##ArrayElements(env, array, isCopy)); \
+    return CHECK_JNI_EXIT("p", result); \
+  }
+
+#define RELEASE_PRIMITIVE_ARRAY_ELEMENTS(_ctype, _jname) \
+  static void Release##_jname##ArrayElements(JNIEnv* env, _ctype##Array array, _ctype* elems, jint mode) { \
+    CHECK_JNI_ENTRY(kFlag_Default | kFlag_ExcepOkay, "Eapr", env, array, elems, mode); \
+    sc.checkNonNull(elems); \
+    if (sc.forceCopy()) { \
+      ReleaseGuardedPACopy(env, array, elems, mode); \
+    } \
+    baseEnv(env)->Release##_jname##ArrayElements(env, array, elems, mode); \
+    CHECK_JNI_EXIT_VOID(); \
+  }
+
+#define GET_PRIMITIVE_ARRAY_REGION(_ctype, _jname) \
+    static void Get##_jname##ArrayRegion(JNIEnv* env, _ctype##Array array, jsize start, jsize len, _ctype* buf) { \
+        CHECK_JNI_ENTRY(kFlag_Default, "EaIIp", env, array, start, len, buf); \
+        baseEnv(env)->Get##_jname##ArrayRegion(env, array, start, len, buf); \
+        CHECK_JNI_EXIT_VOID(); \
+    }
+
+#define SET_PRIMITIVE_ARRAY_REGION(_ctype, _jname) \
+    static void Set##_jname##ArrayRegion(JNIEnv* env, _ctype##Array array, jsize start, jsize len, const _ctype* buf) { \
+        CHECK_JNI_ENTRY(kFlag_Default, "EaIIp", env, array, start, len, buf); \
+        baseEnv(env)->Set##_jname##ArrayRegion(env, array, start, len, buf); \
+        CHECK_JNI_EXIT_VOID(); \
+    }
+
+#define PRIMITIVE_ARRAY_FUNCTIONS(_ctype, _jname, _typechar) \
+    GET_PRIMITIVE_ARRAY_ELEMENTS(_ctype, _jname); \
+    RELEASE_PRIMITIVE_ARRAY_ELEMENTS(_ctype, _jname); \
+    GET_PRIMITIVE_ARRAY_REGION(_ctype, _jname); \
+    SET_PRIMITIVE_ARRAY_REGION(_ctype, _jname);
+
+/* TODO: verify primitive array type matches call type */
+PRIMITIVE_ARRAY_FUNCTIONS(jboolean, Boolean, 'Z');
+PRIMITIVE_ARRAY_FUNCTIONS(jbyte, Byte, 'B');
+PRIMITIVE_ARRAY_FUNCTIONS(jchar, Char, 'C');
+PRIMITIVE_ARRAY_FUNCTIONS(jshort, Short, 'S');
+PRIMITIVE_ARRAY_FUNCTIONS(jint, Int, 'I');
+PRIMITIVE_ARRAY_FUNCTIONS(jlong, Long, 'J');
+PRIMITIVE_ARRAY_FUNCTIONS(jfloat, Float, 'F');
+PRIMITIVE_ARRAY_FUNCTIONS(jdouble, Double, 'D');
+
+  static jint RegisterNatives(JNIEnv* env, jclass clazz, const JNINativeMethod* methods, jint nMethods) {
+    CHECK_JNI_ENTRY(kFlag_Default, "EcpI", env, clazz, methods, nMethods);
+    return CHECK_JNI_EXIT("I", baseEnv(env)->RegisterNatives(env, clazz, methods, nMethods));
+  }
+
+  static jint UnregisterNatives(JNIEnv* env, jclass clazz) {
+    CHECK_JNI_ENTRY(kFlag_Default, "Ec", env, clazz);
+    return CHECK_JNI_EXIT("I", baseEnv(env)->UnregisterNatives(env, clazz));
+  }
+
+  static jint MonitorEnter(JNIEnv* env, jobject obj) {
+    CHECK_JNI_ENTRY(kFlag_Default, "EL", env, obj);
+    return CHECK_JNI_EXIT("I", baseEnv(env)->MonitorEnter(env, obj));
+  }
+
+  static jint MonitorExit(JNIEnv* env, jobject obj) {
+    CHECK_JNI_ENTRY(kFlag_Default | kFlag_ExcepOkay, "EL", env, obj);
+    return CHECK_JNI_EXIT("I", baseEnv(env)->MonitorExit(env, obj));
+  }
+
+  static jint GetJavaVM(JNIEnv *env, JavaVM **vm) {
+    CHECK_JNI_ENTRY(kFlag_Default, "Ep", env, vm);
+    return CHECK_JNI_EXIT("I", baseEnv(env)->GetJavaVM(env, vm));
+  }
+
+  static void GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len, jchar* buf) {
+    CHECK_JNI_ENTRY(kFlag_CritOkay, "EsIIp", env, str, start, len, buf);
+    baseEnv(env)->GetStringRegion(env, str, start, len, buf);
+    CHECK_JNI_EXIT_VOID();
+  }
+
+  static void GetStringUTFRegion(JNIEnv* env, jstring str, jsize start, jsize len, char* buf) {
+    CHECK_JNI_ENTRY(kFlag_CritOkay, "EsIIp", env, str, start, len, buf);
+    baseEnv(env)->GetStringUTFRegion(env, str, start, len, buf);
+    CHECK_JNI_EXIT_VOID();
+  }
+
+  static void* GetPrimitiveArrayCritical(JNIEnv* env, jarray array, jboolean* isCopy) {
+    CHECK_JNI_ENTRY(kFlag_CritGet, "Eap", env, array, isCopy);
+    void* result = baseEnv(env)->GetPrimitiveArrayCritical(env, array, isCopy);
+    if (sc.forceCopy() && result != NULL) {
+      result = CreateGuardedPACopy(env, array, isCopy);
+    }
+    return CHECK_JNI_EXIT("p", result);
+  }
+
+  static void ReleasePrimitiveArrayCritical(JNIEnv* env, jarray array, void* carray, jint mode) {
+    CHECK_JNI_ENTRY(kFlag_CritRelease | kFlag_ExcepOkay, "Eapr", env, array, carray, mode);
+    sc.checkNonNull(carray);
+    if (sc.forceCopy()) {
+      ReleaseGuardedPACopy(env, array, carray, mode);
+    }
+    baseEnv(env)->ReleasePrimitiveArrayCritical(env, array, carray, mode);
+    CHECK_JNI_EXIT_VOID();
+  }
+
+  static const jchar* GetStringCritical(JNIEnv* env, jstring java_string, jboolean* isCopy) {
+    CHECK_JNI_ENTRY(kFlag_CritGet, "Esp", env, java_string, isCopy);
+    const jchar* result = baseEnv(env)->GetStringCritical(env, java_string, isCopy);
+    if (sc.forceCopy() && result != NULL) {
+      ScopedJniThreadState ts(env);
+      String* s = Decode<String*>(ts, java_string);
+      int byteCount = s->GetLength() * 2;
+      result = (const jchar*) GuardedCopy::create(result, byteCount, false);
+      if (isCopy != NULL) {
+        *isCopy = JNI_TRUE;
+      }
+    }
+    return CHECK_JNI_EXIT("p", result);
+  }
+
+  static void ReleaseStringCritical(JNIEnv* env, jstring string, const jchar* carray) {
+    CHECK_JNI_ENTRY(kFlag_CritRelease | kFlag_ExcepOkay, "Esp", env, string, carray);
+    sc.checkNonNull(carray);
+    if (sc.forceCopy()) {
+      GuardedCopy::check(__FUNCTION__, carray, false);
+      carray = (const jchar*) GuardedCopy::destroy((jchar*)carray);
+    }
+    baseEnv(env)->ReleaseStringCritical(env, string, carray);
+    CHECK_JNI_EXIT_VOID();
+  }
+
+  static jweak NewWeakGlobalRef(JNIEnv* env, jobject obj) {
+    CHECK_JNI_ENTRY(kFlag_Default, "EL", env, obj);
+    return CHECK_JNI_EXIT("L", baseEnv(env)->NewWeakGlobalRef(env, obj));
+  }
+
+  static jboolean ExceptionCheck(JNIEnv* env) {
+    CHECK_JNI_ENTRY(kFlag_CritOkay | kFlag_ExcepOkay, "E", env);
+    return CHECK_JNI_EXIT("b", baseEnv(env)->ExceptionCheck(env));
+  }
+
+  static jobjectRefType GetObjectRefType(JNIEnv* env, jobject obj) {
+    // Note: we use "Ep" rather than "EL" because this is the one JNI function
+    // that it's okay to pass an invalid reference to.
+    CHECK_JNI_ENTRY(kFlag_Default, "Ep", env, obj);
+    // TODO: proper decoding of jobjectRefType!
+    return CHECK_JNI_EXIT("I", baseEnv(env)->GetObjectRefType(env, obj));
+  }
+
+  static jobject NewDirectByteBuffer(JNIEnv* env, void* address, jlong capacity) {
+    CHECK_JNI_ENTRY(kFlag_Default, "EpJ", env, address, capacity);
+    if (address == NULL) {
+      LOG(ERROR) << "JNI ERROR: non-nullable address is NULL";
+      JniAbort(__FUNCTION__);
+    }
+    if (capacity <= 0) {
+      LOG(ERROR) << "JNI ERROR: capacity must be greater than 0: " << capacity;
+      JniAbort(__FUNCTION__);
+    }
+    return CHECK_JNI_EXIT("L", baseEnv(env)->NewDirectByteBuffer(env, address, capacity));
+  }
+
+  static void* GetDirectBufferAddress(JNIEnv* env, jobject buf) {
+    CHECK_JNI_ENTRY(kFlag_Default, "EL", env, buf);
+    // TODO: check that 'buf' is a java.nio.Buffer.
+    return CHECK_JNI_EXIT("p", baseEnv(env)->GetDirectBufferAddress(env, buf));
+  }
+
+  static jlong GetDirectBufferCapacity(JNIEnv* env, jobject buf) {
+    CHECK_JNI_ENTRY(kFlag_Default, "EL", env, buf);
+    // TODO: check that 'buf' is a java.nio.Buffer.
+    return CHECK_JNI_EXIT("J", baseEnv(env)->GetDirectBufferCapacity(env, buf));
+  }
+
+ private:
+  static inline const JNINativeInterface* baseEnv(JNIEnv* env) {
+    return reinterpret_cast<JNIEnvExt*>(env)->unchecked_functions;
+  }
+};
+
+const JNINativeInterface gCheckNativeInterface = {
+  NULL,  // reserved0.
+  NULL,  // reserved1.
+  NULL,  // reserved2.
+  NULL,  // reserved3.
+  CheckJNI::GetVersion,
+  CheckJNI::DefineClass,
+  CheckJNI::FindClass,
+  CheckJNI::FromReflectedMethod,
+  CheckJNI::FromReflectedField,
+  CheckJNI::ToReflectedMethod,
+  CheckJNI::GetSuperclass,
+  CheckJNI::IsAssignableFrom,
+  CheckJNI::ToReflectedField,
+  CheckJNI::Throw,
+  CheckJNI::ThrowNew,
+  CheckJNI::ExceptionOccurred,
+  CheckJNI::ExceptionDescribe,
+  CheckJNI::ExceptionClear,
+  CheckJNI::FatalError,
+  CheckJNI::PushLocalFrame,
+  CheckJNI::PopLocalFrame,
+  CheckJNI::NewGlobalRef,
+  CheckJNI::DeleteGlobalRef,
+  CheckJNI::DeleteLocalRef,
+  CheckJNI::IsSameObject,
+  CheckJNI::NewLocalRef,
+  CheckJNI::EnsureLocalCapacity,
+  CheckJNI::AllocObject,
+  CheckJNI::NewObject,
+  CheckJNI::NewObjectV,
+  CheckJNI::NewObjectA,
+  CheckJNI::GetObjectClass,
+  CheckJNI::IsInstanceOf,
+  CheckJNI::GetMethodID,
+  CheckJNI::CallObjectMethod,
+  CheckJNI::CallObjectMethodV,
+  CheckJNI::CallObjectMethodA,
+  CheckJNI::CallBooleanMethod,
+  CheckJNI::CallBooleanMethodV,
+  CheckJNI::CallBooleanMethodA,
+  CheckJNI::CallByteMethod,
+  CheckJNI::CallByteMethodV,
+  CheckJNI::CallByteMethodA,
+  CheckJNI::CallCharMethod,
+  CheckJNI::CallCharMethodV,
+  CheckJNI::CallCharMethodA,
+  CheckJNI::CallShortMethod,
+  CheckJNI::CallShortMethodV,
+  CheckJNI::CallShortMethodA,
+  CheckJNI::CallIntMethod,
+  CheckJNI::CallIntMethodV,
+  CheckJNI::CallIntMethodA,
+  CheckJNI::CallLongMethod,
+  CheckJNI::CallLongMethodV,
+  CheckJNI::CallLongMethodA,
+  CheckJNI::CallFloatMethod,
+  CheckJNI::CallFloatMethodV,
+  CheckJNI::CallFloatMethodA,
+  CheckJNI::CallDoubleMethod,
+  CheckJNI::CallDoubleMethodV,
+  CheckJNI::CallDoubleMethodA,
+  CheckJNI::CallVoidMethod,
+  CheckJNI::CallVoidMethodV,
+  CheckJNI::CallVoidMethodA,
+  CheckJNI::CallNonvirtualObjectMethod,
+  CheckJNI::CallNonvirtualObjectMethodV,
+  CheckJNI::CallNonvirtualObjectMethodA,
+  CheckJNI::CallNonvirtualBooleanMethod,
+  CheckJNI::CallNonvirtualBooleanMethodV,
+  CheckJNI::CallNonvirtualBooleanMethodA,
+  CheckJNI::CallNonvirtualByteMethod,
+  CheckJNI::CallNonvirtualByteMethodV,
+  CheckJNI::CallNonvirtualByteMethodA,
+  CheckJNI::CallNonvirtualCharMethod,
+  CheckJNI::CallNonvirtualCharMethodV,
+  CheckJNI::CallNonvirtualCharMethodA,
+  CheckJNI::CallNonvirtualShortMethod,
+  CheckJNI::CallNonvirtualShortMethodV,
+  CheckJNI::CallNonvirtualShortMethodA,
+  CheckJNI::CallNonvirtualIntMethod,
+  CheckJNI::CallNonvirtualIntMethodV,
+  CheckJNI::CallNonvirtualIntMethodA,
+  CheckJNI::CallNonvirtualLongMethod,
+  CheckJNI::CallNonvirtualLongMethodV,
+  CheckJNI::CallNonvirtualLongMethodA,
+  CheckJNI::CallNonvirtualFloatMethod,
+  CheckJNI::CallNonvirtualFloatMethodV,
+  CheckJNI::CallNonvirtualFloatMethodA,
+  CheckJNI::CallNonvirtualDoubleMethod,
+  CheckJNI::CallNonvirtualDoubleMethodV,
+  CheckJNI::CallNonvirtualDoubleMethodA,
+  CheckJNI::CallNonvirtualVoidMethod,
+  CheckJNI::CallNonvirtualVoidMethodV,
+  CheckJNI::CallNonvirtualVoidMethodA,
+  CheckJNI::GetFieldID,
+  CheckJNI::GetObjectField,
+  CheckJNI::GetBooleanField,
+  CheckJNI::GetByteField,
+  CheckJNI::GetCharField,
+  CheckJNI::GetShortField,
+  CheckJNI::GetIntField,
+  CheckJNI::GetLongField,
+  CheckJNI::GetFloatField,
+  CheckJNI::GetDoubleField,
+  CheckJNI::SetObjectField,
+  CheckJNI::SetBooleanField,
+  CheckJNI::SetByteField,
+  CheckJNI::SetCharField,
+  CheckJNI::SetShortField,
+  CheckJNI::SetIntField,
+  CheckJNI::SetLongField,
+  CheckJNI::SetFloatField,
+  CheckJNI::SetDoubleField,
+  CheckJNI::GetStaticMethodID,
+  CheckJNI::CallStaticObjectMethod,
+  CheckJNI::CallStaticObjectMethodV,
+  CheckJNI::CallStaticObjectMethodA,
+  CheckJNI::CallStaticBooleanMethod,
+  CheckJNI::CallStaticBooleanMethodV,
+  CheckJNI::CallStaticBooleanMethodA,
+  CheckJNI::CallStaticByteMethod,
+  CheckJNI::CallStaticByteMethodV,
+  CheckJNI::CallStaticByteMethodA,
+  CheckJNI::CallStaticCharMethod,
+  CheckJNI::CallStaticCharMethodV,
+  CheckJNI::CallStaticCharMethodA,
+  CheckJNI::CallStaticShortMethod,
+  CheckJNI::CallStaticShortMethodV,
+  CheckJNI::CallStaticShortMethodA,
+  CheckJNI::CallStaticIntMethod,
+  CheckJNI::CallStaticIntMethodV,
+  CheckJNI::CallStaticIntMethodA,
+  CheckJNI::CallStaticLongMethod,
+  CheckJNI::CallStaticLongMethodV,
+  CheckJNI::CallStaticLongMethodA,
+  CheckJNI::CallStaticFloatMethod,
+  CheckJNI::CallStaticFloatMethodV,
+  CheckJNI::CallStaticFloatMethodA,
+  CheckJNI::CallStaticDoubleMethod,
+  CheckJNI::CallStaticDoubleMethodV,
+  CheckJNI::CallStaticDoubleMethodA,
+  CheckJNI::CallStaticVoidMethod,
+  CheckJNI::CallStaticVoidMethodV,
+  CheckJNI::CallStaticVoidMethodA,
+  CheckJNI::GetStaticFieldID,
+  CheckJNI::GetStaticObjectField,
+  CheckJNI::GetStaticBooleanField,
+  CheckJNI::GetStaticByteField,
+  CheckJNI::GetStaticCharField,
+  CheckJNI::GetStaticShortField,
+  CheckJNI::GetStaticIntField,
+  CheckJNI::GetStaticLongField,
+  CheckJNI::GetStaticFloatField,
+  CheckJNI::GetStaticDoubleField,
+  CheckJNI::SetStaticObjectField,
+  CheckJNI::SetStaticBooleanField,
+  CheckJNI::SetStaticByteField,
+  CheckJNI::SetStaticCharField,
+  CheckJNI::SetStaticShortField,
+  CheckJNI::SetStaticIntField,
+  CheckJNI::SetStaticLongField,
+  CheckJNI::SetStaticFloatField,
+  CheckJNI::SetStaticDoubleField,
+  CheckJNI::NewString,
+  CheckJNI::GetStringLength,
+  CheckJNI::GetStringChars,
+  CheckJNI::ReleaseStringChars,
+  CheckJNI::NewStringUTF,
+  CheckJNI::GetStringUTFLength,
+  CheckJNI::GetStringUTFChars,
+  CheckJNI::ReleaseStringUTFChars,
+  CheckJNI::GetArrayLength,
+  CheckJNI::NewObjectArray,
+  CheckJNI::GetObjectArrayElement,
+  CheckJNI::SetObjectArrayElement,
+  CheckJNI::NewBooleanArray,
+  CheckJNI::NewByteArray,
+  CheckJNI::NewCharArray,
+  CheckJNI::NewShortArray,
+  CheckJNI::NewIntArray,
+  CheckJNI::NewLongArray,
+  CheckJNI::NewFloatArray,
+  CheckJNI::NewDoubleArray,
+  CheckJNI::GetBooleanArrayElements,
+  CheckJNI::GetByteArrayElements,
+  CheckJNI::GetCharArrayElements,
+  CheckJNI::GetShortArrayElements,
+  CheckJNI::GetIntArrayElements,
+  CheckJNI::GetLongArrayElements,
+  CheckJNI::GetFloatArrayElements,
+  CheckJNI::GetDoubleArrayElements,
+  CheckJNI::ReleaseBooleanArrayElements,
+  CheckJNI::ReleaseByteArrayElements,
+  CheckJNI::ReleaseCharArrayElements,
+  CheckJNI::ReleaseShortArrayElements,
+  CheckJNI::ReleaseIntArrayElements,
+  CheckJNI::ReleaseLongArrayElements,
+  CheckJNI::ReleaseFloatArrayElements,
+  CheckJNI::ReleaseDoubleArrayElements,
+  CheckJNI::GetBooleanArrayRegion,
+  CheckJNI::GetByteArrayRegion,
+  CheckJNI::GetCharArrayRegion,
+  CheckJNI::GetShortArrayRegion,
+  CheckJNI::GetIntArrayRegion,
+  CheckJNI::GetLongArrayRegion,
+  CheckJNI::GetFloatArrayRegion,
+  CheckJNI::GetDoubleArrayRegion,
+  CheckJNI::SetBooleanArrayRegion,
+  CheckJNI::SetByteArrayRegion,
+  CheckJNI::SetCharArrayRegion,
+  CheckJNI::SetShortArrayRegion,
+  CheckJNI::SetIntArrayRegion,
+  CheckJNI::SetLongArrayRegion,
+  CheckJNI::SetFloatArrayRegion,
+  CheckJNI::SetDoubleArrayRegion,
+  CheckJNI::RegisterNatives,
+  CheckJNI::UnregisterNatives,
+  CheckJNI::MonitorEnter,
+  CheckJNI::MonitorExit,
+  CheckJNI::GetJavaVM,
+  CheckJNI::GetStringRegion,
+  CheckJNI::GetStringUTFRegion,
+  CheckJNI::GetPrimitiveArrayCritical,
+  CheckJNI::ReleasePrimitiveArrayCritical,
+  CheckJNI::GetStringCritical,
+  CheckJNI::ReleaseStringCritical,
+  CheckJNI::NewWeakGlobalRef,
+  CheckJNI::DeleteWeakGlobalRef,
+  CheckJNI::ExceptionCheck,
+  CheckJNI::NewDirectByteBuffer,
+  CheckJNI::GetDirectBufferAddress,
+  CheckJNI::GetDirectBufferCapacity,
+  CheckJNI::GetObjectRefType,
+};
+
+const JNINativeInterface* GetCheckJniNativeInterface() {
+  return &gCheckNativeInterface;
+}
+
+class CheckJII {
+public:
+  static jint DestroyJavaVM(JavaVM* vm) {
+    ScopedCheck sc(false, __FUNCTION__);
+    sc.check(true, "v", vm);
+    return CHECK_JNI_EXIT("I", baseVm(vm)->DestroyJavaVM(vm));
+  }
+
+  static jint AttachCurrentThread(JavaVM* vm, JNIEnv** p_env, void* thr_args) {
+    ScopedCheck sc(false, __FUNCTION__);
+    sc.check(true, "vpp", vm, p_env, thr_args);
+    return CHECK_JNI_EXIT("I", baseVm(vm)->AttachCurrentThread(vm, p_env, thr_args));
+  }
+
+  static jint AttachCurrentThreadAsDaemon(JavaVM* vm, JNIEnv** p_env, void* thr_args) {
+    ScopedCheck sc(false, __FUNCTION__);
+    sc.check(true, "vpp", vm, p_env, thr_args);
+    return CHECK_JNI_EXIT("I", baseVm(vm)->AttachCurrentThreadAsDaemon(vm, p_env, thr_args));
+  }
+
+  static jint DetachCurrentThread(JavaVM* vm) {
+    ScopedCheck sc(true, __FUNCTION__);
+    sc.check(true, "v", vm);
+    return CHECK_JNI_EXIT("I", baseVm(vm)->DetachCurrentThread(vm));
+  }
+
+  static jint GetEnv(JavaVM* vm, void** env, jint version) {
+    ScopedCheck sc(true, __FUNCTION__);
+    sc.check(true, "v", vm);
+    return CHECK_JNI_EXIT("I", baseVm(vm)->GetEnv(vm, env, version));
+  }
+
+ private:
+  static inline const JNIInvokeInterface* baseVm(JavaVM* vm) {
+    return reinterpret_cast<JavaVMExt*>(vm)->unchecked_functions;
+  }
+};
+
+const JNIInvokeInterface gCheckInvokeInterface = {
+  NULL,  // reserved0
+  NULL,  // reserved1
+  NULL,  // reserved2
+  CheckJII::DestroyJavaVM,
+  CheckJII::AttachCurrentThread,
+  CheckJII::DetachCurrentThread,
+  CheckJII::GetEnv,
+  CheckJII::AttachCurrentThreadAsDaemon
+};
+
+const JNIInvokeInterface* GetCheckJniInvokeInterface() {
+  return &gCheckInvokeInterface;
+}
+
+}  // namespace art
diff --git a/src/heap.cc b/src/heap.cc
index 42e42bd..e96714f 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -112,7 +112,7 @@
   return obj;
 }
 
-void Heap::VerifyObject(Object *obj) {
+void Heap::VerifyObject(Object* obj) {
   if (!IsAligned(obj, kObjectAlignment)) {
     LOG(FATAL) << "Object isn't aligned: " << obj;
   } else if (!live_bitmap_->Test(obj)) {
@@ -124,6 +124,14 @@
   }
 }
 
+bool Heap::IsHeapAddress(Object* obj) {
+  if (!IsAligned(obj, kObjectAlignment)) {
+    return false;
+  }
+  // TODO
+  return true;
+}
+
 void Heap::RecordAllocation(Space* space, const Object* obj) {
   size_t size = space->AllocationSize(obj);
   DCHECK_NE(size, 0u);
diff --git a/src/heap.h b/src/heap.h
index 1e56778..bbd05db 100644
--- a/src/heap.h
+++ b/src/heap.h
@@ -33,9 +33,14 @@
   // Allocates and initializes storage for an object instance.
   static Object* AllocObject(Class* klass, size_t num_bytes);
 
-  // Check sanity of given reference
+  // Check sanity of given reference. Requires the heap lock.
   static void VerifyObject(Object *obj);
 
+  // A weaker test than VerifyObject that doesn't require the heap lock,
+  // and doesn't abort on error, allowing the caller to report more
+  // meaningful diagnostics.
+  static bool IsHeapAddress(Object* obj);
+
   // Initiates an explicit garbage collection.
   static void CollectGarbage();
 
diff --git a/src/indirect_reference_table.cc b/src/indirect_reference_table.cc
index 76d5379..6e5446f 100644
--- a/src/indirect_reference_table.cc
+++ b/src/indirect_reference_table.cc
@@ -15,20 +15,21 @@
  */
 
 #include "indirect_reference_table.h"
+#include "jni_internal.h"
 #include "reference_table.h"
+#include "runtime.h"
 #include "utils.h"
 
 #include <cstdlib>
 
 namespace art {
 
-// TODO: implement this for art. (only needed for non-CheckJNI operation.)
 static void AbortMaybe() {
-  // If CheckJNI is on, it'll give a more detailed error before aborting.
-  // Otherwise, we want to abort rather than hand back a bad reference.
-//  if (!gDvmJni.useCheckJni) {
-//    LOG(FATAL) << "bye!";
-//  }
+  // If -Xcheck:jni is on, it'll give a more detailed error before aborting.
+  if (!Runtime::Current()->GetJavaVM()->check_jni) {
+    // Otherwise, we want to abort rather than hand back a bad reference.
+    LOG(FATAL) << "JNI ERROR (app bug): see above.";
+  }
 }
 
 IndirectReferenceTable::IndirectReferenceTable(size_t initialCount,
diff --git a/src/indirect_reference_table.h b/src/indirect_reference_table.h
index 358162c..4a8833c 100644
--- a/src/indirect_reference_table.h
+++ b/src/indirect_reference_table.h
@@ -95,7 +95,7 @@
  */
 typedef void* IndirectRef;
 
-/* magic failure values; must not pass dvmIsHeapAddress() */
+/* Magic failure values; must not pass Heap::ValidateObject() or Heap::IsHeapAddress(). */
 static Object* const kInvalidIndirectRefObject = reinterpret_cast<Object*>(0xdead4321);
 static Object* const kClearedJniWeakGlobal = reinterpret_cast<Object*>(0xdead1234);
 
diff --git a/src/jni_compiler_test.cc b/src/jni_compiler_test.cc
index 9129162..4cd32e8 100644
--- a/src/jni_compiler_test.cc
+++ b/src/jni_compiler_test.cc
@@ -353,27 +353,35 @@
 
 int gExceptionHandler_calls;
 void ExceptionHandler(Method** frame) {
-  EXPECT_TRUE((*frame)->GetName()->Equals("foo"));
+  EXPECT_TRUE((*frame)->GetName()->Equals("throwException"));
   gExceptionHandler_calls++;
   Thread::Current()->ClearException();
 }
 
-TEST_F(JniCompilerTest, ExceptionHandling) {
-  SetupForTest(false, "foo", "()V", reinterpret_cast<void*>(&Java_MyClass_foo));
-  Thread::Current()->RegisterExceptionEntryPoint(&ExceptionHandler);
+void Java_MyClass_throwException(JNIEnv* env, jobject) {
+  jclass c = env->FindClass("java/lang/RuntimeException");
+  env->ThrowNew(c, "hello");
+}
 
+TEST_F(JniCompilerTest, ExceptionHandling) {
+  Thread::Current()->RegisterExceptionEntryPoint(&ExceptionHandler);
+  gExceptionHandler_calls = 0;
   gJava_MyClass_foo_calls = 0;
+
+  SetupForTest(false, "foo", "()V", reinterpret_cast<void*>(&Java_MyClass_foo));
   env_->CallNonvirtualVoidMethod(jobj_, jklass_, jmethod_);
   EXPECT_EQ(1, gJava_MyClass_foo_calls);
   EXPECT_EQ(0, gExceptionHandler_calls);
-  // TODO: create a real exception here
-  Thread::Current()->SetException(reinterpret_cast<Throwable*>(jobj_));
+
+  SetupForTest(false, "throwException", "()V", reinterpret_cast<void*>(&Java_MyClass_throwException));
+  env_->CallNonvirtualVoidMethod(jobj_, jklass_, jmethod_);
+  EXPECT_EQ(1, gJava_MyClass_foo_calls);
+  EXPECT_EQ(1, gExceptionHandler_calls);
+
+  SetupForTest(false, "foo", "()V", reinterpret_cast<void*>(&Java_MyClass_foo));
   env_->CallNonvirtualVoidMethod(jobj_, jklass_, jmethod_);
   EXPECT_EQ(2, gJava_MyClass_foo_calls);
   EXPECT_EQ(1, gExceptionHandler_calls);
-  env_->CallNonvirtualVoidMethod(jobj_, jklass_, jmethod_);
-  EXPECT_EQ(3, gJava_MyClass_foo_calls);
-  EXPECT_EQ(1, gExceptionHandler_calls);
 }
 
 jint Java_MyClass_nativeUpCall(JNIEnv* env, jobject thisObj, jint i) {
diff --git a/src/jni_internal.cc b/src/jni_internal.cc
index 57090ac..97c4cea 100644
--- a/src/jni_internal.cc
+++ b/src/jni_internal.cc
@@ -41,7 +41,7 @@
   size_t length = assembler.CodeSize();
   void* addr = mmap(NULL, length, prot, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
   if (addr == MAP_FAILED) {
-    PLOG(FATAL) << "mmap failed for " << PrettyMethod(method, true);
+    PLOG(FATAL) << "mmap failed for " << PrettyMethod(method);
   }
   MemoryRegion region(addr, length);
   assembler.FinalizeInstructions(region);
@@ -267,7 +267,7 @@
     (*stub)(method, receiver, self, args, &result);
   } else {
     LOG(WARNING) << "Not invoking method with no associated code: "
-                 << PrettyMethod(method, true);
+                 << PrettyMethod(method);
     result.j = 0;
   }
 
@@ -354,7 +354,7 @@
 
   if (method == NULL || method->IsStatic() != is_static) {
     Thread* self = Thread::Current();
-    std::string method_name(PrettyMethod(method, true));
+    std::string method_name(PrettyMethod(method));
     // TODO: try searching for the opposite kind of method from is_static
     // for better diagnostics?
     self->ThrowNewException("Ljava/lang/NoSuchMethodError;",
@@ -640,7 +640,7 @@
       }
       if (fn != NULL) {
         if (Runtime::Current()->GetJavaVM()->verbose_jni) {
-          LOG(INFO) << "[Found native code for " << PrettyMethod(m, true)
+          LOG(INFO) << "[Found native code for " << PrettyMethod(m)
                     << " in \"" << library->GetPath() << "\"]";
         }
         return fn;
@@ -648,7 +648,7 @@
     }
     std::string detail;
     detail += "No implementation found for ";
-    detail += PrettyMethod(m, true);
+    detail += PrettyMethod(m);
     LOG(ERROR) << detail;
     Thread::Current()->ThrowNewException("Ljava/lang/UnsatisfiedLinkError;",
         "%s", detail.c_str());
@@ -2201,8 +2201,7 @@
       }
 
       if (ts.Vm()->verbose_jni) {
-        LOG(INFO) << "[Registering JNI native method "
-                  << PrettyMethod(m, true) << "]";
+        LOG(INFO) << "[Registering JNI native method " << PrettyMethod(m) << "]";
       }
 
       m->RegisterNative(methods[i].fnPtr);
@@ -2328,7 +2327,7 @@
   }
 };
 
-static const struct JNINativeInterface gNativeInterface = {
+const JNINativeInterface gNativeInterface = {
   NULL,  // reserved0.
   NULL,  // reserved1.
   NULL,  // reserved2.
@@ -2577,7 +2576,10 @@
       critical(false),
       monitors("monitors", kMonitorsInitial, kMonitorsMax),
       locals(kLocalsInitial, kLocalsMax, kLocal) {
-  functions = &gNativeInterface;
+  functions = unchecked_functions = &gNativeInterface;
+  if (check_jni) {
+    functions = GetCheckJniNativeInterface();
+  }
 }
 
 JNIEnvExt::~JNIEnvExt() {
@@ -2671,7 +2673,7 @@
   }
 };
 
-struct JNIInvokeInterface gInvokeInterface = {
+const JNIInvokeInterface gInvokeInterface = {
   NULL,  // reserved0
   NULL,  // reserved1
   NULL,  // reserved2
@@ -2693,8 +2695,10 @@
 
 JavaVMExt::JavaVMExt(Runtime* runtime, bool check_jni, bool verbose_jni)
     : runtime(runtime),
+      check_jni_abort_hook(NULL),
       check_jni(check_jni),
       verbose_jni(verbose_jni),
+      force_copy(false), // TODO
       pins_lock(Mutex::Create("JNI pin table lock")),
       pin_table("pin table", kPinTableInitialSize, kPinTableMaxSize),
       globals_lock(Mutex::Create("JNI global reference table lock")),
@@ -2703,7 +2707,10 @@
       weak_globals(kWeakGlobalsInitial, kWeakGlobalsMax, kWeakGlobal),
       libraries_lock(Mutex::Create("JNI shared libraries map lock")),
       libraries(new Libraries) {
-  functions = &gInvokeInterface;
+  functions = unchecked_functions = &gInvokeInterface;
+  if (check_jni) {
+    functions = GetCheckJniInvokeInterface();
+  }
 }
 
 JavaVMExt::~JavaVMExt() {
diff --git a/src/jni_internal.h b/src/jni_internal.h
index c8a5a39..a4362d3 100644
--- a/src/jni_internal.h
+++ b/src/jni_internal.h
@@ -20,6 +20,8 @@
 class Runtime;
 class Thread;
 
+void JniAbort(const char* jni_function_name);
+
 struct JavaVMExt : public JavaVM {
   JavaVMExt(Runtime* runtime, bool check_jni, bool verbose_jni);
   ~JavaVMExt();
@@ -40,8 +42,12 @@
 
   Runtime* runtime;
 
+  // Used for testing. By default, we'll LOG(FATAL) the reason.
+  void (*check_jni_abort_hook)(const std::string& reason);
+
   bool check_jni;
   bool verbose_jni;
+  bool force_copy;
 
   // Used to hold references to pinned primitive arrays.
   Mutex* pins_lock;
@@ -57,6 +63,9 @@
 
   Mutex* libraries_lock;
   Libraries* libraries;
+
+  // Used by -Xcheck:jni.
+  const JNIInvokeInterface* unchecked_functions;
 };
 
 struct JNIEnvExt : public JNIEnv {
@@ -68,16 +77,22 @@
 
   bool check_jni;
 
-  // Are we in a "critical" JNI call?
-  bool critical;
+  // How many nested "critical" JNI calls are we in?
+  int critical;
 
   // Entered JNI monitors, for bulk exit on thread detach.
   ReferenceTable  monitors;
 
   // JNI local references.
   IndirectReferenceTable locals;
+
+  // Used by -Xcheck:jni.
+  const JNINativeInterface* unchecked_functions;
 };
 
+const JNINativeInterface* GetCheckJniNativeInterface();
+const JNIInvokeInterface* GetCheckJniInvokeInterface();
+
 }  // namespace art
 
 std::ostream& operator<<(std::ostream& os, const jobjectRefType& rhs);
diff --git a/src/jni_internal_test.cc b/src/jni_internal_test.cc
index c66bb42..a71975b 100644
--- a/src/jni_internal_test.cc
+++ b/src/jni_internal_test.cc
@@ -15,8 +15,10 @@
   virtual void SetUp() {
     CommonTest::SetUp();
 
+    vm_ = Runtime::Current()->GetJavaVM();
+
     // Turn on -verbose:jni for the JNI tests.
-    Runtime::Current()->GetJavaVM()->verbose_jni = true;
+    vm_->verbose_jni = true;
 
     env_ = Thread::Current()->GetJniEnv();
 
@@ -27,7 +29,8 @@
     CHECK(sioobe_ != NULL);
   }
 
-  JNIEnv* env_;
+  JavaVMExt* vm_;
+  JNIEnvExt* env_;
   jclass aioobe_;
   jclass sioobe_;
 };
@@ -60,29 +63,39 @@
   EXPECT_TRUE(env_->ExceptionCheck()); \
   env_->ExceptionClear()
 
+std::string gCheckJniAbortMessage;
+void TestCheckJniAbortHook(const std::string& reason) {
+  gCheckJniAbortMessage = reason;
+}
+
 TEST_F(JniInternalTest, FindClass) {
   // TODO: when these tests start failing because you're calling FindClass
   // with a pending exception, fix EXPECT_CLASS_NOT_FOUND to assert that an
   // exception was thrown and clear the exception.
 
-  // TODO: . is only allowed as an alternative to / if CheckJNI is off.
-
   // Reference types...
-  // You can't include the "L;" in a JNI class descriptor.
   EXPECT_CLASS_FOUND("java/lang/String");
-  EXPECT_CLASS_NOT_FOUND("Ljava/lang/String;");
-  // We support . as well as / for compatibility.
-  EXPECT_CLASS_FOUND("java.lang.String");
-  EXPECT_CLASS_NOT_FOUND("Ljava.lang.String;");
   // ...for arrays too, where you must include "L;".
   EXPECT_CLASS_FOUND("[Ljava/lang/String;");
-  EXPECT_CLASS_NOT_FOUND("[java/lang/String");
+
+  vm_->check_jni_abort_hook = TestCheckJniAbortHook;
+  // We support . as well as / for compatibility, if -Xcheck:jni is off.
+  EXPECT_CLASS_FOUND("java.lang.String");
+  EXPECT_CLASS_NOT_FOUND("Ljava.lang.String;");
   EXPECT_CLASS_FOUND("[Ljava.lang.String;");
   EXPECT_CLASS_NOT_FOUND("[java.lang.String");
 
+  // You can't include the "L;" in a JNI class descriptor.
+  EXPECT_CLASS_NOT_FOUND("Ljava/lang/String;");
+  // But you must include it for an array of any reference type.
+  EXPECT_CLASS_NOT_FOUND("[java/lang/String");
+  vm_->check_jni_abort_hook = NULL;
+
   // Primitive arrays are okay (if the primitive type is valid)...
   EXPECT_CLASS_FOUND("[C");
+  vm_->check_jni_abort_hook = TestCheckJniAbortHook;
   EXPECT_CLASS_NOT_FOUND("[K");
+  vm_->check_jni_abort_hook = NULL;
   // But primitive types aren't allowed...
   EXPECT_CLASS_NOT_FOUND("C");
   EXPECT_CLASS_NOT_FOUND("K");
@@ -93,8 +106,8 @@
     EXPECT_TRUE(env_->ExceptionCheck()); \
     jthrowable exception = env_->ExceptionOccurred(); \
     EXPECT_NE(static_cast<jthrowable>(NULL), exception); \
-    EXPECT_TRUE(env_->IsInstanceOf(exception, exception_class)); \
     env_->ExceptionClear(); \
+    EXPECT_TRUE(env_->IsInstanceOf(exception, exception_class)); \
   } while (false)
 
 TEST_F(JniInternalTest, GetFieldID) {
@@ -514,7 +527,10 @@
 }
 
 TEST_F(JniInternalTest, GetStringUTFChars_ReleaseStringUTFChars) {
+  vm_->check_jni_abort_hook = TestCheckJniAbortHook;
+  // Passing in a NULL jstring is ignored normally, but caught by -Xcheck:jni.
   EXPECT_TRUE(env_->GetStringUTFChars(NULL, NULL) == NULL);
+  vm_->check_jni_abort_hook = NULL;
 
   jstring s = env_->NewStringUTF("hello");
   ASSERT_TRUE(s != NULL);
@@ -704,7 +720,9 @@
   env_->DeleteLocalRef(s);
 
   // Currently, deleting an already-deleted reference is just a warning.
+  vm_->check_jni_abort_hook = TestCheckJniAbortHook;
   env_->DeleteLocalRef(s);
+  vm_->check_jni_abort_hook = NULL;
 
   s = env_->NewStringUTF("");
   ASSERT_TRUE(s != NULL);
@@ -741,8 +759,10 @@
   ASSERT_TRUE(o != NULL);
   env_->DeleteGlobalRef(o);
 
+  vm_->check_jni_abort_hook = TestCheckJniAbortHook;
   // Currently, deleting an already-deleted reference is just a warning.
   env_->DeleteGlobalRef(o);
+  vm_->check_jni_abort_hook = NULL;
 
   jobject o1 = env_->NewGlobalRef(s);
   ASSERT_TRUE(o1 != NULL);
@@ -779,8 +799,10 @@
   ASSERT_TRUE(o != NULL);
   env_->DeleteWeakGlobalRef(o);
 
+  vm_->check_jni_abort_hook = TestCheckJniAbortHook;
   // Currently, deleting an already-deleted reference is just a warning.
   env_->DeleteWeakGlobalRef(o);
+  vm_->check_jni_abort_hook = NULL;
 
   jobject o1 = env_->NewWeakGlobalRef(s);
   ASSERT_TRUE(o1 != NULL);
@@ -1508,8 +1530,9 @@
 
   EXPECT_EQ(JNI_OK, env_->Throw(exception));
   EXPECT_TRUE(env_->ExceptionCheck());
-  EXPECT_TRUE(env_->IsSameObject(exception, env_->ExceptionOccurred()));
+  jthrowable thrown_exception = env_->ExceptionOccurred();
   env_->ExceptionClear();
+  EXPECT_TRUE(env_->IsSameObject(exception, thrown_exception));
 }
 
 TEST_F(JniInternalTest, ThrowNew) {
@@ -1520,8 +1543,9 @@
 
   EXPECT_EQ(JNI_OK, env_->ThrowNew(exception_class, "hello world"));
   EXPECT_TRUE(env_->ExceptionCheck());
-  EXPECT_TRUE(env_->IsInstanceOf(env_->ExceptionOccurred(), exception_class));
+  jthrowable thrown_exception = env_->ExceptionOccurred();
   env_->ExceptionClear();
+  EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, exception_class));
 }
 
 // TODO: this test is DISABLED until we can actually run java.nio.Buffer's <init>.
diff --git a/src/thread.cc b/src/thread.cc
index 525e2a1..c90c745 100644
--- a/src/thread.cc
+++ b/src/thread.cc
@@ -303,16 +303,18 @@
       // Assume an invalid local reference is actually a direct pointer.
       result = reinterpret_cast<Object*>(obj);
     } else {
-      LOG(FATAL) << "Invalid indirect reference " << obj;
-      result = reinterpret_cast<Object*>(kInvalidIndirectRefObject);
+      result = kInvalidIndirectRefObject;
     }
   }
 
   if (result == NULL) {
-    LOG(FATAL) << "JNI ERROR (app bug): use of deleted " << kind << ": "
-               << obj;
+    LOG(ERROR) << "JNI ERROR (app bug): use of deleted " << kind << ": " << obj;
+    JniAbort(NULL);
+  } else {
+    if (result != kInvalidIndirectRefObject) {
+      Heap::VerifyObject(result);
+    }
   }
-  Heap::VerifyObject(result);
   return result;
 }
 
diff --git a/src/utils.cc b/src/utils.cc
index 84b1556..695cbb3 100644
--- a/src/utils.cc
+++ b/src/utils.cc
@@ -84,6 +84,16 @@
   return result;
 }
 
+std::string PrettyField(const Field* f) {
+  if (f == NULL) {
+    return "null";
+  }
+  std::string result(PrettyDescriptor(f->GetDeclaringClass()->GetDescriptor()));
+  result += '.';
+  result += f->GetName()->ToModifiedUtf8();
+  return result;
+}
+
 std::string PrettyMethod(const Method* m, bool with_signature) {
   if (m == NULL) {
     return "null";
diff --git a/src/utils.h b/src/utils.h
index 6bc27a8..4b3e57e 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -10,6 +10,7 @@
 
 namespace art {
 
+class Field;
 class Method;
 class Object;
 class String;
@@ -142,6 +143,9 @@
 // "java.lang.String[]", and so forth.
 std::string PrettyDescriptor(const String* descriptor);
 
+// Returns a human-readable signature for 'f'. Something like "a.b.C.f".
+std::string PrettyField(const Field* f);
+
 // Returns a human-readable signature for 'm'. Something like "a.b.C.m" or
 // "a.b.C.m(II)V" (depending on the value of 'with_signature').
 std::string PrettyMethod(const Method* m, bool with_signature = true);
diff --git a/test/MyClassNatives/MyClassNatives.java b/test/MyClassNatives/MyClassNatives.java
index 5203e4a..f462363 100644
--- a/test/MyClassNatives/MyClassNatives.java
+++ b/test/MyClassNatives/MyClassNatives.java
@@ -1,6 +1,7 @@
 // Copyright 2011 Google Inc. All Rights Reserved.
 
 class MyClass {
+    native void throwException();
     native void foo();
     native int fooI(int x);
     native int fooII(int x, int y);
