Home | History | Annotate | Download | only in runtime
      1 /*
      2  * Copyright (C) 2008 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "jni_internal.h"
     18 
     19 #include <sys/mman.h>
     20 #include <zlib.h>
     21 
     22 #include "base/logging.h"
     23 #include "class_linker.h"
     24 #include "class_linker-inl.h"
     25 #include "dex_file-inl.h"
     26 #include "gc/space/space.h"
     27 #include "mirror/art_field-inl.h"
     28 #include "mirror/art_method-inl.h"
     29 #include "mirror/class-inl.h"
     30 #include "mirror/object-inl.h"
     31 #include "mirror/object_array-inl.h"
     32 #include "mirror/throwable.h"
     33 #include "object_utils.h"
     34 #include "runtime.h"
     35 #include "scoped_thread_state_change.h"
     36 #include "thread.h"
     37 
     38 namespace art {
     39 
     40 static void JniAbort(const char* jni_function_name, const char* msg) {
     41   Thread* self = Thread::Current();
     42   ScopedObjectAccess soa(self);
     43   mirror::ArtMethod* current_method = self->GetCurrentMethod(NULL);
     44 
     45   std::ostringstream os;
     46   os << "JNI DETECTED ERROR IN APPLICATION: " << msg;
     47 
     48   if (jni_function_name != NULL) {
     49     os << "\n    in call to " << jni_function_name;
     50   }
     51   // TODO: is this useful given that we're about to dump the calling thread's stack?
     52   if (current_method != NULL) {
     53     os << "\n    from " << PrettyMethod(current_method);
     54   }
     55   os << "\n";
     56   self->Dump(os);
     57 
     58   JavaVMExt* vm = Runtime::Current()->GetJavaVM();
     59   if (vm->check_jni_abort_hook != NULL) {
     60     vm->check_jni_abort_hook(vm->check_jni_abort_hook_data, os.str());
     61   } else {
     62     // Ensure that we get a native stack trace for this thread.
     63     self->TransitionFromRunnableToSuspended(kNative);
     64     LOG(FATAL) << os.str();
     65     self->TransitionFromSuspendedToRunnable();  // Unreachable, keep annotalysis happy.
     66   }
     67 }
     68 
     69 static void JniAbortV(const char* jni_function_name, const char* fmt, va_list ap) {
     70   std::string msg;
     71   StringAppendV(&msg, fmt, ap);
     72   JniAbort(jni_function_name, msg.c_str());
     73 }
     74 
     75 void JniAbortF(const char* jni_function_name, const char* fmt, ...) {
     76   va_list args;
     77   va_start(args, fmt);
     78   JniAbortV(jni_function_name, fmt, args);
     79   va_end(args);
     80 }
     81 
     82 /*
     83  * ===========================================================================
     84  *      JNI function helpers
     85  * ===========================================================================
     86  */
     87 
     88 static bool IsSirtLocalRef(JNIEnv* env, jobject localRef) {
     89   return GetIndirectRefKind(localRef) == kSirtOrInvalid &&
     90       reinterpret_cast<JNIEnvExt*>(env)->self->SirtContains(localRef);
     91 }
     92 
     93 // Hack to allow forcecopy to work with jniGetNonMovableArrayElements.
     94 // The code deliberately uses an invalid sequence of operations, so we
     95 // need to pass it through unmodified.  Review that code before making
     96 // any changes here.
     97 #define kNoCopyMagic    0xd5aab57f
     98 
     99 // Flags passed into ScopedCheck.
    100 #define kFlag_Default       0x0000
    101 
    102 #define kFlag_CritBad       0x0000      // Calling while in critical is not allowed.
    103 #define kFlag_CritOkay      0x0001      // Calling while in critical is allowed.
    104 #define kFlag_CritGet       0x0002      // This is a critical "get".
    105 #define kFlag_CritRelease   0x0003      // This is a critical "release".
    106 #define kFlag_CritMask      0x0003      // Bit mask to get "crit" value.
    107 
    108 #define kFlag_ExcepBad      0x0000      // Raised exceptions are not allowed.
    109 #define kFlag_ExcepOkay     0x0004      // Raised exceptions are allowed.
    110 
    111 #define kFlag_Release       0x0010      // Are we in a non-critical release function?
    112 #define kFlag_NullableUtf   0x0020      // Are our UTF parameters nullable?
    113 
    114 #define kFlag_Invocation    0x8000      // Part of the invocation interface (JavaVM*).
    115 
    116 #define kFlag_ForceTrace    0x80000000  // Add this to a JNI function's flags if you want to trace every call.
    117 
    118 static const char* gBuiltInPrefixes[] = {
    119   "Landroid/",
    120   "Lcom/android/",
    121   "Lcom/google/android/",
    122   "Ldalvik/",
    123   "Ljava/",
    124   "Ljavax/",
    125   "Llibcore/",
    126   "Lorg/apache/harmony/",
    127   NULL
    128 };
    129 
    130 static bool ShouldTrace(JavaVMExt* vm, const mirror::ArtMethod* method)
    131     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    132   // If both "-Xcheck:jni" and "-Xjnitrace:" are enabled, we print trace messages
    133   // when a native method that matches the -Xjnitrace argument calls a JNI function
    134   // such as NewByteArray.
    135   // If -verbose:third-party-jni is on, we want to log any JNI function calls
    136   // made by a third-party native method.
    137   std::string class_name(MethodHelper(method).GetDeclaringClassDescriptor());
    138   if (!vm->trace.empty() && class_name.find(vm->trace) != std::string::npos) {
    139     return true;
    140   }
    141   if (VLOG_IS_ON(third_party_jni)) {
    142     // Return true if we're trying to log all third-party JNI activity and 'method' doesn't look
    143     // like part of Android.
    144     for (size_t i = 0; gBuiltInPrefixes[i] != NULL; ++i) {
    145       if (StartsWith(class_name, gBuiltInPrefixes[i])) {
    146         return false;
    147       }
    148     }
    149     return true;
    150   }
    151   return false;
    152 }
    153 
    154 class ScopedCheck {
    155  public:
    156   // For JNIEnv* functions.
    157   explicit ScopedCheck(JNIEnv* env, int flags, const char* functionName)
    158       SHARED_LOCK_FUNCTION(Locks::mutator_lock_)
    159       : soa_(env) {
    160     Init(flags, functionName, true);
    161     CheckThread(flags);
    162   }
    163 
    164   // For JavaVM* functions.
    165   // TODO: it's not correct that this is a lock function, but making it so aids annotalysis.
    166   explicit ScopedCheck(JavaVM* vm, bool has_method, const char* functionName)
    167       SHARED_LOCK_FUNCTION(Locks::mutator_lock_)
    168       : soa_(vm) {
    169     Init(kFlag_Invocation, functionName, has_method);
    170   }
    171 
    172   ~ScopedCheck() UNLOCK_FUNCTION(Locks::mutator_lock_) {}
    173 
    174   const ScopedObjectAccess& soa() {
    175     return soa_;
    176   }
    177 
    178   bool ForceCopy() {
    179     return Runtime::Current()->GetJavaVM()->force_copy;
    180   }
    181 
    182   // Checks that 'class_name' is a valid "fully-qualified" JNI class name, like "java/lang/Thread"
    183   // or "[Ljava/lang/Object;". A ClassLoader can actually normalize class names a couple of
    184   // times, so using "java.lang.Thread" instead of "java/lang/Thread" might work in some
    185   // circumstances, but this is incorrect.
    186   void CheckClassName(const char* class_name) {
    187     if (!IsValidJniClassName(class_name)) {
    188       JniAbortF(function_name_,
    189                 "illegal class name '%s'\n"
    190                 "    (should be of the form 'package/Class', [Lpackage/Class;' or '[[B')",
    191                 class_name);
    192     }
    193   }
    194 
    195   /*
    196    * Verify that the field is of the appropriate type.  If the field has an
    197    * object type, "java_object" is the object we're trying to assign into it.
    198    *
    199    * Works for both static and instance fields.
    200    */
    201   void CheckFieldType(jobject java_object, jfieldID fid, char prim, bool isStatic)
    202       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    203     mirror::ArtField* f = CheckFieldID(fid);
    204     if (f == NULL) {
    205       return;
    206     }
    207     mirror::Class* field_type = FieldHelper(f).GetType();
    208     if (!field_type->IsPrimitive()) {
    209       if (java_object != NULL) {
    210         mirror::Object* obj = soa_.Decode<mirror::Object*>(java_object);
    211         // If java_object is a weak global ref whose referent has been cleared,
    212         // obj will be NULL.  Otherwise, obj should always be non-NULL
    213         // and valid.
    214         if (!Runtime::Current()->GetHeap()->IsHeapAddress(obj)) {
    215           Runtime::Current()->GetHeap()->DumpSpaces();
    216           JniAbortF(function_name_, "field operation on invalid %s: %p",
    217                     ToStr<IndirectRefKind>(GetIndirectRefKind(java_object)).c_str(), java_object);
    218           return;
    219         } else {
    220           if (!obj->InstanceOf(field_type)) {
    221             JniAbortF(function_name_, "attempt to set field %s with value of wrong type: %s",
    222                       PrettyField(f).c_str(), PrettyTypeOf(obj).c_str());
    223             return;
    224           }
    225         }
    226       }
    227     } else if (field_type != Runtime::Current()->GetClassLinker()->FindPrimitiveClass(prim)) {
    228       JniAbortF(function_name_, "attempt to set field %s with value of wrong type: %c",
    229                 PrettyField(f).c_str(), prim);
    230       return;
    231     }
    232 
    233     if (isStatic != f->IsStatic()) {
    234       if (isStatic) {
    235         JniAbortF(function_name_, "accessing non-static field %s as static", PrettyField(f).c_str());
    236       } else {
    237         JniAbortF(function_name_, "accessing static field %s as non-static", PrettyField(f).c_str());
    238       }
    239       return;
    240     }
    241   }
    242 
    243   /*
    244    * Verify that this instance field ID is valid for this object.
    245    *
    246    * Assumes "jobj" has already been validated.
    247    */
    248   void CheckInstanceFieldID(jobject java_object, jfieldID fid)
    249       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    250     mirror::Object* o = soa_.Decode<mirror::Object*>(java_object);
    251     if (o == NULL || !Runtime::Current()->GetHeap()->IsHeapAddress(o)) {
    252       Runtime::Current()->GetHeap()->DumpSpaces();
    253       JniAbortF(function_name_, "field operation on invalid %s: %p",
    254                 ToStr<IndirectRefKind>(GetIndirectRefKind(java_object)).c_str(), java_object);
    255       return;
    256     }
    257 
    258     mirror::ArtField* f = CheckFieldID(fid);
    259     if (f == NULL) {
    260       return;
    261     }
    262     mirror::Class* c = o->GetClass();
    263     FieldHelper fh(f);
    264     if (c->FindInstanceField(fh.GetName(), fh.GetTypeDescriptor()) == NULL) {
    265       JniAbortF(function_name_, "jfieldID %s not valid for an object of class %s",
    266                 PrettyField(f).c_str(), PrettyTypeOf(o).c_str());
    267     }
    268   }
    269 
    270   /*
    271    * Verify that the pointer value is non-NULL.
    272    */
    273   void CheckNonNull(const void* ptr) {
    274     if (ptr == NULL) {
    275       JniAbortF(function_name_, "non-nullable argument was NULL");
    276     }
    277   }
    278 
    279   /*
    280    * Verify that the method's return type matches the type of call.
    281    * 'expectedType' will be "L" for all objects, including arrays.
    282    */
    283   void CheckSig(jmethodID mid, const char* expectedType, bool isStatic)
    284       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    285     mirror::ArtMethod* m = CheckMethodID(mid);
    286     if (m == NULL) {
    287       return;
    288     }
    289     if (*expectedType != MethodHelper(m).GetShorty()[0]) {
    290       JniAbortF(function_name_, "the return type of %s does not match %s",
    291                 function_name_, PrettyMethod(m).c_str());
    292     }
    293     if (isStatic != m->IsStatic()) {
    294       if (isStatic) {
    295         JniAbortF(function_name_, "calling non-static method %s with %s",
    296                   PrettyMethod(m).c_str(), function_name_);
    297       } else {
    298         JniAbortF(function_name_, "calling static method %s with %s",
    299                   PrettyMethod(m).c_str(), function_name_);
    300       }
    301     }
    302   }
    303 
    304   /*
    305    * Verify that this static field ID is valid for this class.
    306    *
    307    * Assumes "java_class" has already been validated.
    308    */
    309   void CheckStaticFieldID(jclass java_class, jfieldID fid)
    310       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    311     mirror::Class* c = soa_.Decode<mirror::Class*>(java_class);
    312     const mirror::ArtField* f = CheckFieldID(fid);
    313     if (f == NULL) {
    314       return;
    315     }
    316     if (f->GetDeclaringClass() != c) {
    317       JniAbortF(function_name_, "static jfieldID %p not valid for class %s",
    318                 fid, PrettyClass(c).c_str());
    319     }
    320   }
    321 
    322   /*
    323    * Verify that "mid" is appropriate for "java_class".
    324    *
    325    * A mismatch isn't dangerous, because the jmethodID defines the class.  In
    326    * fact, java_class is unused in the implementation.  It's best if we don't
    327    * allow bad code in the system though.
    328    *
    329    * Instances of "java_class" must be instances of the method's declaring class.
    330    */
    331   void CheckStaticMethod(jclass java_class, jmethodID mid)
    332       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    333     const mirror::ArtMethod* m = CheckMethodID(mid);
    334     if (m == NULL) {
    335       return;
    336     }
    337     mirror::Class* c = soa_.Decode<mirror::Class*>(java_class);
    338     if (!m->GetDeclaringClass()->IsAssignableFrom(c)) {
    339       JniAbortF(function_name_, "can't call static %s on class %s",
    340                 PrettyMethod(m).c_str(), PrettyClass(c).c_str());
    341     }
    342   }
    343 
    344   /*
    345    * Verify that "mid" is appropriate for "jobj".
    346    *
    347    * Make sure the object is an instance of the method's declaring class.
    348    * (Note the mid might point to a declaration in an interface; this
    349    * will be handled automatically by the instanceof check.)
    350    */
    351   void CheckVirtualMethod(jobject java_object, jmethodID mid)
    352       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    353     const mirror::ArtMethod* m = CheckMethodID(mid);
    354     if (m == NULL) {
    355       return;
    356     }
    357     mirror::Object* o = soa_.Decode<mirror::Object*>(java_object);
    358     if (!o->InstanceOf(m->GetDeclaringClass())) {
    359       JniAbortF(function_name_, "can't call %s on instance of %s",
    360                 PrettyMethod(m).c_str(), PrettyTypeOf(o).c_str());
    361     }
    362   }
    363 
    364   /**
    365    * The format string is a sequence of the following characters,
    366    * and must be followed by arguments of the corresponding types
    367    * in the same order.
    368    *
    369    * Java primitive types:
    370    * B - jbyte
    371    * C - jchar
    372    * D - jdouble
    373    * F - jfloat
    374    * I - jint
    375    * J - jlong
    376    * S - jshort
    377    * Z - jboolean (shown as true and false)
    378    * V - void
    379    *
    380    * Java reference types:
    381    * L - jobject
    382    * a - jarray
    383    * c - jclass
    384    * s - jstring
    385    *
    386    * JNI types:
    387    * b - jboolean (shown as JNI_TRUE and JNI_FALSE)
    388    * f - jfieldID
    389    * m - jmethodID
    390    * p - void*
    391    * r - jint (for release mode arguments)
    392    * u - const char* (Modified UTF-8)
    393    * z - jsize (for lengths; use i if negative values are okay)
    394    * v - JavaVM*
    395    * E - JNIEnv*
    396    * . - no argument; just print "..." (used for varargs JNI calls)
    397    *
    398    * Use the kFlag_NullableUtf flag where 'u' field(s) are nullable.
    399    */
    400   void Check(bool entry, const char* fmt0, ...) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    401     va_list ap;
    402 
    403     const mirror::ArtMethod* traceMethod = NULL;
    404     if (has_method_ && (!soa_.Vm()->trace.empty() || VLOG_IS_ON(third_party_jni))) {
    405       // We need to guard some of the invocation interface's calls: a bad caller might
    406       // use DetachCurrentThread or GetEnv on a thread that's not yet attached.
    407       Thread* self = Thread::Current();
    408       if ((flags_ & kFlag_Invocation) == 0 || self != NULL) {
    409         traceMethod = self->GetCurrentMethod(NULL);
    410       }
    411     }
    412 
    413     if (((flags_ & kFlag_ForceTrace) != 0) || (traceMethod != NULL && ShouldTrace(soa_.Vm(), traceMethod))) {
    414       va_start(ap, fmt0);
    415       std::string msg;
    416       for (const char* fmt = fmt0; *fmt;) {
    417         char ch = *fmt++;
    418         if (ch == 'B') {  // jbyte
    419           jbyte b = va_arg(ap, int);
    420           if (b >= 0 && b < 10) {
    421             StringAppendF(&msg, "%d", b);
    422           } else {
    423             StringAppendF(&msg, "%#x (%d)", b, b);
    424           }
    425         } else if (ch == 'C') {  // jchar
    426           jchar c = va_arg(ap, int);
    427           if (c < 0x7f && c >= ' ') {
    428             StringAppendF(&msg, "U+%x ('%c')", c, c);
    429           } else {
    430             StringAppendF(&msg, "U+%x", c);
    431           }
    432         } else if (ch == 'F' || ch == 'D') {  // jfloat, jdouble
    433           StringAppendF(&msg, "%g", va_arg(ap, double));
    434         } else if (ch == 'I' || ch == 'S') {  // jint, jshort
    435           StringAppendF(&msg, "%d", va_arg(ap, int));
    436         } else if (ch == 'J') {  // jlong
    437           StringAppendF(&msg, "%lld", va_arg(ap, jlong));
    438         } else if (ch == 'Z') {  // jboolean
    439           StringAppendF(&msg, "%s", va_arg(ap, int) ? "true" : "false");
    440         } else if (ch == 'V') {  // void
    441           msg += "void";
    442         } else if (ch == 'v') {  // JavaVM*
    443           JavaVM* vm = va_arg(ap, JavaVM*);
    444           StringAppendF(&msg, "(JavaVM*)%p", vm);
    445         } else if (ch == 'E') {  // JNIEnv*
    446           JNIEnv* env = va_arg(ap, JNIEnv*);
    447           StringAppendF(&msg, "(JNIEnv*)%p", env);
    448         } else if (ch == 'L' || ch == 'a' || ch == 's') {  // jobject, jarray, jstring
    449           // For logging purposes, these are identical.
    450           jobject o = va_arg(ap, jobject);
    451           if (o == NULL) {
    452             msg += "NULL";
    453           } else {
    454             StringAppendF(&msg, "%p", o);
    455           }
    456         } else if (ch == 'b') {  // jboolean (JNI-style)
    457           jboolean b = va_arg(ap, int);
    458           msg += (b ? "JNI_TRUE" : "JNI_FALSE");
    459         } else if (ch == 'c') {  // jclass
    460           jclass jc = va_arg(ap, jclass);
    461           mirror::Class* c = reinterpret_cast<mirror::Class*>(Thread::Current()->DecodeJObject(jc));
    462           if (c == NULL) {
    463             msg += "NULL";
    464           } else if (c == kInvalidIndirectRefObject || !Runtime::Current()->GetHeap()->IsHeapAddress(c)) {
    465             StringAppendF(&msg, "INVALID POINTER:%p", jc);
    466           } else if (!c->IsClass()) {
    467             msg += "INVALID NON-CLASS OBJECT OF TYPE:" + PrettyTypeOf(c);
    468           } else {
    469             msg += PrettyClass(c);
    470             if (!entry) {
    471               StringAppendF(&msg, " (%p)", jc);
    472             }
    473           }
    474         } else if (ch == 'f') {  // jfieldID
    475           jfieldID fid = va_arg(ap, jfieldID);
    476           mirror::ArtField* f = reinterpret_cast<mirror::ArtField*>(fid);
    477           msg += PrettyField(f);
    478           if (!entry) {
    479             StringAppendF(&msg, " (%p)", fid);
    480           }
    481         } else if (ch == 'z') {  // non-negative jsize
    482           // You might expect jsize to be size_t, but it's not; it's the same as jint.
    483           // We only treat this specially so we can do the non-negative check.
    484           // TODO: maybe this wasn't worth it?
    485           jint i = va_arg(ap, jint);
    486           StringAppendF(&msg, "%d", i);
    487         } else if (ch == 'm') {  // jmethodID
    488           jmethodID mid = va_arg(ap, jmethodID);
    489           mirror::ArtMethod* m = reinterpret_cast<mirror::ArtMethod*>(mid);
    490           msg += PrettyMethod(m);
    491           if (!entry) {
    492             StringAppendF(&msg, " (%p)", mid);
    493           }
    494         } else if (ch == 'p') {  // void* ("pointer")
    495           void* p = va_arg(ap, void*);
    496           if (p == NULL) {
    497             msg += "NULL";
    498           } else {
    499             StringAppendF(&msg, "(void*) %p", p);
    500           }
    501         } else if (ch == 'r') {  // jint (release mode)
    502           jint releaseMode = va_arg(ap, jint);
    503           if (releaseMode == 0) {
    504             msg += "0";
    505           } else if (releaseMode == JNI_ABORT) {
    506             msg += "JNI_ABORT";
    507           } else if (releaseMode == JNI_COMMIT) {
    508             msg += "JNI_COMMIT";
    509           } else {
    510             StringAppendF(&msg, "invalid release mode %d", releaseMode);
    511           }
    512         } else if (ch == 'u') {  // const char* (Modified UTF-8)
    513           const char* utf = va_arg(ap, const char*);
    514           if (utf == NULL) {
    515             msg += "NULL";
    516           } else {
    517             StringAppendF(&msg, "\"%s\"", utf);
    518           }
    519         } else if (ch == '.') {
    520           msg += "...";
    521         } else {
    522           JniAbortF(function_name_, "unknown trace format specifier: %c", ch);
    523           return;
    524         }
    525         if (*fmt) {
    526           StringAppendF(&msg, ", ");
    527         }
    528       }
    529       va_end(ap);
    530 
    531       if ((flags_ & kFlag_ForceTrace) != 0) {
    532         LOG(INFO) << "JNI: call to " << function_name_ << "(" << msg << ")";
    533       } else if (entry) {
    534         if (has_method_) {
    535           std::string methodName(PrettyMethod(traceMethod, false));
    536           LOG(INFO) << "JNI: " << methodName << " -> " << function_name_ << "(" << msg << ")";
    537           indent_ = methodName.size() + 1;
    538         } else {
    539           LOG(INFO) << "JNI: -> " << function_name_ << "(" << msg << ")";
    540           indent_ = 0;
    541         }
    542       } else {
    543         LOG(INFO) << StringPrintf("JNI: %*s<- %s returned %s", indent_, "", function_name_, msg.c_str());
    544       }
    545     }
    546 
    547     // We always do the thorough checks on entry, and never on exit...
    548     if (entry) {
    549       va_start(ap, fmt0);
    550       for (const char* fmt = fmt0; *fmt; ++fmt) {
    551         char ch = *fmt;
    552         if (ch == 'a') {
    553           CheckArray(va_arg(ap, jarray));
    554         } else if (ch == 'c') {
    555           CheckInstance(kClass, va_arg(ap, jclass));
    556         } else if (ch == 'L') {
    557           CheckObject(va_arg(ap, jobject));
    558         } else if (ch == 'r') {
    559           CheckReleaseMode(va_arg(ap, jint));
    560         } else if (ch == 's') {
    561           CheckInstance(kString, va_arg(ap, jstring));
    562         } else if (ch == 'u') {
    563           if ((flags_ & kFlag_Release) != 0) {
    564             CheckNonNull(va_arg(ap, const char*));
    565           } else {
    566             bool nullable = ((flags_ & kFlag_NullableUtf) != 0);
    567             CheckUtfString(va_arg(ap, const char*), nullable);
    568           }
    569         } else if (ch == 'z') {
    570           CheckLengthPositive(va_arg(ap, jsize));
    571         } else if (strchr("BCISZbfmpEv", ch) != NULL) {
    572           va_arg(ap, uint32_t);  // Skip this argument.
    573         } else if (ch == 'D' || ch == 'F') {
    574           va_arg(ap, double);  // Skip this argument.
    575         } else if (ch == 'J') {
    576           va_arg(ap, uint64_t);  // Skip this argument.
    577         } else if (ch == '.') {
    578         } else {
    579           LOG(FATAL) << "Unknown check format specifier: " << ch;
    580         }
    581       }
    582       va_end(ap);
    583     }
    584   }
    585 
    586   enum InstanceKind {
    587     kClass,
    588     kDirectByteBuffer,
    589     kObject,
    590     kString,
    591     kThrowable,
    592   };
    593 
    594   /*
    595    * Verify that "jobj" is a valid non-NULL object reference, and points to
    596    * an instance of expectedClass.
    597    *
    598    * Because we're looking at an object on the GC heap, we have to switch
    599    * to "running" mode before doing the checks.
    600    */
    601   bool CheckInstance(InstanceKind kind, jobject java_object)
    602       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    603     const char* what = NULL;
    604     switch (kind) {
    605     case kClass:
    606       what = "jclass";
    607       break;
    608     case kDirectByteBuffer:
    609       what = "direct ByteBuffer";
    610       break;
    611     case kObject:
    612       what = "jobject";
    613       break;
    614     case kString:
    615       what = "jstring";
    616       break;
    617     case kThrowable:
    618       what = "jthrowable";
    619       break;
    620     default:
    621       LOG(FATAL) << "Unknown kind " << static_cast<int>(kind);
    622     }
    623 
    624     if (java_object == NULL) {
    625       JniAbortF(function_name_, "%s received null %s", function_name_, what);
    626       return false;
    627     }
    628 
    629     mirror::Object* obj = soa_.Decode<mirror::Object*>(java_object);
    630     if (!Runtime::Current()->GetHeap()->IsHeapAddress(obj)) {
    631       Runtime::Current()->GetHeap()->DumpSpaces();
    632       JniAbortF(function_name_, "%s is an invalid %s: %p (%p)",
    633                 what, ToStr<IndirectRefKind>(GetIndirectRefKind(java_object)).c_str(), java_object, obj);
    634       return false;
    635     }
    636 
    637     bool okay = true;
    638     switch (kind) {
    639     case kClass:
    640       okay = obj->IsClass();
    641       break;
    642     case kDirectByteBuffer:
    643       UNIMPLEMENTED(FATAL);
    644       break;
    645     case kString:
    646       okay = obj->GetClass()->IsStringClass();
    647       break;
    648     case kThrowable:
    649       okay = obj->GetClass()->IsThrowableClass();
    650       break;
    651     case kObject:
    652       break;
    653     }
    654     if (!okay) {
    655       JniAbortF(function_name_, "%s has wrong type: %s", what, PrettyTypeOf(obj).c_str());
    656       return false;
    657     }
    658 
    659     return true;
    660   }
    661 
    662  private:
    663   // Set "has_method" to true if we have a valid thread with a method pointer.
    664   // We won't have one before attaching a thread, after detaching a thread, or
    665   // when shutting down the runtime.
    666   void Init(int flags, const char* functionName, bool has_method) {
    667     flags_ = flags;
    668     function_name_ = functionName;
    669     has_method_ = has_method;
    670   }
    671 
    672   /*
    673    * Verify that "array" is non-NULL and points to an Array object.
    674    *
    675    * Since we're dealing with objects, switch to "running" mode.
    676    */
    677   void CheckArray(jarray java_array) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    678     if (java_array == NULL) {
    679       JniAbortF(function_name_, "jarray was NULL");
    680       return;
    681     }
    682 
    683     mirror::Array* a = soa_.Decode<mirror::Array*>(java_array);
    684     if (!Runtime::Current()->GetHeap()->IsHeapAddress(a)) {
    685       Runtime::Current()->GetHeap()->DumpSpaces();
    686       JniAbortF(function_name_, "jarray is an invalid %s: %p (%p)",
    687                 ToStr<IndirectRefKind>(GetIndirectRefKind(java_array)).c_str(), java_array, a);
    688     } else if (!a->IsArrayInstance()) {
    689       JniAbortF(function_name_, "jarray argument has non-array type: %s", PrettyTypeOf(a).c_str());
    690     }
    691   }
    692 
    693   void CheckLengthPositive(jsize length) {
    694     if (length < 0) {
    695       JniAbortF(function_name_, "negative jsize: %d", length);
    696     }
    697   }
    698 
    699   mirror::ArtField* CheckFieldID(jfieldID fid) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    700     if (fid == NULL) {
    701       JniAbortF(function_name_, "jfieldID was NULL");
    702       return NULL;
    703     }
    704     mirror::ArtField* f = soa_.DecodeField(fid);
    705     if (!Runtime::Current()->GetHeap()->IsHeapAddress(f) || !f->IsArtField()) {
    706       Runtime::Current()->GetHeap()->DumpSpaces();
    707       JniAbortF(function_name_, "invalid jfieldID: %p", fid);
    708       return NULL;
    709     }
    710     return f;
    711   }
    712 
    713   mirror::ArtMethod* CheckMethodID(jmethodID mid) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    714     if (mid == NULL) {
    715       JniAbortF(function_name_, "jmethodID was NULL");
    716       return NULL;
    717     }
    718     mirror::ArtMethod* m = soa_.DecodeMethod(mid);
    719     if (!Runtime::Current()->GetHeap()->IsHeapAddress(m) || !m->IsArtMethod()) {
    720       Runtime::Current()->GetHeap()->DumpSpaces();
    721       JniAbortF(function_name_, "invalid jmethodID: %p", mid);
    722       return NULL;
    723     }
    724     return m;
    725   }
    726 
    727   /*
    728    * Verify that "jobj" is a valid object, and that it's an object that JNI
    729    * is allowed to know about.  We allow NULL references.
    730    *
    731    * Switches to "running" mode before performing checks.
    732    */
    733   void CheckObject(jobject java_object)
    734       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    735     if (java_object == NULL) {
    736       return;
    737     }
    738 
    739     mirror::Object* o = soa_.Decode<mirror::Object*>(java_object);
    740     if (!Runtime::Current()->GetHeap()->IsHeapAddress(o)) {
    741       Runtime::Current()->GetHeap()->DumpSpaces();
    742       // TODO: when we remove work_around_app_jni_bugs, this should be impossible.
    743       JniAbortF(function_name_, "native code passing in reference to invalid %s: %p",
    744                 ToStr<IndirectRefKind>(GetIndirectRefKind(java_object)).c_str(), java_object);
    745     }
    746   }
    747 
    748   /*
    749    * Verify that the "mode" argument passed to a primitive array Release
    750    * function is one of the valid values.
    751    */
    752   void CheckReleaseMode(jint mode) {
    753     if (mode != 0 && mode != JNI_COMMIT && mode != JNI_ABORT) {
    754       JniAbortF(function_name_, "unknown value for release mode: %d", mode);
    755     }
    756   }
    757 
    758   void CheckThread(int flags) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    759     Thread* self = Thread::Current();
    760     if (self == NULL) {
    761       JniAbortF(function_name_, "a thread (tid %d) is making JNI calls without being attached", GetTid());
    762       return;
    763     }
    764 
    765     // Get the *correct* JNIEnv by going through our TLS pointer.
    766     JNIEnvExt* threadEnv = self->GetJniEnv();
    767 
    768     // Verify that the current thread is (a) attached and (b) associated with
    769     // this particular instance of JNIEnv.
    770     if (soa_.Env() != threadEnv) {
    771       if (soa_.Vm()->work_around_app_jni_bugs) {
    772         // If we're keeping broken code limping along, we need to suppress the abort...
    773         LOG(ERROR) << "APP BUG DETECTED: thread " << *self << " using JNIEnv* from thread " << *soa_.Self();
    774       } else {
    775         JniAbortF(function_name_, "thread %s using JNIEnv* from thread %s",
    776                   ToStr<Thread>(*self).c_str(), ToStr<Thread>(*soa_.Self()).c_str());
    777         return;
    778       }
    779     }
    780 
    781     // Verify that, if this thread previously made a critical "get" call, we
    782     // do the corresponding "release" call before we try anything else.
    783     switch (flags & kFlag_CritMask) {
    784     case kFlag_CritOkay:    // okay to call this method
    785       break;
    786     case kFlag_CritBad:     // not okay to call
    787       if (threadEnv->critical) {
    788         JniAbortF(function_name_, "thread %s using JNI after critical get", ToStr<Thread>(*self).c_str());
    789         return;
    790       }
    791       break;
    792     case kFlag_CritGet:     // this is a "get" call
    793       // Don't check here; we allow nested gets.
    794       threadEnv->critical++;
    795       break;
    796     case kFlag_CritRelease:  // this is a "release" call
    797       threadEnv->critical--;
    798       if (threadEnv->critical < 0) {
    799         JniAbortF(function_name_, "thread %s called too many critical releases", ToStr<Thread>(*self).c_str());
    800         return;
    801       }
    802       break;
    803     default:
    804       LOG(FATAL) << "Bad flags (internal error): " << flags;
    805     }
    806 
    807     // Verify that, if an exception has been raised, the native code doesn't
    808     // make any JNI calls other than the Exception* methods.
    809     if ((flags & kFlag_ExcepOkay) == 0 && self->IsExceptionPending()) {
    810       ThrowLocation throw_location;
    811       mirror::Throwable* exception = self->GetException(&throw_location);
    812       std::string type(PrettyTypeOf(exception));
    813       JniAbortF(function_name_, "JNI %s called with pending exception '%s' thrown in %s",
    814                 function_name_, type.c_str(), throw_location.Dump().c_str());
    815       return;
    816     }
    817   }
    818 
    819   // Verifies that "bytes" points to valid Modified UTF-8 data.
    820   void CheckUtfString(const char* bytes, bool nullable) {
    821     if (bytes == NULL) {
    822       if (!nullable) {
    823         JniAbortF(function_name_, "non-nullable const char* was NULL");
    824         return;
    825       }
    826       return;
    827     }
    828 
    829     const char* errorKind = NULL;
    830     uint8_t utf8 = CheckUtfBytes(bytes, &errorKind);
    831     if (errorKind != NULL) {
    832       JniAbortF(function_name_,
    833                 "input is not valid Modified UTF-8: illegal %s byte %#x\n"
    834                 "    string: '%s'", errorKind, utf8, bytes);
    835       return;
    836     }
    837   }
    838 
    839   static uint8_t CheckUtfBytes(const char* bytes, const char** errorKind) {
    840     while (*bytes != '\0') {
    841       uint8_t utf8 = *(bytes++);
    842       // Switch on the high four bits.
    843       switch (utf8 >> 4) {
    844       case 0x00:
    845       case 0x01:
    846       case 0x02:
    847       case 0x03:
    848       case 0x04:
    849       case 0x05:
    850       case 0x06:
    851       case 0x07:
    852         // Bit pattern 0xxx. No need for any extra bytes.
    853         break;
    854       case 0x08:
    855       case 0x09:
    856       case 0x0a:
    857       case 0x0b:
    858       case 0x0f:
    859         /*
    860          * Bit pattern 10xx or 1111, which are illegal start bytes.
    861          * Note: 1111 is valid for normal UTF-8, but not the
    862          * Modified UTF-8 used here.
    863          */
    864         *errorKind = "start";
    865         return utf8;
    866       case 0x0e:
    867         // Bit pattern 1110, so there are two additional bytes.
    868         utf8 = *(bytes++);
    869         if ((utf8 & 0xc0) != 0x80) {
    870           *errorKind = "continuation";
    871           return utf8;
    872         }
    873         // Fall through to take care of the final byte.
    874       case 0x0c:
    875       case 0x0d:
    876         // Bit pattern 110x, so there is one additional byte.
    877         utf8 = *(bytes++);
    878         if ((utf8 & 0xc0) != 0x80) {
    879           *errorKind = "continuation";
    880           return utf8;
    881         }
    882         break;
    883       }
    884     }
    885     return 0;
    886   }
    887 
    888   const ScopedObjectAccess soa_;
    889   const char* function_name_;
    890   int flags_;
    891   bool has_method_;
    892   int indent_;
    893 
    894   DISALLOW_COPY_AND_ASSIGN(ScopedCheck);
    895 };
    896 
    897 #define CHECK_JNI_ENTRY(flags, types, args...) \
    898   ScopedCheck sc(env, flags, __FUNCTION__); \
    899   sc.Check(true, types, ##args)
    900 
    901 #define CHECK_JNI_EXIT(type, exp) ({ \
    902     auto _rc = (exp); \
    903   sc.Check(false, type, _rc); \
    904   _rc; })
    905 #define CHECK_JNI_EXIT_VOID() \
    906   sc.Check(false, "V")
    907 
    908 /*
    909  * ===========================================================================
    910  *      Guarded arrays
    911  * ===========================================================================
    912  */
    913 
    914 #define kGuardLen       512         /* must be multiple of 2 */
    915 #define kGuardPattern   0xd5e3      /* uncommon values; d5e3d5e3 invalid addr */
    916 #define kGuardMagic     0xffd5aa96
    917 
    918 /* this gets tucked in at the start of the buffer; struct size must be even */
    919 struct GuardedCopy {
    920   uint32_t magic;
    921   uLong adler;
    922   size_t original_length;
    923   const void* original_ptr;
    924 
    925   /* find the GuardedCopy given the pointer into the "live" data */
    926   static inline const GuardedCopy* FromData(const void* dataBuf) {
    927     return reinterpret_cast<const GuardedCopy*>(ActualBuffer(dataBuf));
    928   }
    929 
    930   /*
    931    * Create an over-sized buffer to hold the contents of "buf".  Copy it in,
    932    * filling in the area around it with guard data.
    933    *
    934    * We use a 16-bit pattern to make a rogue memset less likely to elude us.
    935    */
    936   static void* Create(const void* buf, size_t len, bool modOkay) {
    937     size_t newLen = ActualLength(len);
    938     uint8_t* newBuf = DebugAlloc(newLen);
    939 
    940     // Fill it in with a pattern.
    941     uint16_t* pat = reinterpret_cast<uint16_t*>(newBuf);
    942     for (size_t i = 0; i < newLen / 2; i++) {
    943       *pat++ = kGuardPattern;
    944     }
    945 
    946     // Copy the data in; note "len" could be zero.
    947     memcpy(newBuf + kGuardLen / 2, buf, len);
    948 
    949     // If modification is not expected, grab a checksum.
    950     uLong adler = 0;
    951     if (!modOkay) {
    952       adler = adler32(0L, Z_NULL, 0);
    953       adler = adler32(adler, reinterpret_cast<const Bytef*>(buf), len);
    954       *reinterpret_cast<uLong*>(newBuf) = adler;
    955     }
    956 
    957     GuardedCopy* pExtra = reinterpret_cast<GuardedCopy*>(newBuf);
    958     pExtra->magic = kGuardMagic;
    959     pExtra->adler = adler;
    960     pExtra->original_ptr = buf;
    961     pExtra->original_length = len;
    962 
    963     return newBuf + kGuardLen / 2;
    964   }
    965 
    966   /*
    967    * Free up the guard buffer, scrub it, and return the original pointer.
    968    */
    969   static void* Destroy(void* dataBuf) {
    970     const GuardedCopy* pExtra = GuardedCopy::FromData(dataBuf);
    971     void* original_ptr = const_cast<void*>(pExtra->original_ptr);
    972     size_t len = pExtra->original_length;
    973     DebugFree(dataBuf, len);
    974     return original_ptr;
    975   }
    976 
    977   /*
    978    * Verify the guard area and, if "modOkay" is false, that the data itself
    979    * has not been altered.
    980    *
    981    * The caller has already checked that "dataBuf" is non-NULL.
    982    */
    983   static void Check(const char* functionName, const void* dataBuf, bool modOkay) {
    984     static const uint32_t kMagicCmp = kGuardMagic;
    985     const uint8_t* fullBuf = ActualBuffer(dataBuf);
    986     const GuardedCopy* pExtra = GuardedCopy::FromData(dataBuf);
    987 
    988     // Before we do anything with "pExtra", check the magic number.  We
    989     // do the check with memcmp rather than "==" in case the pointer is
    990     // unaligned.  If it points to completely bogus memory we're going
    991     // to crash, but there's no easy way around that.
    992     if (memcmp(&pExtra->magic, &kMagicCmp, 4) != 0) {
    993       uint8_t buf[4];
    994       memcpy(buf, &pExtra->magic, 4);
    995       JniAbortF(functionName,
    996           "guard magic does not match (found 0x%02x%02x%02x%02x) -- incorrect data pointer %p?",
    997           buf[3], buf[2], buf[1], buf[0], dataBuf);  // Assumes little-endian.
    998     }
    999 
   1000     size_t len = pExtra->original_length;
   1001 
   1002     // Check bottom half of guard; skip over optional checksum storage.
   1003     const uint16_t* pat = reinterpret_cast<const uint16_t*>(fullBuf);
   1004     for (size_t i = sizeof(GuardedCopy) / 2; i < (kGuardLen / 2 - sizeof(GuardedCopy)) / 2; i++) {
   1005       if (pat[i] != kGuardPattern) {
   1006         JniAbortF(functionName, "guard pattern(1) disturbed at %p +%d", fullBuf, i*2);
   1007       }
   1008     }
   1009 
   1010     int offset = kGuardLen / 2 + len;
   1011     if (offset & 0x01) {
   1012       // Odd byte; expected value depends on endian.
   1013       const uint16_t patSample = kGuardPattern;
   1014       uint8_t expected_byte = reinterpret_cast<const uint8_t*>(&patSample)[1];
   1015       if (fullBuf[offset] != expected_byte) {
   1016         JniAbortF(functionName, "guard pattern disturbed in odd byte after %p +%d 0x%02x 0x%02x",
   1017                   fullBuf, offset, fullBuf[offset], expected_byte);
   1018       }
   1019       offset++;
   1020     }
   1021 
   1022     // Check top half of guard.
   1023     pat = reinterpret_cast<const uint16_t*>(fullBuf + offset);
   1024     for (size_t i = 0; i < kGuardLen / 4; i++) {
   1025       if (pat[i] != kGuardPattern) {
   1026         JniAbortF(functionName, "guard pattern(2) disturbed at %p +%d", fullBuf, offset + i*2);
   1027       }
   1028     }
   1029 
   1030     // If modification is not expected, verify checksum.  Strictly speaking
   1031     // this is wrong: if we told the client that we made a copy, there's no
   1032     // reason they can't alter the buffer.
   1033     if (!modOkay) {
   1034       uLong adler = adler32(0L, Z_NULL, 0);
   1035       adler = adler32(adler, (const Bytef*)dataBuf, len);
   1036       if (pExtra->adler != adler) {
   1037         JniAbortF(functionName, "buffer modified (0x%08lx vs 0x%08lx) at address %p",
   1038                   pExtra->adler, adler, dataBuf);
   1039       }
   1040     }
   1041   }
   1042 
   1043  private:
   1044   static uint8_t* DebugAlloc(size_t len) {
   1045     void* result = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0);
   1046     if (result == MAP_FAILED) {
   1047       PLOG(FATAL) << "GuardedCopy::create mmap(" << len << ") failed";
   1048     }
   1049     return reinterpret_cast<uint8_t*>(result);
   1050   }
   1051 
   1052   static void DebugFree(void* dataBuf, size_t len) {
   1053     uint8_t* fullBuf = ActualBuffer(dataBuf);
   1054     size_t totalByteCount = ActualLength(len);
   1055     // TODO: we could mprotect instead, and keep the allocation around for a while.
   1056     // This would be even more expensive, but it might catch more errors.
   1057     // if (mprotect(fullBuf, totalByteCount, PROT_NONE) != 0) {
   1058     //     PLOG(WARNING) << "mprotect(PROT_NONE) failed";
   1059     // }
   1060     if (munmap(fullBuf, totalByteCount) != 0) {
   1061       PLOG(FATAL) << "munmap(" << reinterpret_cast<void*>(fullBuf) << ", " << totalByteCount << ") failed";
   1062     }
   1063   }
   1064 
   1065   static const uint8_t* ActualBuffer(const void* dataBuf) {
   1066     return reinterpret_cast<const uint8_t*>(dataBuf) - kGuardLen / 2;
   1067   }
   1068 
   1069   static uint8_t* ActualBuffer(void* dataBuf) {
   1070     return reinterpret_cast<uint8_t*>(dataBuf) - kGuardLen / 2;
   1071   }
   1072 
   1073   // Underlying length of a user allocation of 'length' bytes.
   1074   static size_t ActualLength(size_t length) {
   1075     return (length + kGuardLen + 1) & ~0x01;
   1076   }
   1077 };
   1078 
   1079 /*
   1080  * Create a guarded copy of a primitive array.  Modifications to the copied
   1081  * data are allowed.  Returns a pointer to the copied data.
   1082  */
   1083 static void* CreateGuardedPACopy(JNIEnv* env, const jarray java_array, jboolean* isCopy) {
   1084   ScopedObjectAccess soa(env);
   1085 
   1086   mirror::Array* a = soa.Decode<mirror::Array*>(java_array);
   1087   size_t component_size = a->GetClass()->GetComponentSize();
   1088   size_t byte_count = a->GetLength() * component_size;
   1089   void* result = GuardedCopy::Create(a->GetRawData(component_size), byte_count, true);
   1090   if (isCopy != NULL) {
   1091     *isCopy = JNI_TRUE;
   1092   }
   1093   return result;
   1094 }
   1095 
   1096 /*
   1097  * Perform the array "release" operation, which may or may not copy data
   1098  * back into the managed heap, and may or may not release the underlying storage.
   1099  */
   1100 static void ReleaseGuardedPACopy(JNIEnv* env, jarray java_array, void* dataBuf, int mode) {
   1101   if (reinterpret_cast<uintptr_t>(dataBuf) == kNoCopyMagic) {
   1102     return;
   1103   }
   1104 
   1105   ScopedObjectAccess soa(env);
   1106   mirror::Array* a = soa.Decode<mirror::Array*>(java_array);
   1107 
   1108   GuardedCopy::Check(__FUNCTION__, dataBuf, true);
   1109 
   1110   if (mode != JNI_ABORT) {
   1111     size_t len = GuardedCopy::FromData(dataBuf)->original_length;
   1112     memcpy(a->GetRawData(a->GetClass()->GetComponentSize()), dataBuf, len);
   1113   }
   1114   if (mode != JNI_COMMIT) {
   1115     GuardedCopy::Destroy(dataBuf);
   1116   }
   1117 }
   1118 
   1119 /*
   1120  * ===========================================================================
   1121  *      JNI functions
   1122  * ===========================================================================
   1123  */
   1124 
   1125 class CheckJNI {
   1126  public:
   1127   static jint GetVersion(JNIEnv* env) {
   1128     CHECK_JNI_ENTRY(kFlag_Default, "E", env);
   1129     return CHECK_JNI_EXIT("I", baseEnv(env)->GetVersion(env));
   1130   }
   1131 
   1132   static jclass DefineClass(JNIEnv* env, const char* name, jobject loader, const jbyte* buf, jsize bufLen) {
   1133     CHECK_JNI_ENTRY(kFlag_Default, "EuLpz", env, name, loader, buf, bufLen);
   1134     sc.CheckClassName(name);
   1135     return CHECK_JNI_EXIT("c", baseEnv(env)->DefineClass(env, name, loader, buf, bufLen));
   1136   }
   1137 
   1138   static jclass FindClass(JNIEnv* env, const char* name) {
   1139     CHECK_JNI_ENTRY(kFlag_Default, "Eu", env, name);
   1140     sc.CheckClassName(name);
   1141     return CHECK_JNI_EXIT("c", baseEnv(env)->FindClass(env, name));
   1142   }
   1143 
   1144   static jclass GetSuperclass(JNIEnv* env, jclass c) {
   1145     CHECK_JNI_ENTRY(kFlag_Default, "Ec", env, c);
   1146     return CHECK_JNI_EXIT("c", baseEnv(env)->GetSuperclass(env, c));
   1147   }
   1148 
   1149   static jboolean IsAssignableFrom(JNIEnv* env, jclass c1, jclass c2) {
   1150     CHECK_JNI_ENTRY(kFlag_Default, "Ecc", env, c1, c2);
   1151     return CHECK_JNI_EXIT("b", baseEnv(env)->IsAssignableFrom(env, c1, c2));
   1152   }
   1153 
   1154   static jmethodID FromReflectedMethod(JNIEnv* env, jobject method) {
   1155     CHECK_JNI_ENTRY(kFlag_Default, "EL", env, method);
   1156     // TODO: check that 'field' is a java.lang.reflect.Method.
   1157     return CHECK_JNI_EXIT("m", baseEnv(env)->FromReflectedMethod(env, method));
   1158   }
   1159 
   1160   static jfieldID FromReflectedField(JNIEnv* env, jobject field) {
   1161     CHECK_JNI_ENTRY(kFlag_Default, "EL", env, field);
   1162     // TODO: check that 'field' is a java.lang.reflect.Field.
   1163     return CHECK_JNI_EXIT("f", baseEnv(env)->FromReflectedField(env, field));
   1164   }
   1165 
   1166   static jobject ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID mid, jboolean isStatic) {
   1167     CHECK_JNI_ENTRY(kFlag_Default, "Ecmb", env, cls, mid, isStatic);
   1168     return CHECK_JNI_EXIT("L", baseEnv(env)->ToReflectedMethod(env, cls, mid, isStatic));
   1169   }
   1170 
   1171   static jobject ToReflectedField(JNIEnv* env, jclass cls, jfieldID fid, jboolean isStatic) {
   1172     CHECK_JNI_ENTRY(kFlag_Default, "Ecfb", env, cls, fid, isStatic);
   1173     return CHECK_JNI_EXIT("L", baseEnv(env)->ToReflectedField(env, cls, fid, isStatic));
   1174   }
   1175 
   1176   static jint Throw(JNIEnv* env, jthrowable obj) {
   1177     CHECK_JNI_ENTRY(kFlag_Default, "EL", env, obj);
   1178     // TODO: check that 'obj' is a java.lang.Throwable.
   1179     return CHECK_JNI_EXIT("I", baseEnv(env)->Throw(env, obj));
   1180   }
   1181 
   1182   static jint ThrowNew(JNIEnv* env, jclass c, const char* message) {
   1183     CHECK_JNI_ENTRY(kFlag_NullableUtf, "Ecu", env, c, message);
   1184     return CHECK_JNI_EXIT("I", baseEnv(env)->ThrowNew(env, c, message));
   1185   }
   1186 
   1187   static jthrowable ExceptionOccurred(JNIEnv* env) {
   1188     CHECK_JNI_ENTRY(kFlag_ExcepOkay, "E", env);
   1189     return CHECK_JNI_EXIT("L", baseEnv(env)->ExceptionOccurred(env));
   1190   }
   1191 
   1192   static void ExceptionDescribe(JNIEnv* env) {
   1193     CHECK_JNI_ENTRY(kFlag_ExcepOkay, "E", env);
   1194     baseEnv(env)->ExceptionDescribe(env);
   1195     CHECK_JNI_EXIT_VOID();
   1196   }
   1197 
   1198   static void ExceptionClear(JNIEnv* env) {
   1199     CHECK_JNI_ENTRY(kFlag_ExcepOkay, "E", env);
   1200     baseEnv(env)->ExceptionClear(env);
   1201     CHECK_JNI_EXIT_VOID();
   1202   }
   1203 
   1204   static void FatalError(JNIEnv* env, const char* msg) {
   1205     // The JNI specification doesn't say it's okay to call FatalError with a pending exception,
   1206     // but you're about to abort anyway, and it's quite likely that you have a pending exception,
   1207     // and it's not unimaginable that you don't know that you do. So we allow it.
   1208     CHECK_JNI_ENTRY(kFlag_ExcepOkay | kFlag_NullableUtf, "Eu", env, msg);
   1209     baseEnv(env)->FatalError(env, msg);
   1210     CHECK_JNI_EXIT_VOID();
   1211   }
   1212 
   1213   static jint PushLocalFrame(JNIEnv* env, jint capacity) {
   1214     CHECK_JNI_ENTRY(kFlag_Default | kFlag_ExcepOkay, "EI", env, capacity);
   1215     return CHECK_JNI_EXIT("I", baseEnv(env)->PushLocalFrame(env, capacity));
   1216   }
   1217 
   1218   static jobject PopLocalFrame(JNIEnv* env, jobject res) {
   1219     CHECK_JNI_ENTRY(kFlag_Default | kFlag_ExcepOkay, "EL", env, res);
   1220     return CHECK_JNI_EXIT("L", baseEnv(env)->PopLocalFrame(env, res));
   1221   }
   1222 
   1223   static jobject NewGlobalRef(JNIEnv* env, jobject obj) {
   1224     CHECK_JNI_ENTRY(kFlag_Default, "EL", env, obj);
   1225     return CHECK_JNI_EXIT("L", baseEnv(env)->NewGlobalRef(env, obj));
   1226   }
   1227 
   1228   static jobject NewLocalRef(JNIEnv* env, jobject ref) {
   1229     CHECK_JNI_ENTRY(kFlag_Default, "EL", env, ref);
   1230     return CHECK_JNI_EXIT("L", baseEnv(env)->NewLocalRef(env, ref));
   1231   }
   1232 
   1233   static void DeleteGlobalRef(JNIEnv* env, jobject globalRef) {
   1234     CHECK_JNI_ENTRY(kFlag_Default | kFlag_ExcepOkay, "EL", env, globalRef);
   1235     if (globalRef != NULL && GetIndirectRefKind(globalRef) != kGlobal) {
   1236       JniAbortF(__FUNCTION__, "DeleteGlobalRef on %s: %p",
   1237                 ToStr<IndirectRefKind>(GetIndirectRefKind(globalRef)).c_str(), globalRef);
   1238     } else {
   1239       baseEnv(env)->DeleteGlobalRef(env, globalRef);
   1240       CHECK_JNI_EXIT_VOID();
   1241     }
   1242   }
   1243 
   1244   static void DeleteWeakGlobalRef(JNIEnv* env, jweak weakGlobalRef) {
   1245     CHECK_JNI_ENTRY(kFlag_Default | kFlag_ExcepOkay, "EL", env, weakGlobalRef);
   1246     if (weakGlobalRef != NULL && GetIndirectRefKind(weakGlobalRef) != kWeakGlobal) {
   1247       JniAbortF(__FUNCTION__, "DeleteWeakGlobalRef on %s: %p",
   1248                 ToStr<IndirectRefKind>(GetIndirectRefKind(weakGlobalRef)).c_str(), weakGlobalRef);
   1249     } else {
   1250       baseEnv(env)->DeleteWeakGlobalRef(env, weakGlobalRef);
   1251       CHECK_JNI_EXIT_VOID();
   1252     }
   1253   }
   1254 
   1255   static void DeleteLocalRef(JNIEnv* env, jobject localRef) {
   1256     CHECK_JNI_ENTRY(kFlag_Default | kFlag_ExcepOkay, "EL", env, localRef);
   1257     if (localRef != NULL && GetIndirectRefKind(localRef) != kLocal && !IsSirtLocalRef(env, localRef)) {
   1258       JniAbortF(__FUNCTION__, "DeleteLocalRef on %s: %p",
   1259                 ToStr<IndirectRefKind>(GetIndirectRefKind(localRef)).c_str(), localRef);
   1260     } else {
   1261       baseEnv(env)->DeleteLocalRef(env, localRef);
   1262       CHECK_JNI_EXIT_VOID();
   1263     }
   1264   }
   1265 
   1266   static jint EnsureLocalCapacity(JNIEnv *env, jint capacity) {
   1267     CHECK_JNI_ENTRY(kFlag_Default, "EI", env, capacity);
   1268     return CHECK_JNI_EXIT("I", baseEnv(env)->EnsureLocalCapacity(env, capacity));
   1269   }
   1270 
   1271   static jboolean IsSameObject(JNIEnv* env, jobject ref1, jobject ref2) {
   1272     CHECK_JNI_ENTRY(kFlag_Default, "ELL", env, ref1, ref2);
   1273     return CHECK_JNI_EXIT("b", baseEnv(env)->IsSameObject(env, ref1, ref2));
   1274   }
   1275 
   1276   static jobject AllocObject(JNIEnv* env, jclass c) {
   1277     CHECK_JNI_ENTRY(kFlag_Default, "Ec", env, c);
   1278     return CHECK_JNI_EXIT("L", baseEnv(env)->AllocObject(env, c));
   1279   }
   1280 
   1281   static jobject NewObject(JNIEnv* env, jclass c, jmethodID mid, ...) {
   1282     CHECK_JNI_ENTRY(kFlag_Default, "Ecm.", env, c, mid);
   1283     va_list args;
   1284     va_start(args, mid);
   1285     jobject result = baseEnv(env)->NewObjectV(env, c, mid, args);
   1286     va_end(args);
   1287     return CHECK_JNI_EXIT("L", result);
   1288   }
   1289 
   1290   static jobject NewObjectV(JNIEnv* env, jclass c, jmethodID mid, va_list args) {
   1291     CHECK_JNI_ENTRY(kFlag_Default, "Ecm.", env, c, mid);
   1292     return CHECK_JNI_EXIT("L", baseEnv(env)->NewObjectV(env, c, mid, args));
   1293   }
   1294 
   1295   static jobject NewObjectA(JNIEnv* env, jclass c, jmethodID mid, jvalue* args) {
   1296     CHECK_JNI_ENTRY(kFlag_Default, "Ecm.", env, c, mid);
   1297     return CHECK_JNI_EXIT("L", baseEnv(env)->NewObjectA(env, c, mid, args));
   1298   }
   1299 
   1300   static jclass GetObjectClass(JNIEnv* env, jobject obj) {
   1301     CHECK_JNI_ENTRY(kFlag_Default, "EL", env, obj);
   1302     return CHECK_JNI_EXIT("c", baseEnv(env)->GetObjectClass(env, obj));
   1303   }
   1304 
   1305   static jboolean IsInstanceOf(JNIEnv* env, jobject obj, jclass c) {
   1306     CHECK_JNI_ENTRY(kFlag_Default, "ELc", env, obj, c);
   1307     return CHECK_JNI_EXIT("b", baseEnv(env)->IsInstanceOf(env, obj, c));
   1308   }
   1309 
   1310   static jmethodID GetMethodID(JNIEnv* env, jclass c, const char* name, const char* sig) {
   1311     CHECK_JNI_ENTRY(kFlag_Default, "Ecuu", env, c, name, sig);
   1312     return CHECK_JNI_EXIT("m", baseEnv(env)->GetMethodID(env, c, name, sig));
   1313   }
   1314 
   1315   static jfieldID GetFieldID(JNIEnv* env, jclass c, const char* name, const char* sig) {
   1316     CHECK_JNI_ENTRY(kFlag_Default, "Ecuu", env, c, name, sig);
   1317     return CHECK_JNI_EXIT("f", baseEnv(env)->GetFieldID(env, c, name, sig));
   1318   }
   1319 
   1320   static jmethodID GetStaticMethodID(JNIEnv* env, jclass c, const char* name, const char* sig) {
   1321     CHECK_JNI_ENTRY(kFlag_Default, "Ecuu", env, c, name, sig);
   1322     return CHECK_JNI_EXIT("m", baseEnv(env)->GetStaticMethodID(env, c, name, sig));
   1323   }
   1324 
   1325   static jfieldID GetStaticFieldID(JNIEnv* env, jclass c, const char* name, const char* sig) {
   1326     CHECK_JNI_ENTRY(kFlag_Default, "Ecuu", env, c, name, sig);
   1327     return CHECK_JNI_EXIT("f", baseEnv(env)->GetStaticFieldID(env, c, name, sig));
   1328   }
   1329 
   1330 #define FIELD_ACCESSORS(_ctype, _jname, _type) \
   1331     static _ctype GetStatic##_jname##Field(JNIEnv* env, jclass c, jfieldID fid) { \
   1332         CHECK_JNI_ENTRY(kFlag_Default, "Ecf", env, c, fid); \
   1333         sc.CheckStaticFieldID(c, fid); \
   1334         return CHECK_JNI_EXIT(_type, baseEnv(env)->GetStatic##_jname##Field(env, c, fid)); \
   1335     } \
   1336     static _ctype Get##_jname##Field(JNIEnv* env, jobject obj, jfieldID fid) { \
   1337         CHECK_JNI_ENTRY(kFlag_Default, "ELf", env, obj, fid); \
   1338         sc.CheckInstanceFieldID(obj, fid); \
   1339         return CHECK_JNI_EXIT(_type, baseEnv(env)->Get##_jname##Field(env, obj, fid)); \
   1340     } \
   1341     static void SetStatic##_jname##Field(JNIEnv* env, jclass c, jfieldID fid, _ctype value) { \
   1342         CHECK_JNI_ENTRY(kFlag_Default, "Ecf" _type, env, c, fid, value); \
   1343         sc.CheckStaticFieldID(c, fid); \
   1344         /* "value" arg only used when type == ref */ \
   1345         sc.CheckFieldType((jobject)(uint32_t)value, fid, _type[0], true); \
   1346         baseEnv(env)->SetStatic##_jname##Field(env, c, fid, value); \
   1347         CHECK_JNI_EXIT_VOID(); \
   1348     } \
   1349     static void Set##_jname##Field(JNIEnv* env, jobject obj, jfieldID fid, _ctype value) { \
   1350         CHECK_JNI_ENTRY(kFlag_Default, "ELf" _type, env, obj, fid, value); \
   1351         sc.CheckInstanceFieldID(obj, fid); \
   1352         /* "value" arg only used when type == ref */ \
   1353         sc.CheckFieldType((jobject)(uint32_t) value, fid, _type[0], false); \
   1354         baseEnv(env)->Set##_jname##Field(env, obj, fid, value); \
   1355         CHECK_JNI_EXIT_VOID(); \
   1356     }
   1357 
   1358 FIELD_ACCESSORS(jobject, Object, "L");
   1359 FIELD_ACCESSORS(jboolean, Boolean, "Z");
   1360 FIELD_ACCESSORS(jbyte, Byte, "B");
   1361 FIELD_ACCESSORS(jchar, Char, "C");
   1362 FIELD_ACCESSORS(jshort, Short, "S");
   1363 FIELD_ACCESSORS(jint, Int, "I");
   1364 FIELD_ACCESSORS(jlong, Long, "J");
   1365 FIELD_ACCESSORS(jfloat, Float, "F");
   1366 FIELD_ACCESSORS(jdouble, Double, "D");
   1367 
   1368 #define CALL(_ctype, _jname, _retdecl, _retasgn, _retok, _retsig) \
   1369     /* Virtual... */ \
   1370     static _ctype Call##_jname##Method(JNIEnv* env, jobject obj, \
   1371         jmethodID mid, ...) \
   1372     { \
   1373         CHECK_JNI_ENTRY(kFlag_Default, "ELm.", env, obj, mid); /* TODO: args! */ \
   1374         sc.CheckSig(mid, _retsig, false); \
   1375         sc.CheckVirtualMethod(obj, mid); \
   1376         _retdecl; \
   1377         va_list args; \
   1378         va_start(args, mid); \
   1379         _retasgn(baseEnv(env)->Call##_jname##MethodV(env, obj, mid, args)); \
   1380         va_end(args); \
   1381         _retok; \
   1382     } \
   1383     static _ctype Call##_jname##MethodV(JNIEnv* env, jobject obj, \
   1384         jmethodID mid, va_list args) \
   1385     { \
   1386         CHECK_JNI_ENTRY(kFlag_Default, "ELm.", env, obj, mid); /* TODO: args! */ \
   1387         sc.CheckSig(mid, _retsig, false); \
   1388         sc.CheckVirtualMethod(obj, mid); \
   1389         _retdecl; \
   1390         _retasgn(baseEnv(env)->Call##_jname##MethodV(env, obj, mid, args)); \
   1391         _retok; \
   1392     } \
   1393     static _ctype Call##_jname##MethodA(JNIEnv* env, jobject obj, \
   1394         jmethodID mid, jvalue* args) \
   1395     { \
   1396         CHECK_JNI_ENTRY(kFlag_Default, "ELm.", env, obj, mid); /* TODO: args! */ \
   1397         sc.CheckSig(mid, _retsig, false); \
   1398         sc.CheckVirtualMethod(obj, mid); \
   1399         _retdecl; \
   1400         _retasgn(baseEnv(env)->Call##_jname##MethodA(env, obj, mid, args)); \
   1401         _retok; \
   1402     } \
   1403     /* Non-virtual... */ \
   1404     static _ctype CallNonvirtual##_jname##Method(JNIEnv* env, \
   1405         jobject obj, jclass c, jmethodID mid, ...) \
   1406     { \
   1407         CHECK_JNI_ENTRY(kFlag_Default, "ELcm.", env, obj, c, mid); /* TODO: args! */ \
   1408         sc.CheckSig(mid, _retsig, false); \
   1409         sc.CheckVirtualMethod(obj, mid); \
   1410         _retdecl; \
   1411         va_list args; \
   1412         va_start(args, mid); \
   1413         _retasgn(baseEnv(env)->CallNonvirtual##_jname##MethodV(env, obj, c, mid, args)); \
   1414         va_end(args); \
   1415         _retok; \
   1416     } \
   1417     static _ctype CallNonvirtual##_jname##MethodV(JNIEnv* env, \
   1418         jobject obj, jclass c, jmethodID mid, va_list args) \
   1419     { \
   1420         CHECK_JNI_ENTRY(kFlag_Default, "ELcm.", env, obj, c, mid); /* TODO: args! */ \
   1421         sc.CheckSig(mid, _retsig, false); \
   1422         sc.CheckVirtualMethod(obj, mid); \
   1423         _retdecl; \
   1424         _retasgn(baseEnv(env)->CallNonvirtual##_jname##MethodV(env, obj, c, mid, args)); \
   1425         _retok; \
   1426     } \
   1427     static _ctype CallNonvirtual##_jname##MethodA(JNIEnv* env, \
   1428         jobject obj, jclass c, jmethodID mid, jvalue* args) \
   1429     { \
   1430         CHECK_JNI_ENTRY(kFlag_Default, "ELcm.", env, obj, c, mid); /* TODO: args! */ \
   1431         sc.CheckSig(mid, _retsig, false); \
   1432         sc.CheckVirtualMethod(obj, mid); \
   1433         _retdecl; \
   1434         _retasgn(baseEnv(env)->CallNonvirtual##_jname##MethodA(env, obj, c, mid, args)); \
   1435         _retok; \
   1436     } \
   1437     /* Static... */ \
   1438     static _ctype CallStatic##_jname##Method(JNIEnv* env, jclass c, jmethodID mid, ...) \
   1439     { \
   1440         CHECK_JNI_ENTRY(kFlag_Default, "Ecm.", env, c, mid); /* TODO: args! */ \
   1441         sc.CheckSig(mid, _retsig, true); \
   1442         sc.CheckStaticMethod(c, mid); \
   1443         _retdecl; \
   1444         va_list args; \
   1445         va_start(args, mid); \
   1446         _retasgn(baseEnv(env)->CallStatic##_jname##MethodV(env, c, mid, args)); \
   1447         va_end(args); \
   1448         _retok; \
   1449     } \
   1450     static _ctype CallStatic##_jname##MethodV(JNIEnv* env, jclass c, jmethodID mid, va_list args) \
   1451     { \
   1452         CHECK_JNI_ENTRY(kFlag_Default, "Ecm.", env, c, mid); /* TODO: args! */ \
   1453         sc.CheckSig(mid, _retsig, true); \
   1454         sc.CheckStaticMethod(c, mid); \
   1455         _retdecl; \
   1456          _retasgn(baseEnv(env)->CallStatic##_jname##MethodV(env, c, mid, args)); \
   1457         _retok; \
   1458     } \
   1459     static _ctype CallStatic##_jname##MethodA(JNIEnv* env, jclass c, jmethodID mid, jvalue* args) \
   1460     { \
   1461         CHECK_JNI_ENTRY(kFlag_Default, "Ecm.", env, c, mid); /* TODO: args! */ \
   1462         sc.CheckSig(mid, _retsig, true); \
   1463         sc.CheckStaticMethod(c, mid); \
   1464         _retdecl; \
   1465         _retasgn(baseEnv(env)->CallStatic##_jname##MethodA(env, c, mid, args)); \
   1466         _retok; \
   1467     }
   1468 
   1469 #define NON_VOID_RETURN(_retsig, _ctype) return CHECK_JNI_EXIT(_retsig, (_ctype) result)
   1470 #define VOID_RETURN CHECK_JNI_EXIT_VOID()
   1471 
   1472 CALL(jobject, Object, mirror::Object* result, result = reinterpret_cast<mirror::Object*>, NON_VOID_RETURN("L", jobject), "L");
   1473 CALL(jboolean, Boolean, jboolean result, result =, NON_VOID_RETURN("Z", jboolean), "Z");
   1474 CALL(jbyte, Byte, jbyte result, result =, NON_VOID_RETURN("B", jbyte), "B");
   1475 CALL(jchar, Char, jchar result, result =, NON_VOID_RETURN("C", jchar), "C");
   1476 CALL(jshort, Short, jshort result, result =, NON_VOID_RETURN("S", jshort), "S");
   1477 CALL(jint, Int, jint result, result =, NON_VOID_RETURN("I", jint), "I");
   1478 CALL(jlong, Long, jlong result, result =, NON_VOID_RETURN("J", jlong), "J");
   1479 CALL(jfloat, Float, jfloat result, result =, NON_VOID_RETURN("F", jfloat), "F");
   1480 CALL(jdouble, Double, jdouble result, result =, NON_VOID_RETURN("D", jdouble), "D");
   1481 CALL(void, Void, , , VOID_RETURN, "V");
   1482 
   1483   static jstring NewString(JNIEnv* env, const jchar* unicodeChars, jsize len) {
   1484     CHECK_JNI_ENTRY(kFlag_Default, "Epz", env, unicodeChars, len);
   1485     return CHECK_JNI_EXIT("s", baseEnv(env)->NewString(env, unicodeChars, len));
   1486   }
   1487 
   1488   static jsize GetStringLength(JNIEnv* env, jstring string) {
   1489     CHECK_JNI_ENTRY(kFlag_CritOkay, "Es", env, string);
   1490     return CHECK_JNI_EXIT("I", baseEnv(env)->GetStringLength(env, string));
   1491   }
   1492 
   1493   static const jchar* GetStringChars(JNIEnv* env, jstring java_string, jboolean* isCopy) {
   1494     CHECK_JNI_ENTRY(kFlag_CritOkay, "Esp", env, java_string, isCopy);
   1495     const jchar* result = baseEnv(env)->GetStringChars(env, java_string, isCopy);
   1496     if (sc.ForceCopy() && result != NULL) {
   1497       mirror::String* s = sc.soa().Decode<mirror::String*>(java_string);
   1498       int byteCount = s->GetLength() * 2;
   1499       result = (const jchar*) GuardedCopy::Create(result, byteCount, false);
   1500       if (isCopy != NULL) {
   1501         *isCopy = JNI_TRUE;
   1502       }
   1503     }
   1504     return CHECK_JNI_EXIT("p", result);
   1505   }
   1506 
   1507   static void ReleaseStringChars(JNIEnv* env, jstring string, const jchar* chars) {
   1508     CHECK_JNI_ENTRY(kFlag_Default | kFlag_ExcepOkay, "Esp", env, string, chars);
   1509     sc.CheckNonNull(chars);
   1510     if (sc.ForceCopy()) {
   1511       GuardedCopy::Check(__FUNCTION__, chars, false);
   1512       chars = reinterpret_cast<const jchar*>(GuardedCopy::Destroy(const_cast<jchar*>(chars)));
   1513     }
   1514     baseEnv(env)->ReleaseStringChars(env, string, chars);
   1515     CHECK_JNI_EXIT_VOID();
   1516   }
   1517 
   1518   static jstring NewStringUTF(JNIEnv* env, const char* bytes) {
   1519     CHECK_JNI_ENTRY(kFlag_NullableUtf, "Eu", env, bytes);  // TODO: show pointer and truncate string.
   1520     return CHECK_JNI_EXIT("s", baseEnv(env)->NewStringUTF(env, bytes));
   1521   }
   1522 
   1523   static jsize GetStringUTFLength(JNIEnv* env, jstring string) {
   1524     CHECK_JNI_ENTRY(kFlag_CritOkay, "Es", env, string);
   1525     return CHECK_JNI_EXIT("I", baseEnv(env)->GetStringUTFLength(env, string));
   1526   }
   1527 
   1528   static const char* GetStringUTFChars(JNIEnv* env, jstring string, jboolean* isCopy) {
   1529     CHECK_JNI_ENTRY(kFlag_CritOkay, "Esp", env, string, isCopy);
   1530     const char* result = baseEnv(env)->GetStringUTFChars(env, string, isCopy);
   1531     if (sc.ForceCopy() && result != NULL) {
   1532       result = (const char*) GuardedCopy::Create(result, strlen(result) + 1, false);
   1533       if (isCopy != NULL) {
   1534         *isCopy = JNI_TRUE;
   1535       }
   1536     }
   1537     return CHECK_JNI_EXIT("u", result);  // TODO: show pointer and truncate string.
   1538   }
   1539 
   1540   static void ReleaseStringUTFChars(JNIEnv* env, jstring string, const char* utf) {
   1541     CHECK_JNI_ENTRY(kFlag_ExcepOkay | kFlag_Release, "Esu", env, string, utf);  // TODO: show pointer and truncate string.
   1542     if (sc.ForceCopy()) {
   1543       GuardedCopy::Check(__FUNCTION__, utf, false);
   1544       utf = reinterpret_cast<const char*>(GuardedCopy::Destroy(const_cast<char*>(utf)));
   1545     }
   1546     baseEnv(env)->ReleaseStringUTFChars(env, string, utf);
   1547     CHECK_JNI_EXIT_VOID();
   1548   }
   1549 
   1550   static jsize GetArrayLength(JNIEnv* env, jarray array) {
   1551     CHECK_JNI_ENTRY(kFlag_CritOkay, "Ea", env, array);
   1552     return CHECK_JNI_EXIT("I", baseEnv(env)->GetArrayLength(env, array));
   1553   }
   1554 
   1555   static jobjectArray NewObjectArray(JNIEnv* env, jsize length, jclass elementClass, jobject initialElement) {
   1556     CHECK_JNI_ENTRY(kFlag_Default, "EzcL", env, length, elementClass, initialElement);
   1557     return CHECK_JNI_EXIT("a", baseEnv(env)->NewObjectArray(env, length, elementClass, initialElement));
   1558   }
   1559 
   1560   static jobject GetObjectArrayElement(JNIEnv* env, jobjectArray array, jsize index) {
   1561     CHECK_JNI_ENTRY(kFlag_Default, "EaI", env, array, index);
   1562     return CHECK_JNI_EXIT("L", baseEnv(env)->GetObjectArrayElement(env, array, index));
   1563   }
   1564 
   1565   static void SetObjectArrayElement(JNIEnv* env, jobjectArray array, jsize index, jobject value) {
   1566     CHECK_JNI_ENTRY(kFlag_Default, "EaIL", env, array, index, value);
   1567     baseEnv(env)->SetObjectArrayElement(env, array, index, value);
   1568     CHECK_JNI_EXIT_VOID();
   1569   }
   1570 
   1571 #define NEW_PRIMITIVE_ARRAY(_artype, _jname) \
   1572     static _artype New##_jname##Array(JNIEnv* env, jsize length) { \
   1573         CHECK_JNI_ENTRY(kFlag_Default, "Ez", env, length); \
   1574         return CHECK_JNI_EXIT("a", baseEnv(env)->New##_jname##Array(env, length)); \
   1575     }
   1576 NEW_PRIMITIVE_ARRAY(jbooleanArray, Boolean);
   1577 NEW_PRIMITIVE_ARRAY(jbyteArray, Byte);
   1578 NEW_PRIMITIVE_ARRAY(jcharArray, Char);
   1579 NEW_PRIMITIVE_ARRAY(jshortArray, Short);
   1580 NEW_PRIMITIVE_ARRAY(jintArray, Int);
   1581 NEW_PRIMITIVE_ARRAY(jlongArray, Long);
   1582 NEW_PRIMITIVE_ARRAY(jfloatArray, Float);
   1583 NEW_PRIMITIVE_ARRAY(jdoubleArray, Double);
   1584 
   1585 struct ForceCopyGetChecker {
   1586  public:
   1587   ForceCopyGetChecker(ScopedCheck& sc, jboolean* isCopy) {
   1588     force_copy = sc.ForceCopy();
   1589     no_copy = 0;
   1590     if (force_copy && isCopy != NULL) {
   1591       // Capture this before the base call tramples on it.
   1592       no_copy = *reinterpret_cast<uint32_t*>(isCopy);
   1593     }
   1594   }
   1595 
   1596   template<typename ResultT>
   1597   ResultT Check(JNIEnv* env, jarray array, jboolean* isCopy, ResultT result) {
   1598     if (force_copy && result != NULL) {
   1599       if (no_copy != kNoCopyMagic) {
   1600         result = reinterpret_cast<ResultT>(CreateGuardedPACopy(env, array, isCopy));
   1601       }
   1602     }
   1603     return result;
   1604   }
   1605 
   1606   uint32_t no_copy;
   1607   bool force_copy;
   1608 };
   1609 
   1610 #define GET_PRIMITIVE_ARRAY_ELEMENTS(_ctype, _jname) \
   1611   static _ctype* Get##_jname##ArrayElements(JNIEnv* env, _ctype##Array array, jboolean* isCopy) { \
   1612     CHECK_JNI_ENTRY(kFlag_Default, "Eap", env, array, isCopy); \
   1613     _ctype* result = ForceCopyGetChecker(sc, isCopy).Check(env, array, isCopy, baseEnv(env)->Get##_jname##ArrayElements(env, array, isCopy)); \
   1614     return CHECK_JNI_EXIT("p", result); \
   1615   }
   1616 
   1617 #define RELEASE_PRIMITIVE_ARRAY_ELEMENTS(_ctype, _jname) \
   1618   static void Release##_jname##ArrayElements(JNIEnv* env, _ctype##Array array, _ctype* elems, jint mode) { \
   1619     CHECK_JNI_ENTRY(kFlag_Default | kFlag_ExcepOkay, "Eapr", env, array, elems, mode); \
   1620     sc.CheckNonNull(elems); \
   1621     if (sc.ForceCopy()) { \
   1622       ReleaseGuardedPACopy(env, array, elems, mode); \
   1623     } \
   1624     baseEnv(env)->Release##_jname##ArrayElements(env, array, elems, mode); \
   1625     CHECK_JNI_EXIT_VOID(); \
   1626   }
   1627 
   1628 #define GET_PRIMITIVE_ARRAY_REGION(_ctype, _jname) \
   1629     static void Get##_jname##ArrayRegion(JNIEnv* env, _ctype##Array array, jsize start, jsize len, _ctype* buf) { \
   1630         CHECK_JNI_ENTRY(kFlag_Default, "EaIIp", env, array, start, len, buf); \
   1631         baseEnv(env)->Get##_jname##ArrayRegion(env, array, start, len, buf); \
   1632         CHECK_JNI_EXIT_VOID(); \
   1633     }
   1634 
   1635 #define SET_PRIMITIVE_ARRAY_REGION(_ctype, _jname) \
   1636     static void Set##_jname##ArrayRegion(JNIEnv* env, _ctype##Array array, jsize start, jsize len, const _ctype* buf) { \
   1637         CHECK_JNI_ENTRY(kFlag_Default, "EaIIp", env, array, start, len, buf); \
   1638         baseEnv(env)->Set##_jname##ArrayRegion(env, array, start, len, buf); \
   1639         CHECK_JNI_EXIT_VOID(); \
   1640     }
   1641 
   1642 #define PRIMITIVE_ARRAY_FUNCTIONS(_ctype, _jname, _typechar) \
   1643     GET_PRIMITIVE_ARRAY_ELEMENTS(_ctype, _jname); \
   1644     RELEASE_PRIMITIVE_ARRAY_ELEMENTS(_ctype, _jname); \
   1645     GET_PRIMITIVE_ARRAY_REGION(_ctype, _jname); \
   1646     SET_PRIMITIVE_ARRAY_REGION(_ctype, _jname);
   1647 
   1648 // TODO: verify primitive array type matches call type.
   1649 PRIMITIVE_ARRAY_FUNCTIONS(jboolean, Boolean, 'Z');
   1650 PRIMITIVE_ARRAY_FUNCTIONS(jbyte, Byte, 'B');
   1651 PRIMITIVE_ARRAY_FUNCTIONS(jchar, Char, 'C');
   1652 PRIMITIVE_ARRAY_FUNCTIONS(jshort, Short, 'S');
   1653 PRIMITIVE_ARRAY_FUNCTIONS(jint, Int, 'I');
   1654 PRIMITIVE_ARRAY_FUNCTIONS(jlong, Long, 'J');
   1655 PRIMITIVE_ARRAY_FUNCTIONS(jfloat, Float, 'F');
   1656 PRIMITIVE_ARRAY_FUNCTIONS(jdouble, Double, 'D');
   1657 
   1658   static jint RegisterNatives(JNIEnv* env, jclass c, const JNINativeMethod* methods, jint nMethods) {
   1659     CHECK_JNI_ENTRY(kFlag_Default, "EcpI", env, c, methods, nMethods);
   1660     return CHECK_JNI_EXIT("I", baseEnv(env)->RegisterNatives(env, c, methods, nMethods));
   1661   }
   1662 
   1663   static jint UnregisterNatives(JNIEnv* env, jclass c) {
   1664     CHECK_JNI_ENTRY(kFlag_Default, "Ec", env, c);
   1665     return CHECK_JNI_EXIT("I", baseEnv(env)->UnregisterNatives(env, c));
   1666   }
   1667 
   1668   static jint MonitorEnter(JNIEnv* env, jobject obj) {
   1669     CHECK_JNI_ENTRY(kFlag_Default, "EL", env, obj);
   1670     if (!sc.CheckInstance(ScopedCheck::kObject, obj)) {
   1671       return JNI_ERR;  // Only for jni_internal_test. Real code will have aborted already.
   1672     }
   1673     return CHECK_JNI_EXIT("I", baseEnv(env)->MonitorEnter(env, obj));
   1674   }
   1675 
   1676   static jint MonitorExit(JNIEnv* env, jobject obj) {
   1677     CHECK_JNI_ENTRY(kFlag_Default | kFlag_ExcepOkay, "EL", env, obj);
   1678     if (!sc.CheckInstance(ScopedCheck::kObject, obj)) {
   1679       return JNI_ERR;  // Only for jni_internal_test. Real code will have aborted already.
   1680     }
   1681     return CHECK_JNI_EXIT("I", baseEnv(env)->MonitorExit(env, obj));
   1682   }
   1683 
   1684   static jint GetJavaVM(JNIEnv *env, JavaVM **vm) {
   1685     CHECK_JNI_ENTRY(kFlag_Default, "Ep", env, vm);
   1686     return CHECK_JNI_EXIT("I", baseEnv(env)->GetJavaVM(env, vm));
   1687   }
   1688 
   1689   static void GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len, jchar* buf) {
   1690     CHECK_JNI_ENTRY(kFlag_CritOkay, "EsIIp", env, str, start, len, buf);
   1691     baseEnv(env)->GetStringRegion(env, str, start, len, buf);
   1692     CHECK_JNI_EXIT_VOID();
   1693   }
   1694 
   1695   static void GetStringUTFRegion(JNIEnv* env, jstring str, jsize start, jsize len, char* buf) {
   1696     CHECK_JNI_ENTRY(kFlag_CritOkay, "EsIIp", env, str, start, len, buf);
   1697     baseEnv(env)->GetStringUTFRegion(env, str, start, len, buf);
   1698     CHECK_JNI_EXIT_VOID();
   1699   }
   1700 
   1701   static void* GetPrimitiveArrayCritical(JNIEnv* env, jarray array, jboolean* isCopy) {
   1702     CHECK_JNI_ENTRY(kFlag_CritGet, "Eap", env, array, isCopy);
   1703     void* result = baseEnv(env)->GetPrimitiveArrayCritical(env, array, isCopy);
   1704     if (sc.ForceCopy() && result != NULL) {
   1705       result = CreateGuardedPACopy(env, array, isCopy);
   1706     }
   1707     return CHECK_JNI_EXIT("p", result);
   1708   }
   1709 
   1710   static void ReleasePrimitiveArrayCritical(JNIEnv* env, jarray array, void* carray, jint mode) {
   1711     CHECK_JNI_ENTRY(kFlag_CritRelease | kFlag_ExcepOkay, "Eapr", env, array, carray, mode);
   1712     sc.CheckNonNull(carray);
   1713     if (sc.ForceCopy()) {
   1714       ReleaseGuardedPACopy(env, array, carray, mode);
   1715     }
   1716     baseEnv(env)->ReleasePrimitiveArrayCritical(env, array, carray, mode);
   1717     CHECK_JNI_EXIT_VOID();
   1718   }
   1719 
   1720   static const jchar* GetStringCritical(JNIEnv* env, jstring java_string, jboolean* isCopy) {
   1721     CHECK_JNI_ENTRY(kFlag_CritGet, "Esp", env, java_string, isCopy);
   1722     const jchar* result = baseEnv(env)->GetStringCritical(env, java_string, isCopy);
   1723     if (sc.ForceCopy() && result != NULL) {
   1724       mirror::String* s = sc.soa().Decode<mirror::String*>(java_string);
   1725       int byteCount = s->GetLength() * 2;
   1726       result = (const jchar*) GuardedCopy::Create(result, byteCount, false);
   1727       if (isCopy != NULL) {
   1728         *isCopy = JNI_TRUE;
   1729       }
   1730     }
   1731     return CHECK_JNI_EXIT("p", result);
   1732   }
   1733 
   1734   static void ReleaseStringCritical(JNIEnv* env, jstring string, const jchar* carray) {
   1735     CHECK_JNI_ENTRY(kFlag_CritRelease | kFlag_ExcepOkay, "Esp", env, string, carray);
   1736     sc.CheckNonNull(carray);
   1737     if (sc.ForceCopy()) {
   1738       GuardedCopy::Check(__FUNCTION__, carray, false);
   1739       carray = reinterpret_cast<const jchar*>(GuardedCopy::Destroy(const_cast<jchar*>(carray)));
   1740     }
   1741     baseEnv(env)->ReleaseStringCritical(env, string, carray);
   1742     CHECK_JNI_EXIT_VOID();
   1743   }
   1744 
   1745   static jweak NewWeakGlobalRef(JNIEnv* env, jobject obj) {
   1746     CHECK_JNI_ENTRY(kFlag_Default, "EL", env, obj);
   1747     return CHECK_JNI_EXIT("L", baseEnv(env)->NewWeakGlobalRef(env, obj));
   1748   }
   1749 
   1750   static jboolean ExceptionCheck(JNIEnv* env) {
   1751     CHECK_JNI_ENTRY(kFlag_CritOkay | kFlag_ExcepOkay, "E", env);
   1752     return CHECK_JNI_EXIT("b", baseEnv(env)->ExceptionCheck(env));
   1753   }
   1754 
   1755   static jobjectRefType GetObjectRefType(JNIEnv* env, jobject obj) {
   1756     // Note: we use "Ep" rather than "EL" because this is the one JNI function
   1757     // that it's okay to pass an invalid reference to.
   1758     CHECK_JNI_ENTRY(kFlag_Default, "Ep", env, obj);
   1759     // TODO: proper decoding of jobjectRefType!
   1760     return CHECK_JNI_EXIT("I", baseEnv(env)->GetObjectRefType(env, obj));
   1761   }
   1762 
   1763   static jobject NewDirectByteBuffer(JNIEnv* env, void* address, jlong capacity) {
   1764     CHECK_JNI_ENTRY(kFlag_Default, "EpJ", env, address, capacity);
   1765     if (address == NULL) {
   1766       JniAbortF(__FUNCTION__, "non-nullable address is NULL");
   1767     }
   1768     if (capacity <= 0) {
   1769       JniAbortF(__FUNCTION__, "capacity must be greater than 0: %lld", capacity);
   1770     }
   1771     return CHECK_JNI_EXIT("L", baseEnv(env)->NewDirectByteBuffer(env, address, capacity));
   1772   }
   1773 
   1774   static void* GetDirectBufferAddress(JNIEnv* env, jobject buf) {
   1775     CHECK_JNI_ENTRY(kFlag_Default, "EL", env, buf);
   1776     // TODO: check that 'buf' is a java.nio.Buffer.
   1777     return CHECK_JNI_EXIT("p", baseEnv(env)->GetDirectBufferAddress(env, buf));
   1778   }
   1779 
   1780   static jlong GetDirectBufferCapacity(JNIEnv* env, jobject buf) {
   1781     CHECK_JNI_ENTRY(kFlag_Default, "EL", env, buf);
   1782     // TODO: check that 'buf' is a java.nio.Buffer.
   1783     return CHECK_JNI_EXIT("J", baseEnv(env)->GetDirectBufferCapacity(env, buf));
   1784   }
   1785 
   1786  private:
   1787   static inline const JNINativeInterface* baseEnv(JNIEnv* env) {
   1788     return reinterpret_cast<JNIEnvExt*>(env)->unchecked_functions;
   1789   }
   1790 };
   1791 
   1792 const JNINativeInterface gCheckNativeInterface = {
   1793   NULL,  // reserved0.
   1794   NULL,  // reserved1.
   1795   NULL,  // reserved2.
   1796   NULL,  // reserved3.
   1797   CheckJNI::GetVersion,
   1798   CheckJNI::DefineClass,
   1799   CheckJNI::FindClass,
   1800   CheckJNI::FromReflectedMethod,
   1801   CheckJNI::FromReflectedField,
   1802   CheckJNI::ToReflectedMethod,
   1803   CheckJNI::GetSuperclass,
   1804   CheckJNI::IsAssignableFrom,
   1805   CheckJNI::ToReflectedField,
   1806   CheckJNI::Throw,
   1807   CheckJNI::ThrowNew,
   1808   CheckJNI::ExceptionOccurred,
   1809   CheckJNI::ExceptionDescribe,
   1810   CheckJNI::ExceptionClear,
   1811   CheckJNI::FatalError,
   1812   CheckJNI::PushLocalFrame,
   1813   CheckJNI::PopLocalFrame,
   1814   CheckJNI::NewGlobalRef,
   1815   CheckJNI::DeleteGlobalRef,
   1816   CheckJNI::DeleteLocalRef,
   1817   CheckJNI::IsSameObject,
   1818   CheckJNI::NewLocalRef,
   1819   CheckJNI::EnsureLocalCapacity,
   1820   CheckJNI::AllocObject,
   1821   CheckJNI::NewObject,
   1822   CheckJNI::NewObjectV,
   1823   CheckJNI::NewObjectA,
   1824   CheckJNI::GetObjectClass,
   1825   CheckJNI::IsInstanceOf,
   1826   CheckJNI::GetMethodID,
   1827   CheckJNI::CallObjectMethod,
   1828   CheckJNI::CallObjectMethodV,
   1829   CheckJNI::CallObjectMethodA,
   1830   CheckJNI::CallBooleanMethod,
   1831   CheckJNI::CallBooleanMethodV,
   1832   CheckJNI::CallBooleanMethodA,
   1833   CheckJNI::CallByteMethod,
   1834   CheckJNI::CallByteMethodV,
   1835   CheckJNI::CallByteMethodA,
   1836   CheckJNI::CallCharMethod,
   1837   CheckJNI::CallCharMethodV,
   1838   CheckJNI::CallCharMethodA,
   1839   CheckJNI::CallShortMethod,
   1840   CheckJNI::CallShortMethodV,
   1841   CheckJNI::CallShortMethodA,
   1842   CheckJNI::CallIntMethod,
   1843   CheckJNI::CallIntMethodV,
   1844   CheckJNI::CallIntMethodA,
   1845   CheckJNI::CallLongMethod,
   1846   CheckJNI::CallLongMethodV,
   1847   CheckJNI::CallLongMethodA,
   1848   CheckJNI::CallFloatMethod,
   1849   CheckJNI::CallFloatMethodV,
   1850   CheckJNI::CallFloatMethodA,
   1851   CheckJNI::CallDoubleMethod,
   1852   CheckJNI::CallDoubleMethodV,
   1853   CheckJNI::CallDoubleMethodA,
   1854   CheckJNI::CallVoidMethod,
   1855   CheckJNI::CallVoidMethodV,
   1856   CheckJNI::CallVoidMethodA,
   1857   CheckJNI::CallNonvirtualObjectMethod,
   1858   CheckJNI::CallNonvirtualObjectMethodV,
   1859   CheckJNI::CallNonvirtualObjectMethodA,
   1860   CheckJNI::CallNonvirtualBooleanMethod,
   1861   CheckJNI::CallNonvirtualBooleanMethodV,
   1862   CheckJNI::CallNonvirtualBooleanMethodA,
   1863   CheckJNI::CallNonvirtualByteMethod,
   1864   CheckJNI::CallNonvirtualByteMethodV,
   1865   CheckJNI::CallNonvirtualByteMethodA,
   1866   CheckJNI::CallNonvirtualCharMethod,
   1867   CheckJNI::CallNonvirtualCharMethodV,
   1868   CheckJNI::CallNonvirtualCharMethodA,
   1869   CheckJNI::CallNonvirtualShortMethod,
   1870   CheckJNI::CallNonvirtualShortMethodV,
   1871   CheckJNI::CallNonvirtualShortMethodA,
   1872   CheckJNI::CallNonvirtualIntMethod,
   1873   CheckJNI::CallNonvirtualIntMethodV,
   1874   CheckJNI::CallNonvirtualIntMethodA,
   1875   CheckJNI::CallNonvirtualLongMethod,
   1876   CheckJNI::CallNonvirtualLongMethodV,
   1877   CheckJNI::CallNonvirtualLongMethodA,
   1878   CheckJNI::CallNonvirtualFloatMethod,
   1879   CheckJNI::CallNonvirtualFloatMethodV,
   1880   CheckJNI::CallNonvirtualFloatMethodA,
   1881   CheckJNI::CallNonvirtualDoubleMethod,
   1882   CheckJNI::CallNonvirtualDoubleMethodV,
   1883   CheckJNI::CallNonvirtualDoubleMethodA,
   1884   CheckJNI::CallNonvirtualVoidMethod,
   1885   CheckJNI::CallNonvirtualVoidMethodV,
   1886   CheckJNI::CallNonvirtualVoidMethodA,
   1887   CheckJNI::GetFieldID,
   1888   CheckJNI::GetObjectField,
   1889   CheckJNI::GetBooleanField,
   1890   CheckJNI::GetByteField,
   1891   CheckJNI::GetCharField,
   1892   CheckJNI::GetShortField,
   1893   CheckJNI::GetIntField,
   1894   CheckJNI::GetLongField,
   1895   CheckJNI::GetFloatField,
   1896   CheckJNI::GetDoubleField,
   1897   CheckJNI::SetObjectField,
   1898   CheckJNI::SetBooleanField,
   1899   CheckJNI::SetByteField,
   1900   CheckJNI::SetCharField,
   1901   CheckJNI::SetShortField,
   1902   CheckJNI::SetIntField,
   1903   CheckJNI::SetLongField,
   1904   CheckJNI::SetFloatField,
   1905   CheckJNI::SetDoubleField,
   1906   CheckJNI::GetStaticMethodID,
   1907   CheckJNI::CallStaticObjectMethod,
   1908   CheckJNI::CallStaticObjectMethodV,
   1909   CheckJNI::CallStaticObjectMethodA,
   1910   CheckJNI::CallStaticBooleanMethod,
   1911   CheckJNI::CallStaticBooleanMethodV,
   1912   CheckJNI::CallStaticBooleanMethodA,
   1913   CheckJNI::CallStaticByteMethod,
   1914   CheckJNI::CallStaticByteMethodV,
   1915   CheckJNI::CallStaticByteMethodA,
   1916   CheckJNI::CallStaticCharMethod,
   1917   CheckJNI::CallStaticCharMethodV,
   1918   CheckJNI::CallStaticCharMethodA,
   1919   CheckJNI::CallStaticShortMethod,
   1920   CheckJNI::CallStaticShortMethodV,
   1921   CheckJNI::CallStaticShortMethodA,
   1922   CheckJNI::CallStaticIntMethod,
   1923   CheckJNI::CallStaticIntMethodV,
   1924   CheckJNI::CallStaticIntMethodA,
   1925   CheckJNI::CallStaticLongMethod,
   1926   CheckJNI::CallStaticLongMethodV,
   1927   CheckJNI::CallStaticLongMethodA,
   1928   CheckJNI::CallStaticFloatMethod,
   1929   CheckJNI::CallStaticFloatMethodV,
   1930   CheckJNI::CallStaticFloatMethodA,
   1931   CheckJNI::CallStaticDoubleMethod,
   1932   CheckJNI::CallStaticDoubleMethodV,
   1933   CheckJNI::CallStaticDoubleMethodA,
   1934   CheckJNI::CallStaticVoidMethod,
   1935   CheckJNI::CallStaticVoidMethodV,
   1936   CheckJNI::CallStaticVoidMethodA,
   1937   CheckJNI::GetStaticFieldID,
   1938   CheckJNI::GetStaticObjectField,
   1939   CheckJNI::GetStaticBooleanField,
   1940   CheckJNI::GetStaticByteField,
   1941   CheckJNI::GetStaticCharField,
   1942   CheckJNI::GetStaticShortField,
   1943   CheckJNI::GetStaticIntField,
   1944   CheckJNI::GetStaticLongField,
   1945   CheckJNI::GetStaticFloatField,
   1946   CheckJNI::GetStaticDoubleField,
   1947   CheckJNI::SetStaticObjectField,
   1948   CheckJNI::SetStaticBooleanField,
   1949   CheckJNI::SetStaticByteField,
   1950   CheckJNI::SetStaticCharField,
   1951   CheckJNI::SetStaticShortField,
   1952   CheckJNI::SetStaticIntField,
   1953   CheckJNI::SetStaticLongField,
   1954   CheckJNI::SetStaticFloatField,
   1955   CheckJNI::SetStaticDoubleField,
   1956   CheckJNI::NewString,
   1957   CheckJNI::GetStringLength,
   1958   CheckJNI::GetStringChars,
   1959   CheckJNI::ReleaseStringChars,
   1960   CheckJNI::NewStringUTF,
   1961   CheckJNI::GetStringUTFLength,
   1962   CheckJNI::GetStringUTFChars,
   1963   CheckJNI::ReleaseStringUTFChars,
   1964   CheckJNI::GetArrayLength,
   1965   CheckJNI::NewObjectArray,
   1966   CheckJNI::GetObjectArrayElement,
   1967   CheckJNI::SetObjectArrayElement,
   1968   CheckJNI::NewBooleanArray,
   1969   CheckJNI::NewByteArray,
   1970   CheckJNI::NewCharArray,
   1971   CheckJNI::NewShortArray,
   1972   CheckJNI::NewIntArray,
   1973   CheckJNI::NewLongArray,
   1974   CheckJNI::NewFloatArray,
   1975   CheckJNI::NewDoubleArray,
   1976   CheckJNI::GetBooleanArrayElements,
   1977   CheckJNI::GetByteArrayElements,
   1978   CheckJNI::GetCharArrayElements,
   1979   CheckJNI::GetShortArrayElements,
   1980   CheckJNI::GetIntArrayElements,
   1981   CheckJNI::GetLongArrayElements,
   1982   CheckJNI::GetFloatArrayElements,
   1983   CheckJNI::GetDoubleArrayElements,
   1984   CheckJNI::ReleaseBooleanArrayElements,
   1985   CheckJNI::ReleaseByteArrayElements,
   1986   CheckJNI::ReleaseCharArrayElements,
   1987   CheckJNI::ReleaseShortArrayElements,
   1988   CheckJNI::ReleaseIntArrayElements,
   1989   CheckJNI::ReleaseLongArrayElements,
   1990   CheckJNI::ReleaseFloatArrayElements,
   1991   CheckJNI::ReleaseDoubleArrayElements,
   1992   CheckJNI::GetBooleanArrayRegion,
   1993   CheckJNI::GetByteArrayRegion,
   1994   CheckJNI::GetCharArrayRegion,
   1995   CheckJNI::GetShortArrayRegion,
   1996   CheckJNI::GetIntArrayRegion,
   1997   CheckJNI::GetLongArrayRegion,
   1998   CheckJNI::GetFloatArrayRegion,
   1999   CheckJNI::GetDoubleArrayRegion,
   2000   CheckJNI::SetBooleanArrayRegion,
   2001   CheckJNI::SetByteArrayRegion,
   2002   CheckJNI::SetCharArrayRegion,
   2003   CheckJNI::SetShortArrayRegion,
   2004   CheckJNI::SetIntArrayRegion,
   2005   CheckJNI::SetLongArrayRegion,
   2006   CheckJNI::SetFloatArrayRegion,
   2007   CheckJNI::SetDoubleArrayRegion,
   2008   CheckJNI::RegisterNatives,
   2009   CheckJNI::UnregisterNatives,
   2010   CheckJNI::MonitorEnter,
   2011   CheckJNI::MonitorExit,
   2012   CheckJNI::GetJavaVM,
   2013   CheckJNI::GetStringRegion,
   2014   CheckJNI::GetStringUTFRegion,
   2015   CheckJNI::GetPrimitiveArrayCritical,
   2016   CheckJNI::ReleasePrimitiveArrayCritical,
   2017   CheckJNI::GetStringCritical,
   2018   CheckJNI::ReleaseStringCritical,
   2019   CheckJNI::NewWeakGlobalRef,
   2020   CheckJNI::DeleteWeakGlobalRef,
   2021   CheckJNI::ExceptionCheck,
   2022   CheckJNI::NewDirectByteBuffer,
   2023   CheckJNI::GetDirectBufferAddress,
   2024   CheckJNI::GetDirectBufferCapacity,
   2025   CheckJNI::GetObjectRefType,
   2026 };
   2027 
   2028 const JNINativeInterface* GetCheckJniNativeInterface() {
   2029   return &gCheckNativeInterface;
   2030 }
   2031 
   2032 class CheckJII {
   2033  public:
   2034   static jint DestroyJavaVM(JavaVM* vm) {
   2035     ScopedCheck sc(vm, false, __FUNCTION__);
   2036     sc.Check(true, "v", vm);
   2037     return CHECK_JNI_EXIT("I", BaseVm(vm)->DestroyJavaVM(vm));
   2038   }
   2039 
   2040   static jint AttachCurrentThread(JavaVM* vm, JNIEnv** p_env, void* thr_args) {
   2041     ScopedCheck sc(vm, false, __FUNCTION__);
   2042     sc.Check(true, "vpp", vm, p_env, thr_args);
   2043     return CHECK_JNI_EXIT("I", BaseVm(vm)->AttachCurrentThread(vm, p_env, thr_args));
   2044   }
   2045 
   2046   static jint AttachCurrentThreadAsDaemon(JavaVM* vm, JNIEnv** p_env, void* thr_args) {
   2047     ScopedCheck sc(vm, false, __FUNCTION__);
   2048     sc.Check(true, "vpp", vm, p_env, thr_args);
   2049     return CHECK_JNI_EXIT("I", BaseVm(vm)->AttachCurrentThreadAsDaemon(vm, p_env, thr_args));
   2050   }
   2051 
   2052   static jint DetachCurrentThread(JavaVM* vm) {
   2053     ScopedCheck sc(vm, true, __FUNCTION__);
   2054     sc.Check(true, "v", vm);
   2055     return CHECK_JNI_EXIT("I", BaseVm(vm)->DetachCurrentThread(vm));
   2056   }
   2057 
   2058   static jint GetEnv(JavaVM* vm, void** env, jint version) {
   2059     ScopedCheck sc(vm, true, __FUNCTION__);
   2060     sc.Check(true, "vpI", vm);
   2061     return CHECK_JNI_EXIT("I", BaseVm(vm)->GetEnv(vm, env, version));
   2062   }
   2063 
   2064  private:
   2065   static inline const JNIInvokeInterface* BaseVm(JavaVM* vm) {
   2066     return reinterpret_cast<JavaVMExt*>(vm)->unchecked_functions;
   2067   }
   2068 };
   2069 
   2070 const JNIInvokeInterface gCheckInvokeInterface = {
   2071   NULL,  // reserved0
   2072   NULL,  // reserved1
   2073   NULL,  // reserved2
   2074   CheckJII::DestroyJavaVM,
   2075   CheckJII::AttachCurrentThread,
   2076   CheckJII::DetachCurrentThread,
   2077   CheckJII::GetEnv,
   2078   CheckJII::AttachCurrentThreadAsDaemon
   2079 };
   2080 
   2081 const JNIInvokeInterface* GetCheckJniInvokeInterface() {
   2082   return &gCheckInvokeInterface;
   2083 }
   2084 
   2085 }  // namespace art
   2086