Home | History | Annotate | Download | only in runtime
      1 /*
      2  * Copyright (C) 2011 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 "android-base/stringprintf.h"
     20 
     21 #include "art_method-inl.h"
     22 #include "common_compiler_test.h"
     23 #include "indirect_reference_table.h"
     24 #include "java_vm_ext.h"
     25 #include "jni_env_ext.h"
     26 #include "mirror/string-inl.h"
     27 #include "scoped_thread_state_change-inl.h"
     28 #include "ScopedLocalRef.h"
     29 
     30 namespace art {
     31 
     32 using android::base::StringPrintf;
     33 
     34 // TODO: Convert to CommonRuntimeTest. Currently MakeExecutable is used.
     35 class JniInternalTest : public CommonCompilerTest {
     36  protected:
     37   virtual void SetUp() {
     38     CommonCompilerTest::SetUp();
     39 
     40     vm_ = Runtime::Current()->GetJavaVM();
     41 
     42     // Turn on -verbose:jni for the JNI tests.
     43     // gLogVerbosity.jni = true;
     44 
     45     vm_->AttachCurrentThread(&env_, nullptr);
     46 
     47     ScopedLocalRef<jclass> aioobe(env_,
     48                                   env_->FindClass("java/lang/ArrayIndexOutOfBoundsException"));
     49     CHECK(aioobe.get() != nullptr);
     50     aioobe_ = reinterpret_cast<jclass>(env_->NewGlobalRef(aioobe.get()));
     51 
     52     ScopedLocalRef<jclass> ase(env_, env_->FindClass("java/lang/ArrayStoreException"));
     53     CHECK(ase.get() != nullptr);
     54     ase_ = reinterpret_cast<jclass>(env_->NewGlobalRef(ase.get()));
     55 
     56     ScopedLocalRef<jclass> sioobe(env_,
     57                                   env_->FindClass("java/lang/StringIndexOutOfBoundsException"));
     58     CHECK(sioobe.get() != nullptr);
     59     sioobe_ = reinterpret_cast<jclass>(env_->NewGlobalRef(sioobe.get()));
     60   }
     61 
     62   void ExpectException(jclass exception_class) {
     63     ScopedObjectAccess soa(env_);
     64     EXPECT_TRUE(env_->ExceptionCheck())
     65         << mirror::Class::PrettyDescriptor(soa.Decode<mirror::Class>(exception_class));
     66     jthrowable exception = env_->ExceptionOccurred();
     67     EXPECT_NE(nullptr, exception);
     68     env_->ExceptionClear();
     69     EXPECT_TRUE(env_->IsInstanceOf(exception, exception_class));
     70   }
     71 
     72   void CleanUpJniEnv() {
     73     if (aioobe_ != nullptr) {
     74       env_->DeleteGlobalRef(aioobe_);
     75       aioobe_ = nullptr;
     76     }
     77     if (ase_ != nullptr) {
     78       env_->DeleteGlobalRef(ase_);
     79       ase_ = nullptr;
     80     }
     81     if (sioobe_ != nullptr) {
     82       env_->DeleteGlobalRef(sioobe_);
     83       sioobe_ = nullptr;
     84     }
     85   }
     86 
     87   virtual void TearDown() OVERRIDE {
     88     CleanUpJniEnv();
     89     CommonCompilerTest::TearDown();
     90   }
     91 
     92   jclass GetPrimitiveClass(char descriptor) {
     93     ScopedObjectAccess soa(env_);
     94     mirror::Class* c = class_linker_->FindPrimitiveClass(descriptor);
     95     CHECK(c != nullptr);
     96     return soa.AddLocalReference<jclass>(c);
     97   }
     98 
     99   void ExpectClassFound(const char* name) {
    100     EXPECT_NE(env_->FindClass(name), nullptr) << name;
    101     EXPECT_FALSE(env_->ExceptionCheck()) << name;
    102   }
    103 
    104   void ExpectClassNotFound(const char* name, bool check_jni, const char* check_jni_msg,
    105                            CheckJniAbortCatcher* abort_catcher) {
    106     EXPECT_EQ(env_->FindClass(name), nullptr) << name;
    107     if (!check_jni || check_jni_msg == nullptr) {
    108       EXPECT_TRUE(env_->ExceptionCheck()) << name;
    109       env_->ExceptionClear();
    110     } else {
    111       abort_catcher->Check(check_jni_msg);
    112     }
    113   }
    114 
    115   void FindClassTest(bool check_jni) {
    116     bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
    117     CheckJniAbortCatcher check_jni_abort_catcher;
    118 
    119     // Null argument is always an abort.
    120     env_->FindClass(nullptr);
    121     check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL"
    122                                             : "name == null");
    123 
    124     // Reference types...
    125     ExpectClassFound("java/lang/String");
    126     // ...for arrays too, where you must include "L;".
    127     ExpectClassFound("[Ljava/lang/String;");
    128     // Primitive arrays are okay too, if the primitive type is valid.
    129     ExpectClassFound("[C");
    130 
    131     // But primitive types aren't allowed...
    132     ExpectClassNotFound("C", check_jni, nullptr, &check_jni_abort_catcher);
    133     ExpectClassNotFound("V", check_jni, nullptr, &check_jni_abort_catcher);
    134     ExpectClassNotFound("K", check_jni, nullptr, &check_jni_abort_catcher);
    135 
    136     if (check_jni) {
    137       // Check JNI will reject invalid class names as aborts but without pending exceptions.
    138       EXPECT_EQ(env_->FindClass("java.lang.String"), nullptr);
    139       EXPECT_FALSE(env_->ExceptionCheck());
    140       check_jni_abort_catcher.Check("illegal class name 'java.lang.String'");
    141 
    142       EXPECT_EQ(env_->FindClass("[Ljava.lang.String;"), nullptr);
    143       EXPECT_FALSE(env_->ExceptionCheck());
    144       check_jni_abort_catcher.Check("illegal class name '[Ljava.lang.String;'");
    145     } else {
    146       // Without check JNI we're tolerant and replace '.' with '/'.
    147       ExpectClassFound("java.lang.String");
    148       ExpectClassFound("[Ljava.lang.String;");
    149     }
    150 
    151     ExpectClassNotFound("Ljava.lang.String;", check_jni, "illegal class name 'Ljava.lang.String;'",
    152                         &check_jni_abort_catcher);
    153     ExpectClassNotFound("[java.lang.String", check_jni, "illegal class name '[java.lang.String'",
    154                         &check_jni_abort_catcher);
    155 
    156     // You can't include the "L;" in a JNI class descriptor.
    157     ExpectClassNotFound("Ljava/lang/String;", check_jni, "illegal class name 'Ljava/lang/String;'",
    158                         &check_jni_abort_catcher);
    159 
    160     // But you must include it for an array of any reference type.
    161     ExpectClassNotFound("[java/lang/String", check_jni, "illegal class name '[java/lang/String'",
    162                         &check_jni_abort_catcher);
    163 
    164     ExpectClassNotFound("[K", check_jni, "illegal class name '[K'", &check_jni_abort_catcher);
    165 
    166     // Void arrays aren't allowed.
    167     ExpectClassNotFound("[V", check_jni, "illegal class name '[V'", &check_jni_abort_catcher);
    168 
    169     EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
    170   }
    171 
    172   void GetFieldIdBadArgumentTest(bool check_jni) {
    173     bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
    174     CheckJniAbortCatcher check_jni_abort_catcher;
    175 
    176     jclass c = env_->FindClass("java/lang/String");
    177     ASSERT_NE(c, nullptr);
    178 
    179     jfieldID fid = env_->GetFieldID(nullptr, "count", "I");
    180     EXPECT_EQ(nullptr, fid);
    181     check_jni_abort_catcher.Check(check_jni ? "GetFieldID received NULL jclass"
    182                                             : "java_class == null");
    183     fid = env_->GetFieldID(c, nullptr, "I");
    184     EXPECT_EQ(nullptr, fid);
    185     check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL"
    186                                             : "name == null");
    187     fid = env_->GetFieldID(c, "count", nullptr);
    188     EXPECT_EQ(nullptr, fid);
    189     check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL"
    190                                             : "sig == null");
    191 
    192     EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
    193   }
    194 
    195   void GetStaticFieldIdBadArgumentTest(bool check_jni) {
    196     bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
    197     CheckJniAbortCatcher check_jni_abort_catcher;
    198 
    199     jclass c = env_->FindClass("java/lang/String");
    200     ASSERT_NE(c, nullptr);
    201 
    202     jfieldID fid = env_->GetStaticFieldID(nullptr, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
    203     EXPECT_EQ(nullptr, fid);
    204     check_jni_abort_catcher.Check(check_jni ? "GetStaticFieldID received NULL jclass"
    205                                             : "java_class == null");
    206     fid = env_->GetStaticFieldID(c, nullptr, "Ljava/util/Comparator;");
    207     EXPECT_EQ(nullptr, fid);
    208     check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL"
    209                                             : "name == null");
    210     fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", nullptr);
    211     EXPECT_EQ(nullptr, fid);
    212     check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL"
    213                                             : "sig == null");
    214 
    215     EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
    216   }
    217 
    218   void GetMethodIdBadArgumentTest(bool check_jni) {
    219     bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
    220     CheckJniAbortCatcher check_jni_abort_catcher;
    221 
    222     jmethodID method = env_->GetMethodID(nullptr, "<init>", "(Ljava/lang/String;)V");
    223     EXPECT_EQ(nullptr, method);
    224     check_jni_abort_catcher.Check(check_jni ? "GetMethodID received NULL jclass"
    225                                             : "java_class == null");
    226     jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
    227     ASSERT_TRUE(jlnsme != nullptr);
    228     method = env_->GetMethodID(jlnsme, nullptr, "(Ljava/lang/String;)V");
    229     EXPECT_EQ(nullptr, method);
    230     check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL"
    231                                             : "name == null");
    232     method = env_->GetMethodID(jlnsme, "<init>", nullptr);
    233     EXPECT_EQ(nullptr, method);
    234     check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL"
    235                                             : "sig == null");
    236 
    237     EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
    238   }
    239 
    240   void GetStaticMethodIdBadArgumentTest(bool check_jni) {
    241     bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
    242     CheckJniAbortCatcher check_jni_abort_catcher;
    243 
    244     jmethodID method = env_->GetStaticMethodID(nullptr, "valueOf", "(I)Ljava/lang/String;");
    245     EXPECT_EQ(nullptr, method);
    246     check_jni_abort_catcher.Check(check_jni ? "GetStaticMethodID received NULL jclass"
    247                                             : "java_class == null");
    248     jclass jlstring = env_->FindClass("java/lang/String");
    249     method = env_->GetStaticMethodID(jlstring, nullptr, "(I)Ljava/lang/String;");
    250     EXPECT_EQ(nullptr, method);
    251     check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL"
    252                                             : "name == null");
    253     method = env_->GetStaticMethodID(jlstring, "valueOf", nullptr);
    254     EXPECT_EQ(nullptr, method);
    255     check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL"
    256                                             : "sig == null");
    257 
    258     EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
    259   }
    260 
    261   void GetFromReflectedField_ToReflectedFieldBadArgumentTest(bool check_jni) {
    262     bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
    263     CheckJniAbortCatcher check_jni_abort_catcher;
    264 
    265     jclass c = env_->FindClass("java/lang/String");
    266     ASSERT_NE(c, nullptr);
    267     jfieldID fid = env_->GetFieldID(c, "count", "I");
    268     ASSERT_NE(fid, nullptr);
    269 
    270     // Check class argument for null argument, not checked in non-check JNI.
    271     jobject field = env_->ToReflectedField(nullptr, fid, JNI_FALSE);
    272     if (check_jni) {
    273       EXPECT_EQ(field, nullptr);
    274       check_jni_abort_catcher.Check("ToReflectedField received NULL jclass");
    275     } else {
    276       EXPECT_NE(field, nullptr);
    277     }
    278 
    279     field = env_->ToReflectedField(c, nullptr, JNI_FALSE);
    280     EXPECT_EQ(field, nullptr);
    281     check_jni_abort_catcher.Check(check_jni ? "jfieldID was NULL"
    282                                             : "fid == null");
    283 
    284     fid = env_->FromReflectedField(nullptr);
    285     ASSERT_EQ(fid, nullptr);
    286     check_jni_abort_catcher.Check(check_jni ? "expected non-null java.lang.reflect.Field"
    287                                             : "jlr_field == null");
    288 
    289     EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
    290   }
    291 
    292   void GetFromReflectedMethod_ToReflectedMethodBadArgumentTest(bool check_jni) {
    293     bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
    294     CheckJniAbortCatcher check_jni_abort_catcher;
    295 
    296     jclass c = env_->FindClass("java/lang/String");
    297     ASSERT_NE(c, nullptr);
    298     jmethodID mid = env_->GetMethodID(c, "<init>", "()V");
    299     ASSERT_NE(mid, nullptr);
    300 
    301     // Check class argument for null argument, not checked in non-check JNI.
    302     jobject method = env_->ToReflectedMethod(nullptr, mid, JNI_FALSE);
    303     if (check_jni) {
    304       EXPECT_EQ(method, nullptr);
    305       check_jni_abort_catcher.Check("ToReflectedMethod received NULL jclass");
    306     } else {
    307       EXPECT_NE(method, nullptr);
    308     }
    309 
    310     method = env_->ToReflectedMethod(c, nullptr, JNI_FALSE);
    311     EXPECT_EQ(method, nullptr);
    312     check_jni_abort_catcher.Check(check_jni ? "jmethodID was NULL"
    313                                             : "mid == null");
    314     mid = env_->FromReflectedMethod(method);
    315     ASSERT_EQ(mid, nullptr);
    316     check_jni_abort_catcher.Check(check_jni ? "expected non-null method" : "jlr_method == null");
    317 
    318     EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
    319   }
    320 
    321   void RegisterAndUnregisterNativesBadArguments(bool check_jni,
    322                                                 CheckJniAbortCatcher* check_jni_abort_catcher) {
    323     bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
    324     // Passing a class of null is a failure.
    325     {
    326       JNINativeMethod methods[] = { };
    327       EXPECT_EQ(env_->RegisterNatives(nullptr, methods, 0), JNI_ERR);
    328       check_jni_abort_catcher->Check(check_jni ? "RegisterNatives received NULL jclass"
    329                                                : "java_class == null");
    330     }
    331 
    332     // Passing methods as null is a failure.
    333     jclass jlobject = env_->FindClass("java/lang/Object");
    334     EXPECT_EQ(env_->RegisterNatives(jlobject, nullptr, 1), JNI_ERR);
    335     check_jni_abort_catcher->Check("methods == null");
    336 
    337     // Unregisters null is a failure.
    338     EXPECT_EQ(env_->UnregisterNatives(nullptr), JNI_ERR);
    339     check_jni_abort_catcher->Check(check_jni ? "UnregisterNatives received NULL jclass"
    340                                              : "java_class == null");
    341 
    342     EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
    343   }
    344 
    345 
    346   void GetPrimitiveArrayElementsOfWrongType(bool check_jni) {
    347     bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
    348     CheckJniAbortCatcher jni_abort_catcher;
    349 
    350     jbooleanArray array = env_->NewBooleanArray(10);
    351     jboolean is_copy;
    352     EXPECT_EQ(env_->GetByteArrayElements(reinterpret_cast<jbyteArray>(array), &is_copy), nullptr);
    353     jni_abort_catcher.Check(
    354         check_jni ? "incompatible array type boolean[] expected byte[]"
    355             : "attempt to get byte primitive array elements with an object of type boolean[]");
    356     EXPECT_EQ(env_->GetShortArrayElements(reinterpret_cast<jshortArray>(array), &is_copy), nullptr);
    357     jni_abort_catcher.Check(
    358         check_jni ? "incompatible array type boolean[] expected short[]"
    359             : "attempt to get short primitive array elements with an object of type boolean[]");
    360     EXPECT_EQ(env_->GetCharArrayElements(reinterpret_cast<jcharArray>(array), &is_copy), nullptr);
    361     jni_abort_catcher.Check(
    362         check_jni ? "incompatible array type boolean[] expected char[]"
    363             : "attempt to get char primitive array elements with an object of type boolean[]");
    364     EXPECT_EQ(env_->GetIntArrayElements(reinterpret_cast<jintArray>(array), &is_copy), nullptr);
    365     jni_abort_catcher.Check(
    366         check_jni ? "incompatible array type boolean[] expected int[]"
    367             : "attempt to get int primitive array elements with an object of type boolean[]");
    368     EXPECT_EQ(env_->GetLongArrayElements(reinterpret_cast<jlongArray>(array), &is_copy), nullptr);
    369     jni_abort_catcher.Check(
    370         check_jni ? "incompatible array type boolean[] expected long[]"
    371             : "attempt to get long primitive array elements with an object of type boolean[]");
    372     EXPECT_EQ(env_->GetFloatArrayElements(reinterpret_cast<jfloatArray>(array), &is_copy), nullptr);
    373     jni_abort_catcher.Check(
    374         check_jni ? "incompatible array type boolean[] expected float[]"
    375             : "attempt to get float primitive array elements with an object of type boolean[]");
    376     EXPECT_EQ(env_->GetDoubleArrayElements(reinterpret_cast<jdoubleArray>(array), &is_copy), nullptr);
    377     jni_abort_catcher.Check(
    378         check_jni ? "incompatible array type boolean[] expected double[]"
    379             : "attempt to get double primitive array elements with an object of type boolean[]");
    380     jbyteArray array2 = env_->NewByteArray(10);
    381     EXPECT_EQ(env_->GetBooleanArrayElements(reinterpret_cast<jbooleanArray>(array2), &is_copy),
    382               nullptr);
    383     jni_abort_catcher.Check(
    384         check_jni ? "incompatible array type byte[] expected boolean[]"
    385             : "attempt to get boolean primitive array elements with an object of type byte[]");
    386     jobject object = env_->NewStringUTF("Test String");
    387     EXPECT_EQ(env_->GetBooleanArrayElements(reinterpret_cast<jbooleanArray>(object), &is_copy),
    388               nullptr);
    389     jni_abort_catcher.Check(
    390         check_jni ? "jarray argument has non-array type: java.lang.String"
    391         : "attempt to get boolean primitive array elements with an object of type java.lang.String");
    392 
    393     EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
    394   }
    395 
    396   void ReleasePrimitiveArrayElementsOfWrongType(bool check_jni) {
    397     bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
    398     CheckJniAbortCatcher jni_abort_catcher;
    399     {
    400       jbooleanArray array = env_->NewBooleanArray(10);
    401       ASSERT_TRUE(array != nullptr);
    402       jboolean is_copy;
    403       jboolean* elements = env_->GetBooleanArrayElements(array, &is_copy);
    404       ASSERT_TRUE(elements != nullptr);
    405       env_->ReleaseByteArrayElements(reinterpret_cast<jbyteArray>(array),
    406                                      reinterpret_cast<jbyte*>(elements), 0);
    407       jni_abort_catcher.Check(
    408           check_jni ? "incompatible array type boolean[] expected byte[]"
    409               : "attempt to release byte primitive array elements with an object of type boolean[]");
    410       env_->ReleaseShortArrayElements(reinterpret_cast<jshortArray>(array),
    411                                       reinterpret_cast<jshort*>(elements), 0);
    412       jni_abort_catcher.Check(
    413           check_jni ? "incompatible array type boolean[] expected short[]"
    414               : "attempt to release short primitive array elements with an object of type boolean[]");
    415       env_->ReleaseCharArrayElements(reinterpret_cast<jcharArray>(array),
    416                                      reinterpret_cast<jchar*>(elements), 0);
    417       jni_abort_catcher.Check(
    418           check_jni ? "incompatible array type boolean[] expected char[]"
    419               : "attempt to release char primitive array elements with an object of type boolean[]");
    420       env_->ReleaseIntArrayElements(reinterpret_cast<jintArray>(array),
    421                                     reinterpret_cast<jint*>(elements), 0);
    422       jni_abort_catcher.Check(
    423           check_jni ? "incompatible array type boolean[] expected int[]"
    424               : "attempt to release int primitive array elements with an object of type boolean[]");
    425       env_->ReleaseLongArrayElements(reinterpret_cast<jlongArray>(array),
    426                                      reinterpret_cast<jlong*>(elements), 0);
    427       jni_abort_catcher.Check(
    428           check_jni ? "incompatible array type boolean[] expected long[]"
    429               : "attempt to release long primitive array elements with an object of type boolean[]");
    430       env_->ReleaseFloatArrayElements(reinterpret_cast<jfloatArray>(array),
    431                                       reinterpret_cast<jfloat*>(elements), 0);
    432       jni_abort_catcher.Check(
    433           check_jni ? "incompatible array type boolean[] expected float[]"
    434               : "attempt to release float primitive array elements with an object of type boolean[]");
    435       env_->ReleaseDoubleArrayElements(reinterpret_cast<jdoubleArray>(array),
    436                                        reinterpret_cast<jdouble*>(elements), 0);
    437       jni_abort_catcher.Check(
    438           check_jni ? "incompatible array type boolean[] expected double[]"
    439               : "attempt to release double primitive array elements with an object of type boolean[]");
    440 
    441       // Don't leak the elements array.
    442       env_->ReleaseBooleanArrayElements(array, elements, 0);
    443     }
    444     {
    445       jbyteArray array = env_->NewByteArray(10);
    446       jboolean is_copy;
    447       jbyte* elements = env_->GetByteArrayElements(array, &is_copy);
    448 
    449       env_->ReleaseBooleanArrayElements(reinterpret_cast<jbooleanArray>(array),
    450                                         reinterpret_cast<jboolean*>(elements), 0);
    451       jni_abort_catcher.Check(
    452           check_jni ? "incompatible array type byte[] expected boolean[]"
    453               : "attempt to release boolean primitive array elements with an object of type byte[]");
    454       jobject object = env_->NewStringUTF("Test String");
    455       env_->ReleaseBooleanArrayElements(reinterpret_cast<jbooleanArray>(object),
    456                                         reinterpret_cast<jboolean*>(elements), 0);
    457       jni_abort_catcher.Check(
    458           check_jni ? "jarray argument has non-array type: java.lang.String"
    459               : "attempt to release boolean primitive array elements with an object of type "
    460               "java.lang.String");
    461 
    462       // Don't leak the elements array.
    463       env_->ReleaseByteArrayElements(array, elements, 0);
    464     }
    465     EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
    466   }
    467 
    468   void GetReleasePrimitiveArrayCriticalOfWrongType(bool check_jni) {
    469     bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
    470     CheckJniAbortCatcher jni_abort_catcher;
    471 
    472     jobject object = env_->NewStringUTF("Test String");
    473     jboolean is_copy;
    474     void* elements = env_->GetPrimitiveArrayCritical(reinterpret_cast<jarray>(object), &is_copy);
    475     jni_abort_catcher.Check(check_jni ? "jarray argument has non-array type: java.lang.String"
    476         : "expected primitive array, given java.lang.String");
    477     env_->ReleasePrimitiveArrayCritical(reinterpret_cast<jarray>(object), elements, 0);
    478     jni_abort_catcher.Check(check_jni ? "jarray argument has non-array type: java.lang.String"
    479         : "expected primitive array, given java.lang.String");
    480 
    481     EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
    482   }
    483 
    484   void GetPrimitiveArrayRegionElementsOfWrongType(bool check_jni) {
    485     bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
    486     CheckJniAbortCatcher jni_abort_catcher;
    487     constexpr size_t kLength = 10;
    488     jbooleanArray array = env_->NewBooleanArray(kLength);
    489     ASSERT_TRUE(array != nullptr);
    490     jboolean elements[kLength];
    491     env_->GetByteArrayRegion(reinterpret_cast<jbyteArray>(array), 0, kLength,
    492                              reinterpret_cast<jbyte*>(elements));
    493     jni_abort_catcher.Check(
    494         check_jni ? "incompatible array type boolean[] expected byte[]"
    495             : "attempt to get region of byte primitive array elements with an object of type boolean[]");
    496     env_->GetShortArrayRegion(reinterpret_cast<jshortArray>(array), 0, kLength,
    497                               reinterpret_cast<jshort*>(elements));
    498     jni_abort_catcher.Check(
    499         check_jni ? "incompatible array type boolean[] expected short[]"
    500             : "attempt to get region of short primitive array elements with an object of type boolean[]");
    501     env_->GetCharArrayRegion(reinterpret_cast<jcharArray>(array), 0, kLength,
    502                              reinterpret_cast<jchar*>(elements));
    503     jni_abort_catcher.Check(
    504         check_jni ? "incompatible array type boolean[] expected char[]"
    505             : "attempt to get region of char primitive array elements with an object of type boolean[]");
    506     env_->GetIntArrayRegion(reinterpret_cast<jintArray>(array), 0, kLength,
    507                             reinterpret_cast<jint*>(elements));
    508     jni_abort_catcher.Check(
    509         check_jni ? "incompatible array type boolean[] expected int[]"
    510             : "attempt to get region of int primitive array elements with an object of type boolean[]");
    511     env_->GetLongArrayRegion(reinterpret_cast<jlongArray>(array), 0, kLength,
    512                              reinterpret_cast<jlong*>(elements));
    513     jni_abort_catcher.Check(
    514         check_jni ? "incompatible array type boolean[] expected long[]"
    515             : "attempt to get region of long primitive array elements with an object of type boolean[]");
    516     env_->GetFloatArrayRegion(reinterpret_cast<jfloatArray>(array), 0, kLength,
    517                               reinterpret_cast<jfloat*>(elements));
    518     jni_abort_catcher.Check(
    519         check_jni ? "incompatible array type boolean[] expected float[]"
    520             : "attempt to get region of float primitive array elements with an object of type boolean[]");
    521     env_->GetDoubleArrayRegion(reinterpret_cast<jdoubleArray>(array), 0, kLength,
    522                                reinterpret_cast<jdouble*>(elements));
    523     jni_abort_catcher.Check(
    524         check_jni ? "incompatible array type boolean[] expected double[]"
    525             : "attempt to get region of double primitive array elements with an object of type boolean[]");
    526     jbyteArray array2 = env_->NewByteArray(10);
    527     env_->GetBooleanArrayRegion(reinterpret_cast<jbooleanArray>(array2), 0, kLength,
    528                                 reinterpret_cast<jboolean*>(elements));
    529     jni_abort_catcher.Check(
    530         check_jni ? "incompatible array type byte[] expected boolean[]"
    531             : "attempt to get region of boolean primitive array elements with an object of type byte[]");
    532     jobject object = env_->NewStringUTF("Test String");
    533     env_->GetBooleanArrayRegion(reinterpret_cast<jbooleanArray>(object), 0, kLength,
    534                                 reinterpret_cast<jboolean*>(elements));
    535     jni_abort_catcher.Check(check_jni ? "jarray argument has non-array type: java.lang.String"
    536         : "attempt to get region of boolean primitive array elements with an object of type "
    537           "java.lang.String");
    538 
    539     EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
    540   }
    541 
    542   void SetPrimitiveArrayRegionElementsOfWrongType(bool check_jni) {
    543     bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
    544     CheckJniAbortCatcher jni_abort_catcher;
    545     constexpr size_t kLength = 10;
    546     jbooleanArray array = env_->NewBooleanArray(kLength);
    547     ASSERT_TRUE(array != nullptr);
    548     jboolean elements[kLength];
    549     env_->SetByteArrayRegion(reinterpret_cast<jbyteArray>(array), 0, kLength,
    550                              reinterpret_cast<jbyte*>(elements));
    551     jni_abort_catcher.Check(
    552         check_jni ? "incompatible array type boolean[] expected byte[]"
    553             : "attempt to set region of byte primitive array elements with an object of type boolean[]");
    554     env_->SetShortArrayRegion(reinterpret_cast<jshortArray>(array), 0, kLength,
    555                               reinterpret_cast<jshort*>(elements));
    556     jni_abort_catcher.Check(
    557         check_jni ? "incompatible array type boolean[] expected short[]"
    558             : "attempt to set region of short primitive array elements with an object of type boolean[]");
    559     env_->SetCharArrayRegion(reinterpret_cast<jcharArray>(array), 0, kLength,
    560                              reinterpret_cast<jchar*>(elements));
    561     jni_abort_catcher.Check(
    562         check_jni ? "incompatible array type boolean[] expected char[]"
    563             : "attempt to set region of char primitive array elements with an object of type boolean[]");
    564     env_->SetIntArrayRegion(reinterpret_cast<jintArray>(array), 0, kLength,
    565                             reinterpret_cast<jint*>(elements));
    566     jni_abort_catcher.Check(
    567         check_jni ? "incompatible array type boolean[] expected int[]"
    568             : "attempt to set region of int primitive array elements with an object of type boolean[]");
    569     env_->SetLongArrayRegion(reinterpret_cast<jlongArray>(array), 0, kLength,
    570                              reinterpret_cast<jlong*>(elements));
    571     jni_abort_catcher.Check(
    572         check_jni ? "incompatible array type boolean[] expected long[]"
    573             : "attempt to set region of long primitive array elements with an object of type boolean[]");
    574     env_->SetFloatArrayRegion(reinterpret_cast<jfloatArray>(array), 0, kLength,
    575                               reinterpret_cast<jfloat*>(elements));
    576     jni_abort_catcher.Check(
    577         check_jni ? "incompatible array type boolean[] expected float[]"
    578             : "attempt to set region of float primitive array elements with an object of type boolean[]");
    579     env_->SetDoubleArrayRegion(reinterpret_cast<jdoubleArray>(array), 0, kLength,
    580                                reinterpret_cast<jdouble*>(elements));
    581     jni_abort_catcher.Check(
    582         check_jni ? "incompatible array type boolean[] expected double[]"
    583             : "attempt to set region of double primitive array elements with an object of type boolean[]");
    584     jbyteArray array2 = env_->NewByteArray(10);
    585     env_->SetBooleanArrayRegion(reinterpret_cast<jbooleanArray>(array2), 0, kLength,
    586                                 reinterpret_cast<jboolean*>(elements));
    587     jni_abort_catcher.Check(
    588         check_jni ? "incompatible array type byte[] expected boolean[]"
    589             : "attempt to set region of boolean primitive array elements with an object of type byte[]");
    590     jobject object = env_->NewStringUTF("Test String");
    591     env_->SetBooleanArrayRegion(reinterpret_cast<jbooleanArray>(object), 0, kLength,
    592                                 reinterpret_cast<jboolean*>(elements));
    593     jni_abort_catcher.Check(check_jni ? "jarray argument has non-array type: java.lang.String"
    594         : "attempt to set region of boolean primitive array elements with an object of type "
    595           "java.lang.String");
    596     EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
    597   }
    598 
    599   void NewObjectArrayBadArguments(bool check_jni) {
    600     bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
    601     CheckJniAbortCatcher jni_abort_catcher;
    602 
    603     jclass element_class = env_->FindClass("java/lang/String");
    604     ASSERT_NE(element_class, nullptr);
    605 
    606     env_->NewObjectArray(-1, element_class, nullptr);
    607     jni_abort_catcher.Check(check_jni ? "negative jsize: -1" : "negative array length: -1");
    608 
    609     env_->NewObjectArray(std::numeric_limits<jint>::min(), element_class, nullptr);
    610     jni_abort_catcher.Check(check_jni ? "negative jsize: -2147483648"
    611         : "negative array length: -2147483648");
    612 
    613     EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
    614   }
    615 
    616   void SetUpForTest(bool direct, const char* method_name, const char* method_sig,
    617                     void* native_fnptr) {
    618     // Initialize class loader and set generic JNI entrypoint.
    619     // Note: this code is adapted from the jni_compiler_test, and taken with minimal modifications.
    620     if (!runtime_->IsStarted()) {
    621       {
    622         ScopedObjectAccess soa(Thread::Current());
    623         class_loader_ = LoadDex("MyClassNatives");
    624         StackHandleScope<1> hs(soa.Self());
    625         Handle<mirror::ClassLoader> loader(
    626             hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader_)));
    627         mirror::Class* c = class_linker_->FindClass(soa.Self(), "LMyClassNatives;", loader);
    628         const auto pointer_size = class_linker_->GetImagePointerSize();
    629         ArtMethod* method = direct ? c->FindDirectMethod(method_name, method_sig, pointer_size) :
    630             c->FindVirtualMethod(method_name, method_sig, pointer_size);
    631         ASSERT_TRUE(method != nullptr) << method_name << " " << method_sig;
    632         method->SetEntryPointFromQuickCompiledCode(class_linker_->GetRuntimeQuickGenericJniStub());
    633       }
    634       // Start runtime.
    635       Thread::Current()->TransitionFromSuspendedToRunnable();
    636       bool started = runtime_->Start();
    637       CHECK(started);
    638     }
    639     // JNI operations after runtime start.
    640     env_ = Thread::Current()->GetJniEnv();
    641     jklass_ = env_->FindClass("MyClassNatives");
    642     ASSERT_TRUE(jklass_ != nullptr) << method_name << " " << method_sig;
    643 
    644     if (direct) {
    645       jmethod_ = env_->GetStaticMethodID(jklass_, method_name, method_sig);
    646     } else {
    647       jmethod_ = env_->GetMethodID(jklass_, method_name, method_sig);
    648     }
    649     ASSERT_TRUE(jmethod_ != nullptr) << method_name << " " << method_sig;
    650 
    651     if (native_fnptr != nullptr) {
    652       JNINativeMethod methods[] = { { method_name, method_sig, native_fnptr } };
    653       ASSERT_EQ(JNI_OK, env_->RegisterNatives(jklass_, methods, 1))
    654           << method_name << " " << method_sig;
    655     } else {
    656       env_->UnregisterNatives(jklass_);
    657     }
    658 
    659     jmethodID constructor = env_->GetMethodID(jklass_, "<init>", "()V");
    660     jobj_ = env_->NewObject(jklass_, constructor);
    661     ASSERT_TRUE(jobj_ != nullptr) << method_name << " " << method_sig;
    662   }
    663 
    664   JavaVMExt* vm_;
    665   JNIEnv* env_;
    666   jclass aioobe_;
    667   jclass ase_;
    668   jclass sioobe_;
    669 
    670   jclass jklass_;
    671   jobject jobj_;
    672   jobject class_loader_;
    673   jmethodID jmethod_;
    674 };
    675 
    676 TEST_F(JniInternalTest, AllocObject) {
    677   jclass c = env_->FindClass("java/lang/String");
    678   ASSERT_NE(c, nullptr);
    679   jobject o = env_->AllocObject(c);
    680   ASSERT_NE(o, nullptr);
    681 
    682   // We have an instance of the class we asked for...
    683   ASSERT_TRUE(env_->IsInstanceOf(o, c));
    684   // ...whose fields haven't been initialized because
    685   // we didn't call a constructor.
    686   // Even with string compression empty string has `count == 0`.
    687   ASSERT_EQ(0, env_->GetIntField(o, env_->GetFieldID(c, "count", "I")));
    688 }
    689 
    690 TEST_F(JniInternalTest, GetVersion) {
    691   ASSERT_EQ(JNI_VERSION_1_6, env_->GetVersion());
    692 }
    693 
    694 TEST_F(JniInternalTest, FindClass) {
    695   // This tests leads to warnings in the log.
    696   ScopedLogSeverity sls(LogSeverity::ERROR);
    697 
    698   FindClassTest(false);
    699   FindClassTest(true);
    700 }
    701 
    702 TEST_F(JniInternalTest, GetFieldID) {
    703   jclass jlnsfe = env_->FindClass("java/lang/NoSuchFieldError");
    704   ASSERT_NE(jlnsfe, nullptr);
    705   jclass c = env_->FindClass("java/lang/String");
    706   ASSERT_NE(c, nullptr);
    707 
    708   // Wrong type.
    709   jfieldID fid = env_->GetFieldID(c, "count", "J");
    710   EXPECT_EQ(nullptr, fid);
    711   ExpectException(jlnsfe);
    712 
    713   // Wrong type where type doesn't exist.
    714   fid = env_->GetFieldID(c, "count", "Lrod/jane/freddy;");
    715   EXPECT_EQ(nullptr, fid);
    716   ExpectException(jlnsfe);
    717 
    718   // Wrong name.
    719   fid = env_->GetFieldID(c, "Count", "I");
    720   EXPECT_EQ(nullptr, fid);
    721   ExpectException(jlnsfe);
    722 
    723   // Good declared field lookup.
    724   fid = env_->GetFieldID(c, "count", "I");
    725   EXPECT_NE(nullptr, fid);
    726   EXPECT_FALSE(env_->ExceptionCheck());
    727 
    728   // Good superclass field lookup.
    729   c = env_->FindClass("java/lang/StringBuilder");
    730   fid = env_->GetFieldID(c, "count", "I");
    731   EXPECT_NE(nullptr, fid);
    732   EXPECT_NE(fid, nullptr);
    733   EXPECT_FALSE(env_->ExceptionCheck());
    734 
    735   // Not instance.
    736   fid = env_->GetFieldID(c, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
    737   EXPECT_EQ(nullptr, fid);
    738   ExpectException(jlnsfe);
    739 
    740   // Bad arguments.
    741   GetFieldIdBadArgumentTest(false);
    742   GetFieldIdBadArgumentTest(true);
    743 }
    744 
    745 TEST_F(JniInternalTest, GetStaticFieldID) {
    746   jclass jlnsfe = env_->FindClass("java/lang/NoSuchFieldError");
    747   ASSERT_NE(jlnsfe, nullptr);
    748   jclass c = env_->FindClass("java/lang/String");
    749   ASSERT_NE(c, nullptr);
    750 
    751   // Wrong type.
    752   jfieldID fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "J");
    753   EXPECT_EQ(nullptr, fid);
    754   ExpectException(jlnsfe);
    755 
    756   // Wrong type where type doesn't exist.
    757   fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "Lrod/jane/freddy;");
    758   EXPECT_EQ(nullptr, fid);
    759   ExpectException(jlnsfe);
    760 
    761   // Wrong name.
    762   fid = env_->GetStaticFieldID(c, "cASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
    763   EXPECT_EQ(nullptr, fid);
    764   ExpectException(jlnsfe);
    765 
    766   // Good declared field lookup.
    767   fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
    768   EXPECT_NE(nullptr, fid);
    769   EXPECT_NE(fid, nullptr);
    770   EXPECT_FALSE(env_->ExceptionCheck());
    771 
    772   // Not static.
    773   fid = env_->GetStaticFieldID(c, "count", "I");
    774   EXPECT_EQ(nullptr, fid);
    775   ExpectException(jlnsfe);
    776 
    777   // Bad arguments.
    778   GetStaticFieldIdBadArgumentTest(false);
    779   GetStaticFieldIdBadArgumentTest(true);
    780 }
    781 
    782 TEST_F(JniInternalTest, GetMethodID) {
    783   jclass jlobject = env_->FindClass("java/lang/Object");
    784   jclass jlstring = env_->FindClass("java/lang/String");
    785   jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
    786   jclass jncrbc = env_->FindClass("java/nio/channels/ReadableByteChannel");
    787 
    788   // Sanity check that no exceptions are pending.
    789   ASSERT_FALSE(env_->ExceptionCheck());
    790 
    791   // Check that java.lang.Object.foo() doesn't exist and NoSuchMethodError is
    792   // a pending exception.
    793   jmethodID method = env_->GetMethodID(jlobject, "foo", "()V");
    794   EXPECT_EQ(nullptr, method);
    795   ExpectException(jlnsme);
    796 
    797   // Check that java.lang.Object.equals() does exist.
    798   method = env_->GetMethodID(jlobject, "equals", "(Ljava/lang/Object;)Z");
    799   EXPECT_NE(nullptr, method);
    800   EXPECT_FALSE(env_->ExceptionCheck());
    801 
    802   // Check that GetMethodID for java.lang.String.valueOf(int) fails as the
    803   // method is static.
    804   method = env_->GetMethodID(jlstring, "valueOf", "(I)Ljava/lang/String;");
    805   EXPECT_EQ(nullptr, method);
    806   ExpectException(jlnsme);
    807 
    808   // Check that GetMethodID for java.lang.NoSuchMethodError.<init>(String) finds the constructor.
    809   method = env_->GetMethodID(jlnsme, "<init>", "(Ljava/lang/String;)V");
    810   EXPECT_NE(nullptr, method);
    811   EXPECT_FALSE(env_->ExceptionCheck());
    812 
    813   // Check that GetMethodID can find a interface method inherited from another interface.
    814   method = env_->GetMethodID(jncrbc, "close", "()V");
    815   EXPECT_NE(nullptr, method);
    816   EXPECT_FALSE(env_->ExceptionCheck());
    817 
    818   // Bad arguments.
    819   GetMethodIdBadArgumentTest(false);
    820   GetMethodIdBadArgumentTest(true);
    821 }
    822 
    823 TEST_F(JniInternalTest, CallVoidMethodNullReceiver) {
    824   jclass jlobject = env_->FindClass("java/lang/Object");
    825   jmethodID method;
    826 
    827   // Check that GetMethodID for java.lang.NoSuchMethodError.<init>(String) finds the constructor.
    828   method = env_->GetMethodID(jlobject, "<init>", "()V");
    829   EXPECT_NE(nullptr, method);
    830   EXPECT_FALSE(env_->ExceptionCheck());
    831 
    832   // Null object to CallVoidMethod.
    833   CheckJniAbortCatcher check_jni_abort_catcher;
    834   env_->CallVoidMethod(nullptr, method);
    835   check_jni_abort_catcher.Check("null");
    836 }
    837 
    838 TEST_F(JniInternalTest, GetStaticMethodID) {
    839   jclass jlobject = env_->FindClass("java/lang/Object");
    840   jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
    841 
    842   // Sanity check that no exceptions are pending
    843   ASSERT_FALSE(env_->ExceptionCheck());
    844 
    845   // Check that java.lang.Object.foo() doesn't exist and NoSuchMethodError is
    846   // a pending exception
    847   jmethodID method = env_->GetStaticMethodID(jlobject, "foo", "()V");
    848   EXPECT_EQ(nullptr, method);
    849   ExpectException(jlnsme);
    850 
    851   // Check that GetStaticMethodID for java.lang.Object.equals(Object) fails as
    852   // the method is not static
    853   method = env_->GetStaticMethodID(jlobject, "equals", "(Ljava/lang/Object;)Z");
    854   EXPECT_EQ(nullptr, method);
    855   ExpectException(jlnsme);
    856 
    857   // Check that java.lang.String.valueOf(int) does exist
    858   jclass jlstring = env_->FindClass("java/lang/String");
    859   method = env_->GetStaticMethodID(jlstring, "valueOf", "(I)Ljava/lang/String;");
    860   EXPECT_NE(nullptr, method);
    861   EXPECT_FALSE(env_->ExceptionCheck());
    862 
    863   // Bad arguments.
    864   GetStaticMethodIdBadArgumentTest(false);
    865   GetStaticMethodIdBadArgumentTest(true);
    866 }
    867 
    868 static size_t GetLocalsCapacity(JNIEnv* env) {
    869   ScopedObjectAccess soa(Thread::Current());
    870   return reinterpret_cast<JNIEnvExt*>(env)->locals.Capacity();
    871 }
    872 
    873 TEST_F(JniInternalTest, FromReflectedField_ToReflectedField) {
    874   jclass jlrField = env_->FindClass("java/lang/reflect/Field");
    875   jclass c = env_->FindClass("java/lang/String");
    876   ASSERT_NE(c, nullptr);
    877   jfieldID fid = env_->GetFieldID(c, "count", "I");
    878   ASSERT_NE(fid, nullptr);
    879   // Turn the fid into a java.lang.reflect.Field...
    880   jobject field = env_->ToReflectedField(c, fid, JNI_FALSE);
    881   size_t capacity_before = GetLocalsCapacity(env_);
    882   for (size_t i = 0; i <= 10; ++i) {
    883     // Regression test for b/18396311, ToReflectedField leaking local refs causing a local
    884     // reference table overflows with 512 references to ArtField
    885     env_->DeleteLocalRef(env_->ToReflectedField(c, fid, JNI_FALSE));
    886   }
    887   size_t capacity_after = GetLocalsCapacity(env_);
    888   ASSERT_EQ(capacity_before, capacity_after);
    889 
    890   ASSERT_NE(c, nullptr);
    891   ASSERT_TRUE(env_->IsInstanceOf(field, jlrField));
    892   // ...and back again.
    893   jfieldID fid2 = env_->FromReflectedField(field);
    894   ASSERT_NE(fid2, nullptr);
    895   // Make sure we can actually use it.
    896   jstring s = env_->NewStringUTF("poop");
    897   if (mirror::kUseStringCompression) {
    898     ASSERT_EQ(mirror::String::GetFlaggedCount(4, /* compressible */ true),
    899               env_->GetIntField(s, fid2));
    900     // Create incompressible string
    901     jstring s_16 = env_->NewStringUTF("\u0444\u0444");
    902     ASSERT_EQ(mirror::String::GetFlaggedCount(2, /* compressible */ false),
    903               env_->GetIntField(s_16, fid2));
    904   } else {
    905     ASSERT_EQ(4, env_->GetIntField(s, fid2));
    906   }
    907   // Bad arguments.
    908   GetFromReflectedField_ToReflectedFieldBadArgumentTest(false);
    909   GetFromReflectedField_ToReflectedFieldBadArgumentTest(true);
    910 }
    911 
    912 TEST_F(JniInternalTest, FromReflectedMethod_ToReflectedMethod) {
    913   jclass jlrMethod = env_->FindClass("java/lang/reflect/Method");
    914   ASSERT_NE(jlrMethod, nullptr);
    915   jclass jlrConstructor = env_->FindClass("java/lang/reflect/Constructor");
    916   ASSERT_NE(jlrConstructor, nullptr);
    917   jclass c = env_->FindClass("java/lang/String");
    918   ASSERT_NE(c, nullptr);
    919 
    920   jmethodID mid = env_->GetMethodID(c, "<init>", "()V");
    921   ASSERT_NE(mid, nullptr);
    922   // Turn the mid into a java.lang.reflect.Constructor...
    923   jobject method = env_->ToReflectedMethod(c, mid, JNI_FALSE);
    924   size_t capacity_before = GetLocalsCapacity(env_);
    925   for (size_t i = 0; i <= 10; ++i) {
    926     // Regression test for b/18396311, ToReflectedMethod leaking local refs causing a local
    927     // reference table overflows with 512 references to ArtMethod
    928     env_->DeleteLocalRef(env_->ToReflectedMethod(c, mid, JNI_FALSE));
    929   }
    930   size_t capacity_after = GetLocalsCapacity(env_);
    931   ASSERT_EQ(capacity_before, capacity_after);
    932   ASSERT_NE(method, nullptr);
    933   ASSERT_TRUE(env_->IsInstanceOf(method, jlrConstructor));
    934   // ...and back again.
    935   jmethodID mid2 = env_->FromReflectedMethod(method);
    936   ASSERT_NE(mid2, nullptr);
    937   // Make sure we can actually use it.
    938   jstring s = reinterpret_cast<jstring>(env_->AllocObject(c));
    939   ASSERT_NE(s, nullptr);
    940   env_->CallVoidMethod(s, mid2);
    941   ASSERT_EQ(JNI_FALSE, env_->ExceptionCheck());
    942   env_->ExceptionClear();
    943 
    944   mid = env_->GetMethodID(c, "length", "()I");
    945   ASSERT_NE(mid, nullptr);
    946   // Turn the mid into a java.lang.reflect.Method...
    947   method = env_->ToReflectedMethod(c, mid, JNI_FALSE);
    948   ASSERT_NE(method, nullptr);
    949   ASSERT_TRUE(env_->IsInstanceOf(method, jlrMethod));
    950   // ...and back again.
    951   mid2 = env_->FromReflectedMethod(method);
    952   ASSERT_NE(mid2, nullptr);
    953   // Make sure we can actually use it.
    954   s = env_->NewStringUTF("poop");
    955   ASSERT_NE(s, nullptr);
    956   ASSERT_EQ(4, env_->CallIntMethod(s, mid2));
    957 
    958   // Bad arguments.
    959   GetFromReflectedMethod_ToReflectedMethodBadArgumentTest(false);
    960   GetFromReflectedMethod_ToReflectedMethodBadArgumentTest(true);
    961 }
    962 
    963 static void BogusMethod() {
    964   // You can't pass null function pointers to RegisterNatives.
    965 }
    966 
    967 TEST_F(JniInternalTest, RegisterAndUnregisterNatives) {
    968   jclass jlobject = env_->FindClass("java/lang/Object");
    969   jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
    970   void* native_function = reinterpret_cast<void*>(BogusMethod);
    971 
    972   // Sanity check that no exceptions are pending.
    973   ASSERT_FALSE(env_->ExceptionCheck());
    974 
    975   // The following can print errors to the log we'd like to ignore.
    976   {
    977     ScopedLogSeverity sls(LogSeverity::FATAL);
    978     // Check that registering method without name causes a NoSuchMethodError.
    979     {
    980       JNINativeMethod methods[] = { { nullptr, "()V", native_function } };
    981       EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_ERR);
    982     }
    983     ExpectException(jlnsme);
    984 
    985     // Check that registering method without signature causes a NoSuchMethodError.
    986     {
    987       JNINativeMethod methods[] = { { "notify", nullptr, native_function } };
    988       EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_ERR);
    989     }
    990     ExpectException(jlnsme);
    991 
    992     // Check that registering method without function causes a NoSuchMethodError.
    993     {
    994       JNINativeMethod methods[] = { { "notify", "()V", nullptr } };
    995       EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_ERR);
    996     }
    997     ExpectException(jlnsme);
    998 
    999     // Check that registering to a non-existent java.lang.Object.foo() causes a NoSuchMethodError.
   1000     {
   1001       JNINativeMethod methods[] = { { "foo", "()V", native_function } };
   1002       EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_ERR);
   1003     }
   1004     ExpectException(jlnsme);
   1005 
   1006     // Check that registering non-native methods causes a NoSuchMethodError.
   1007     {
   1008       JNINativeMethod methods[] = { { "equals", "(Ljava/lang/Object;)Z", native_function } };
   1009       EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_ERR);
   1010     }
   1011     ExpectException(jlnsme);
   1012   }
   1013 
   1014   // Check that registering native methods is successful.
   1015   {
   1016     JNINativeMethod methods[] = { { "notify", "()V", native_function } };
   1017     EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_OK);
   1018   }
   1019   EXPECT_FALSE(env_->ExceptionCheck());
   1020   EXPECT_EQ(env_->UnregisterNatives(jlobject), JNI_OK);
   1021 
   1022   // Check that registering no methods isn't a failure.
   1023   {
   1024     JNINativeMethod methods[] = { };
   1025     EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 0), JNI_OK);
   1026   }
   1027   EXPECT_FALSE(env_->ExceptionCheck());
   1028   EXPECT_EQ(env_->UnregisterNatives(jlobject), JNI_OK);
   1029 
   1030   // Check that registering a -ve number of methods is a failure.
   1031   CheckJniAbortCatcher check_jni_abort_catcher;
   1032   for (int i = -10; i < 0; ++i) {
   1033     JNINativeMethod methods[] = { };
   1034     EXPECT_EQ(env_->RegisterNatives(jlobject, methods, i), JNI_ERR);
   1035     check_jni_abort_catcher.Check("negative method count: ");
   1036   }
   1037   EXPECT_FALSE(env_->ExceptionCheck());
   1038 
   1039   // Unregistering a class with no natives is a warning.
   1040   EXPECT_EQ(env_->UnregisterNatives(jlnsme), JNI_OK);
   1041 
   1042   RegisterAndUnregisterNativesBadArguments(false, &check_jni_abort_catcher);
   1043   RegisterAndUnregisterNativesBadArguments(true, &check_jni_abort_catcher);
   1044 }
   1045 
   1046 #define EXPECT_PRIMITIVE_ARRAY(new_fn, \
   1047                                get_region_fn, \
   1048                                set_region_fn, \
   1049                                get_elements_fn, \
   1050                                release_elements_fn, \
   1051                                scalar_type, \
   1052                                expected_class_descriptor) \
   1053   jsize size = 4; \
   1054   \
   1055   { \
   1056     CheckJniAbortCatcher jni_abort_catcher; \
   1057     down_cast<JNIEnvExt*>(env_)->SetCheckJniEnabled(false); \
   1058     /* Allocate an negative sized array and check it has the right failure type. */ \
   1059     EXPECT_EQ(env_->new_fn(-1), nullptr); \
   1060     jni_abort_catcher.Check("negative array length: -1"); \
   1061     EXPECT_EQ(env_->new_fn(std::numeric_limits<jint>::min()), nullptr); \
   1062     jni_abort_catcher.Check("negative array length: -2147483648"); \
   1063     /* Pass the array as null. */ \
   1064     EXPECT_EQ(0, env_->GetArrayLength(nullptr)); \
   1065     jni_abort_catcher.Check("java_array == null"); \
   1066     env_->get_region_fn(nullptr, 0, 0, nullptr); \
   1067     jni_abort_catcher.Check("java_array == null"); \
   1068     env_->set_region_fn(nullptr, 0, 0, nullptr); \
   1069     jni_abort_catcher.Check("java_array == null"); \
   1070     env_->get_elements_fn(nullptr, nullptr); \
   1071     jni_abort_catcher.Check("java_array == null"); \
   1072     env_->release_elements_fn(nullptr, nullptr, 0); \
   1073     jni_abort_catcher.Check("java_array == null"); \
   1074     /* Pass the elements for region as null. */ \
   1075     scalar_type ## Array a = env_->new_fn(size); \
   1076     env_->get_region_fn(a, 0, size, nullptr); \
   1077     jni_abort_catcher.Check("buf == null"); \
   1078     env_->set_region_fn(a, 0, size, nullptr); \
   1079     jni_abort_catcher.Check("buf == null"); \
   1080     down_cast<JNIEnvExt*>(env_)->SetCheckJniEnabled(true); \
   1081   } \
   1082   /* Allocate an array and check it has the right type and length. */ \
   1083   scalar_type ## Array a = env_->new_fn(size); \
   1084   EXPECT_NE(a, nullptr); \
   1085   EXPECT_TRUE(env_->IsInstanceOf(a, env_->FindClass(expected_class_descriptor))); \
   1086   EXPECT_EQ(size, env_->GetArrayLength(a)); \
   1087   \
   1088   /* GetPrimitiveArrayRegion/SetPrimitiveArrayRegion */ \
   1089   /* AIOOBE for negative start offset. */ \
   1090   env_->get_region_fn(a, -1, 1, nullptr); \
   1091   ExpectException(aioobe_); \
   1092   env_->set_region_fn(a, -1, 1, nullptr); \
   1093   ExpectException(aioobe_); \
   1094   \
   1095   /* AIOOBE for negative length. */ \
   1096   env_->get_region_fn(a, 0, -1, nullptr); \
   1097   ExpectException(aioobe_); \
   1098   env_->set_region_fn(a, 0, -1, nullptr); \
   1099   ExpectException(aioobe_); \
   1100   \
   1101   /* AIOOBE for buffer overrun. */ \
   1102   env_->get_region_fn(a, size - 1, size, nullptr); \
   1103   ExpectException(aioobe_); \
   1104   env_->set_region_fn(a, size - 1, size, nullptr); \
   1105   ExpectException(aioobe_); \
   1106   \
   1107   /* Regression test against integer overflow in range check. */ \
   1108   env_->get_region_fn(a, 0x7fffffff, 0x7fffffff, nullptr); \
   1109   ExpectException(aioobe_); \
   1110   env_->set_region_fn(a, 0x7fffffff, 0x7fffffff, nullptr); \
   1111   ExpectException(aioobe_); \
   1112   \
   1113   /* It's okay for the buffer to be null as long as the length is 0. */ \
   1114   env_->get_region_fn(a, 2, 0, nullptr); \
   1115   /* Even if the offset is invalid... */ \
   1116   env_->get_region_fn(a, 123, 0, nullptr); \
   1117   ExpectException(aioobe_); \
   1118   \
   1119   /* It's okay for the buffer to be null as long as the length is 0. */ \
   1120   env_->set_region_fn(a, 2, 0, nullptr); \
   1121   /* Even if the offset is invalid... */ \
   1122   env_->set_region_fn(a, 123, 0, nullptr); \
   1123   ExpectException(aioobe_); \
   1124   \
   1125   /* Prepare a couple of buffers. */ \
   1126   /* NOLINT, no parentheses around scalar_type. */ \
   1127   std::unique_ptr<scalar_type[]> src_buf(new scalar_type[size]); /* NOLINT */ \
   1128   std::unique_ptr<scalar_type[]> dst_buf(new scalar_type[size]); /* NOLINT */ \
   1129   for (jsize i = 0; i < size; ++i) { src_buf[i] = scalar_type(i); } \
   1130   for (jsize i = 0; i < size; ++i) { dst_buf[i] = scalar_type(-1); } \
   1131   \
   1132   /* Copy all of src_buf onto the heap. */ \
   1133   env_->set_region_fn(a, 0, size, &src_buf[0]); \
   1134   /* Copy back only part. */ \
   1135   env_->get_region_fn(a, 1, size - 2, &dst_buf[1]); \
   1136   EXPECT_NE(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) \
   1137     << "short copy equal"; \
   1138   /* Copy the missing pieces. */ \
   1139   env_->get_region_fn(a, 0, 1, &dst_buf[0]); \
   1140   env_->get_region_fn(a, size - 1, 1, &dst_buf[size - 1]); \
   1141   EXPECT_EQ(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) \
   1142     << "fixed copy not equal"; \
   1143   /* Copy back the whole array. */ \
   1144   env_->get_region_fn(a, 0, size, &dst_buf[0]); \
   1145   EXPECT_EQ(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) \
   1146     << "full copy not equal"; \
   1147   /* GetPrimitiveArrayCritical */ \
   1148   void* v = env_->GetPrimitiveArrayCritical(a, nullptr); \
   1149   EXPECT_EQ(memcmp(&src_buf[0], v, size * sizeof(scalar_type)), 0) \
   1150     << "GetPrimitiveArrayCritical not equal"; \
   1151   env_->ReleasePrimitiveArrayCritical(a, v, 0); \
   1152   /* GetXArrayElements */ \
   1153   scalar_type* xs = env_->get_elements_fn(a, nullptr); /* NOLINT, scalar_type */ \
   1154   EXPECT_EQ(memcmp(&src_buf[0], xs, size * sizeof(scalar_type)), 0) \
   1155     << # get_elements_fn " not equal"; \
   1156   env_->release_elements_fn(a, xs, 0); \
   1157 
   1158 TEST_F(JniInternalTest, BooleanArrays) {
   1159   EXPECT_PRIMITIVE_ARRAY(NewBooleanArray, GetBooleanArrayRegion, SetBooleanArrayRegion,
   1160                          GetBooleanArrayElements, ReleaseBooleanArrayElements, jboolean, "[Z");
   1161 }
   1162 TEST_F(JniInternalTest, ByteArrays) {
   1163   EXPECT_PRIMITIVE_ARRAY(NewByteArray, GetByteArrayRegion, SetByteArrayRegion,
   1164                          GetByteArrayElements, ReleaseByteArrayElements, jbyte, "[B");
   1165 }
   1166 TEST_F(JniInternalTest, CharArrays) {
   1167   EXPECT_PRIMITIVE_ARRAY(NewCharArray, GetCharArrayRegion, SetCharArrayRegion,
   1168                          GetCharArrayElements, ReleaseCharArrayElements, jchar, "[C");
   1169 }
   1170 TEST_F(JniInternalTest, DoubleArrays) {
   1171   EXPECT_PRIMITIVE_ARRAY(NewDoubleArray, GetDoubleArrayRegion, SetDoubleArrayRegion,
   1172                          GetDoubleArrayElements, ReleaseDoubleArrayElements, jdouble, "[D");
   1173 }
   1174 TEST_F(JniInternalTest, FloatArrays) {
   1175   EXPECT_PRIMITIVE_ARRAY(NewFloatArray, GetFloatArrayRegion, SetFloatArrayRegion,
   1176                          GetFloatArrayElements, ReleaseFloatArrayElements, jfloat, "[F");
   1177 }
   1178 TEST_F(JniInternalTest, IntArrays) {
   1179   EXPECT_PRIMITIVE_ARRAY(NewIntArray, GetIntArrayRegion, SetIntArrayRegion,
   1180                          GetIntArrayElements, ReleaseIntArrayElements, jint, "[I");
   1181 }
   1182 TEST_F(JniInternalTest, LongArrays) {
   1183   EXPECT_PRIMITIVE_ARRAY(NewLongArray, GetLongArrayRegion, SetLongArrayRegion,
   1184                          GetLongArrayElements, ReleaseLongArrayElements, jlong, "[J");
   1185 }
   1186 TEST_F(JniInternalTest, ShortArrays) {
   1187   EXPECT_PRIMITIVE_ARRAY(NewShortArray, GetShortArrayRegion, SetShortArrayRegion,
   1188                          GetShortArrayElements, ReleaseShortArrayElements, jshort, "[S");
   1189 }
   1190 
   1191 TEST_F(JniInternalTest, GetPrimitiveArrayElementsOfWrongType) {
   1192   GetPrimitiveArrayElementsOfWrongType(false);
   1193   GetPrimitiveArrayElementsOfWrongType(true);
   1194 }
   1195 
   1196 TEST_F(JniInternalTest, ReleasePrimitiveArrayElementsOfWrongType) {
   1197   ReleasePrimitiveArrayElementsOfWrongType(false);
   1198   ReleasePrimitiveArrayElementsOfWrongType(true);
   1199 }
   1200 
   1201 TEST_F(JniInternalTest, GetReleasePrimitiveArrayCriticalOfWrongType) {
   1202   GetReleasePrimitiveArrayCriticalOfWrongType(false);
   1203   GetReleasePrimitiveArrayCriticalOfWrongType(true);
   1204 }
   1205 
   1206 TEST_F(JniInternalTest, GetPrimitiveArrayRegionElementsOfWrongType) {
   1207   GetPrimitiveArrayRegionElementsOfWrongType(false);
   1208   GetPrimitiveArrayRegionElementsOfWrongType(true);
   1209 }
   1210 
   1211 TEST_F(JniInternalTest, SetPrimitiveArrayRegionElementsOfWrongType) {
   1212   SetPrimitiveArrayRegionElementsOfWrongType(false);
   1213   SetPrimitiveArrayRegionElementsOfWrongType(true);
   1214 }
   1215 
   1216 TEST_F(JniInternalTest, NewObjectArray) {
   1217   jclass element_class = env_->FindClass("java/lang/String");
   1218   ASSERT_NE(element_class, nullptr);
   1219   jclass array_class = env_->FindClass("[Ljava/lang/String;");
   1220   ASSERT_NE(array_class, nullptr);
   1221 
   1222   jobjectArray a = env_->NewObjectArray(0, element_class, nullptr);
   1223   EXPECT_NE(a, nullptr);
   1224   EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
   1225   EXPECT_EQ(0, env_->GetArrayLength(a));
   1226 
   1227   a = env_->NewObjectArray(1, element_class, nullptr);
   1228   EXPECT_NE(a, nullptr);
   1229   EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
   1230   EXPECT_EQ(1, env_->GetArrayLength(a));
   1231   EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 0), nullptr));
   1232 
   1233   // Negative array length checks.
   1234   NewObjectArrayBadArguments(false);
   1235   NewObjectArrayBadArguments(true);
   1236 }
   1237 
   1238 TEST_F(JniInternalTest, NewObjectArrayWithPrimitiveClasses) {
   1239   const char* primitive_descriptors = "VZBSCIJFD";
   1240   const char* primitive_names[] = {
   1241       "void", "boolean", "byte", "short", "char", "int", "long", "float", "double"
   1242   };
   1243   ASSERT_EQ(strlen(primitive_descriptors), arraysize(primitive_names));
   1244 
   1245   bool old_check_jni = vm_->SetCheckJniEnabled(false);
   1246   CheckJniAbortCatcher jni_abort_catcher;
   1247   for (size_t i = 0; i < strlen(primitive_descriptors); ++i) {
   1248     env_->NewObjectArray(0, nullptr, nullptr);
   1249     jni_abort_catcher.Check("element_jclass == null");
   1250     jclass primitive_class = GetPrimitiveClass(primitive_descriptors[i]);
   1251     env_->NewObjectArray(1, primitive_class, nullptr);
   1252     std::string error_msg(StringPrintf("not an object type: %s", primitive_names[i]));
   1253     jni_abort_catcher.Check(error_msg.c_str());
   1254   }
   1255   EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
   1256   for (size_t i = 0; i < strlen(primitive_descriptors); ++i) {
   1257     env_->NewObjectArray(0, nullptr, nullptr);
   1258     jni_abort_catcher.Check("NewObjectArray received NULL jclass");
   1259     jclass primitive_class = GetPrimitiveClass(primitive_descriptors[i]);
   1260     env_->NewObjectArray(1, primitive_class, nullptr);
   1261     std::string error_msg(StringPrintf("not an object type: %s", primitive_names[i]));
   1262     jni_abort_catcher.Check(error_msg.c_str());
   1263   }
   1264   EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
   1265 }
   1266 
   1267 TEST_F(JniInternalTest, NewObjectArrayWithInitialValue) {
   1268   jclass element_class = env_->FindClass("java/lang/String");
   1269   ASSERT_NE(element_class, nullptr);
   1270   jclass array_class = env_->FindClass("[Ljava/lang/String;");
   1271   ASSERT_NE(array_class, nullptr);
   1272 
   1273   jstring s = env_->NewStringUTF("poop");
   1274   jobjectArray a = env_->NewObjectArray(2, element_class, s);
   1275   EXPECT_NE(a, nullptr);
   1276   EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
   1277   EXPECT_EQ(2, env_->GetArrayLength(a));
   1278   EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 0), s));
   1279   EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 1), s));
   1280 
   1281   // Attempt to incorrect create an array of strings with initial value of string arrays.
   1282   CheckJniAbortCatcher jni_abort_catcher;
   1283   env_->NewObjectArray(2, element_class, a);
   1284   jni_abort_catcher.Check("cannot assign object of type 'java.lang.String[]' to array with element "
   1285                           "type of 'java.lang.String'");
   1286 }
   1287 
   1288 TEST_F(JniInternalTest, GetArrayLength) {
   1289   // Already tested in NewObjectArray/NewPrimitiveArray except for null.
   1290   CheckJniAbortCatcher jni_abort_catcher;
   1291   bool old_check_jni = vm_->SetCheckJniEnabled(false);
   1292   EXPECT_EQ(0, env_->GetArrayLength(nullptr));
   1293   jni_abort_catcher.Check("java_array == null");
   1294   EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
   1295   EXPECT_EQ(JNI_ERR, env_->GetArrayLength(nullptr));
   1296   jni_abort_catcher.Check("jarray was NULL");
   1297   EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
   1298 }
   1299 
   1300 TEST_F(JniInternalTest, GetObjectClass) {
   1301   jclass string_class = env_->FindClass("java/lang/String");
   1302   ASSERT_NE(string_class, nullptr);
   1303   jclass class_class = env_->FindClass("java/lang/Class");
   1304   ASSERT_NE(class_class, nullptr);
   1305 
   1306   jstring s = env_->NewStringUTF("poop");
   1307   jclass c = env_->GetObjectClass(s);
   1308   ASSERT_TRUE(env_->IsSameObject(string_class, c));
   1309 
   1310   jclass c2 = env_->GetObjectClass(c);
   1311   ASSERT_TRUE(env_->IsSameObject(class_class, env_->GetObjectClass(c2)));
   1312 
   1313   // Null as object should fail.
   1314   CheckJniAbortCatcher jni_abort_catcher;
   1315   EXPECT_EQ(env_->GetObjectClass(nullptr), nullptr);
   1316   jni_abort_catcher.Check("java_object == null");
   1317 }
   1318 
   1319 TEST_F(JniInternalTest, GetSuperclass) {
   1320   jclass object_class = env_->FindClass("java/lang/Object");
   1321   ASSERT_NE(object_class, nullptr);
   1322   jclass string_class = env_->FindClass("java/lang/String");
   1323   ASSERT_NE(string_class, nullptr);
   1324   jclass runnable_interface = env_->FindClass("java/lang/Runnable");
   1325   ASSERT_NE(runnable_interface, nullptr);
   1326   ASSERT_TRUE(env_->IsSameObject(object_class, env_->GetSuperclass(string_class)));
   1327   ASSERT_EQ(env_->GetSuperclass(object_class), nullptr);
   1328   ASSERT_EQ(env_->GetSuperclass(runnable_interface), nullptr);
   1329 
   1330   // Null as class should fail.
   1331   CheckJniAbortCatcher jni_abort_catcher;
   1332   bool old_check_jni = vm_->SetCheckJniEnabled(false);
   1333   EXPECT_EQ(env_->GetSuperclass(nullptr), nullptr);
   1334   jni_abort_catcher.Check("java_class == null");
   1335   EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
   1336   EXPECT_EQ(env_->GetSuperclass(nullptr), nullptr);
   1337   jni_abort_catcher.Check("GetSuperclass received NULL jclass");
   1338   EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
   1339 }
   1340 
   1341 TEST_F(JniInternalTest, IsAssignableFrom) {
   1342   jclass object_class = env_->FindClass("java/lang/Object");
   1343   ASSERT_NE(object_class, nullptr);
   1344   jclass string_class = env_->FindClass("java/lang/String");
   1345   ASSERT_NE(string_class, nullptr);
   1346 
   1347   // A superclass is assignable from an instance of its
   1348   // subclass but not vice versa.
   1349   ASSERT_TRUE(env_->IsAssignableFrom(string_class, object_class));
   1350   ASSERT_FALSE(env_->IsAssignableFrom(object_class, string_class));
   1351 
   1352   jclass charsequence_interface = env_->FindClass("java/lang/CharSequence");
   1353   ASSERT_NE(charsequence_interface, nullptr);
   1354 
   1355   // An interface is assignable from an instance of an implementing
   1356   // class but not vice versa.
   1357   ASSERT_TRUE(env_->IsAssignableFrom(string_class, charsequence_interface));
   1358   ASSERT_FALSE(env_->IsAssignableFrom(charsequence_interface, string_class));
   1359 
   1360   // Check that arrays are covariant.
   1361   jclass string_array_class = env_->FindClass("[Ljava/lang/String;");
   1362   ASSERT_NE(string_array_class, nullptr);
   1363   jclass object_array_class = env_->FindClass("[Ljava/lang/Object;");
   1364   ASSERT_NE(object_array_class, nullptr);
   1365   ASSERT_TRUE(env_->IsAssignableFrom(string_array_class, object_array_class));
   1366   ASSERT_FALSE(env_->IsAssignableFrom(object_array_class, string_array_class));
   1367 
   1368   // Primitive types are tested in 004-JniTest.
   1369 
   1370   // Null as either class should fail.
   1371   CheckJniAbortCatcher jni_abort_catcher;
   1372   bool old_check_jni = vm_->SetCheckJniEnabled(false);
   1373   EXPECT_EQ(env_->IsAssignableFrom(nullptr, string_class), JNI_FALSE);
   1374   jni_abort_catcher.Check("java_class1 == null");
   1375   EXPECT_EQ(env_->IsAssignableFrom(object_class, nullptr), JNI_FALSE);
   1376   jni_abort_catcher.Check("java_class2 == null");
   1377   EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
   1378   EXPECT_EQ(env_->IsAssignableFrom(nullptr, string_class), JNI_FALSE);
   1379   jni_abort_catcher.Check("IsAssignableFrom received NULL jclass");
   1380   EXPECT_EQ(env_->IsAssignableFrom(object_class, nullptr), JNI_FALSE);
   1381   jni_abort_catcher.Check("IsAssignableFrom received NULL jclass");
   1382   EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
   1383 }
   1384 
   1385 TEST_F(JniInternalTest, GetObjectRefType) {
   1386   jclass local = env_->FindClass("java/lang/Object");
   1387   ASSERT_TRUE(local != nullptr);
   1388   EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(local));
   1389 
   1390   jobject global = env_->NewGlobalRef(local);
   1391   EXPECT_EQ(JNIGlobalRefType, env_->GetObjectRefType(global));
   1392 
   1393   jweak weak_global = env_->NewWeakGlobalRef(local);
   1394   EXPECT_EQ(JNIWeakGlobalRefType, env_->GetObjectRefType(weak_global));
   1395 
   1396   {
   1397     CheckJniAbortCatcher jni_abort_catcher;
   1398     jobject invalid = reinterpret_cast<jobject>(this);
   1399     EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(invalid));
   1400     jni_abort_catcher.Check("use of invalid jobject");
   1401   }
   1402 
   1403   // TODO: invoke a native method and test that its arguments are considered local references.
   1404 
   1405   // Null as pointer should not fail and return invalid-ref. b/18820997
   1406   EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(nullptr));
   1407 
   1408   // TODO: Null as reference should return the original type.
   1409   // This requires running a GC so a non-null object gets freed.
   1410 }
   1411 
   1412 TEST_F(JniInternalTest, StaleWeakGlobal) {
   1413   jclass java_lang_Class = env_->FindClass("java/lang/Class");
   1414   ASSERT_NE(java_lang_Class, nullptr);
   1415   jobjectArray local_ref = env_->NewObjectArray(1, java_lang_Class, nullptr);
   1416   ASSERT_NE(local_ref, nullptr);
   1417   jweak weak_global = env_->NewWeakGlobalRef(local_ref);
   1418   ASSERT_NE(weak_global, nullptr);
   1419   env_->DeleteLocalRef(local_ref);
   1420   Runtime::Current()->GetHeap()->CollectGarbage(false);  // GC should clear the weak global.
   1421   jobject new_global_ref = env_->NewGlobalRef(weak_global);
   1422   EXPECT_EQ(new_global_ref, nullptr);
   1423   jobject new_local_ref = env_->NewLocalRef(weak_global);
   1424   EXPECT_EQ(new_local_ref, nullptr);
   1425 }
   1426 
   1427 TEST_F(JniInternalTest, NewStringUTF) {
   1428   EXPECT_EQ(env_->NewStringUTF(nullptr), nullptr);
   1429   jstring s;
   1430 
   1431   s = env_->NewStringUTF("");
   1432   EXPECT_NE(s, nullptr);
   1433   EXPECT_EQ(0, env_->GetStringLength(s));
   1434   EXPECT_EQ(0, env_->GetStringUTFLength(s));
   1435   s = env_->NewStringUTF("hello");
   1436   EXPECT_NE(s, nullptr);
   1437   EXPECT_EQ(5, env_->GetStringLength(s));
   1438   EXPECT_EQ(5, env_->GetStringUTFLength(s));
   1439 
   1440   // Encoded surrogate pair.
   1441   s = env_->NewStringUTF("\xed\xa0\x81\xed\xb0\x80");
   1442   EXPECT_NE(s, nullptr);
   1443   EXPECT_EQ(2, env_->GetStringLength(s));
   1444 
   1445   // The surrogate pair gets encoded into a 4 byte UTF sequence..
   1446   EXPECT_EQ(4, env_->GetStringUTFLength(s));
   1447   const char* chars = env_->GetStringUTFChars(s, nullptr);
   1448   EXPECT_STREQ("\xf0\x90\x90\x80", chars);
   1449   env_->ReleaseStringUTFChars(s, chars);
   1450 
   1451   // .. but is stored as is in the utf-16 representation.
   1452   const jchar* jchars = env_->GetStringChars(s, nullptr);
   1453   EXPECT_EQ(0xd801, jchars[0]);
   1454   EXPECT_EQ(0xdc00, jchars[1]);
   1455   env_->ReleaseStringChars(s, jchars);
   1456 
   1457   // 4 byte UTF sequence appended to an encoded surrogate pair.
   1458   s = env_->NewStringUTF("\xed\xa0\x81\xed\xb0\x80 \xf0\x9f\x8f\xa0");
   1459   EXPECT_NE(s, nullptr);
   1460 
   1461   // The 4 byte sequence {0xf0, 0x9f, 0x8f, 0xa0} is converted into a surrogate
   1462   // pair {0xd83c, 0xdfe0}.
   1463   EXPECT_EQ(5, env_->GetStringLength(s));
   1464   jchars = env_->GetStringChars(s, nullptr);
   1465   // The first surrogate pair, encoded as such in the input.
   1466   EXPECT_EQ(0xd801, jchars[0]);
   1467   EXPECT_EQ(0xdc00, jchars[1]);
   1468   // The second surrogate pair, from the 4 byte UTF sequence in the input.
   1469   EXPECT_EQ(0xd83c, jchars[3]);
   1470   EXPECT_EQ(0xdfe0, jchars[4]);
   1471   env_->ReleaseStringChars(s, jchars);
   1472 
   1473   EXPECT_EQ(9, env_->GetStringUTFLength(s));
   1474   chars = env_->GetStringUTFChars(s, nullptr);
   1475   EXPECT_STREQ("\xf0\x90\x90\x80 \xf0\x9f\x8f\xa0", chars);
   1476   env_->ReleaseStringUTFChars(s, chars);
   1477 
   1478   // A string with 1, 2, 3 and 4 byte UTF sequences with spaces
   1479   // between them
   1480   s = env_->NewStringUTF("\x24 \xc2\xa2 \xe2\x82\xac \xf0\x9f\x8f\xa0");
   1481   EXPECT_NE(s, nullptr);
   1482   EXPECT_EQ(8, env_->GetStringLength(s));
   1483   EXPECT_EQ(13, env_->GetStringUTFLength(s));
   1484 }
   1485 
   1486 TEST_F(JniInternalTest, NewString) {
   1487   jchar chars[] = { 'h', 'i' };
   1488   jstring s;
   1489   s = env_->NewString(chars, 0);
   1490   EXPECT_NE(s, nullptr);
   1491   EXPECT_EQ(0, env_->GetStringLength(s));
   1492   EXPECT_EQ(0, env_->GetStringUTFLength(s));
   1493   s = env_->NewString(chars, 2);
   1494   EXPECT_NE(s, nullptr);
   1495   EXPECT_EQ(2, env_->GetStringLength(s));
   1496   EXPECT_EQ(2, env_->GetStringUTFLength(s));
   1497 
   1498   // TODO: check some non-ASCII strings.
   1499 }
   1500 
   1501 TEST_F(JniInternalTest, NewStringNullCharsZeroLength) {
   1502   jstring s = env_->NewString(nullptr, 0);
   1503   EXPECT_NE(s, nullptr);
   1504   EXPECT_EQ(0, env_->GetStringLength(s));
   1505 }
   1506 
   1507 TEST_F(JniInternalTest, NewStringNullCharsNonzeroLength) {
   1508   CheckJniAbortCatcher jni_abort_catcher;
   1509   env_->NewString(nullptr, 1);
   1510   jni_abort_catcher.Check("chars == null && char_count > 0");
   1511 }
   1512 
   1513 TEST_F(JniInternalTest, NewStringNegativeLength) {
   1514   CheckJniAbortCatcher jni_abort_catcher;
   1515   bool old_check_jni = vm_->SetCheckJniEnabled(false);
   1516   env_->NewString(nullptr, -1);
   1517   jni_abort_catcher.Check("char_count < 0: -1");
   1518   env_->NewString(nullptr, std::numeric_limits<jint>::min());
   1519   jni_abort_catcher.Check("char_count < 0: -2147483648");
   1520   EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
   1521   env_->NewString(nullptr, -1);
   1522   jni_abort_catcher.Check("negative jsize: -1");
   1523   env_->NewString(nullptr, std::numeric_limits<jint>::min());
   1524   jni_abort_catcher.Check("negative jsize: -2147483648");
   1525   EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
   1526 }
   1527 
   1528 TEST_F(JniInternalTest, GetStringLength_GetStringUTFLength) {
   1529   // Already tested in the NewString/NewStringUTF tests.
   1530 }
   1531 
   1532 TEST_F(JniInternalTest, GetStringRegion_GetStringUTFRegion) {
   1533   jstring s = env_->NewStringUTF("hello");
   1534   ASSERT_TRUE(s != nullptr);
   1535 
   1536   env_->GetStringRegion(s, -1, 0, nullptr);
   1537   ExpectException(sioobe_);
   1538   env_->GetStringRegion(s, 0, -1, nullptr);
   1539   ExpectException(sioobe_);
   1540   env_->GetStringRegion(s, 0, 10, nullptr);
   1541   ExpectException(sioobe_);
   1542   env_->GetStringRegion(s, 10, 1, nullptr);
   1543   ExpectException(sioobe_);
   1544   // Regression test against integer overflow in range check.
   1545   env_->GetStringRegion(s, 0x7fffffff, 0x7fffffff, nullptr);
   1546   ExpectException(sioobe_);
   1547 
   1548   jchar chars[4] = { 'x', 'x', 'x', 'x' };
   1549   env_->GetStringRegion(s, 1, 2, &chars[1]);
   1550   EXPECT_EQ('x', chars[0]);
   1551   EXPECT_EQ('e', chars[1]);
   1552   EXPECT_EQ('l', chars[2]);
   1553   EXPECT_EQ('x', chars[3]);
   1554 
   1555   // It's okay for the buffer to be null as long as the length is 0.
   1556   env_->GetStringRegion(s, 2, 0, nullptr);
   1557   // Even if the offset is invalid...
   1558   env_->GetStringRegion(s, 123, 0, nullptr);
   1559   ExpectException(sioobe_);
   1560 
   1561   env_->GetStringUTFRegion(s, -1, 0, nullptr);
   1562   ExpectException(sioobe_);
   1563   env_->GetStringUTFRegion(s, 0, -1, nullptr);
   1564   ExpectException(sioobe_);
   1565   env_->GetStringUTFRegion(s, 0, 10, nullptr);
   1566   ExpectException(sioobe_);
   1567   env_->GetStringUTFRegion(s, 10, 1, nullptr);
   1568   ExpectException(sioobe_);
   1569   // Regression test against integer overflow in range check.
   1570   env_->GetStringUTFRegion(s, 0x7fffffff, 0x7fffffff, nullptr);
   1571   ExpectException(sioobe_);
   1572 
   1573   char bytes[4] = { 'x', 'x', 'x', 'x' };
   1574   env_->GetStringUTFRegion(s, 1, 2, &bytes[1]);
   1575   EXPECT_EQ('x', bytes[0]);
   1576   EXPECT_EQ('e', bytes[1]);
   1577   EXPECT_EQ('l', bytes[2]);
   1578   EXPECT_EQ('x', bytes[3]);
   1579 
   1580   // It's okay for the buffer to be null as long as the length is 0.
   1581   env_->GetStringUTFRegion(s, 2, 0, nullptr);
   1582   // Even if the offset is invalid...
   1583   env_->GetStringUTFRegion(s, 123, 0, nullptr);
   1584   ExpectException(sioobe_);
   1585 }
   1586 
   1587 TEST_F(JniInternalTest, GetStringUTFChars_ReleaseStringUTFChars) {
   1588   // Passing in a null jstring is ignored normally, but caught by -Xcheck:jni.
   1589   bool old_check_jni = vm_->SetCheckJniEnabled(false);
   1590   {
   1591     CheckJniAbortCatcher check_jni_abort_catcher;
   1592     EXPECT_EQ(env_->GetStringUTFChars(nullptr, nullptr), nullptr);
   1593   }
   1594   {
   1595     CheckJniAbortCatcher check_jni_abort_catcher;
   1596     EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
   1597     EXPECT_EQ(env_->GetStringUTFChars(nullptr, nullptr), nullptr);
   1598     check_jni_abort_catcher.Check("GetStringUTFChars received NULL jstring");
   1599     EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
   1600   }
   1601 
   1602   jstring s = env_->NewStringUTF("hello");
   1603   ASSERT_TRUE(s != nullptr);
   1604 
   1605   const char* utf = env_->GetStringUTFChars(s, nullptr);
   1606   EXPECT_STREQ("hello", utf);
   1607   env_->ReleaseStringUTFChars(s, utf);
   1608 
   1609   jboolean is_copy = JNI_FALSE;
   1610   utf = env_->GetStringUTFChars(s, &is_copy);
   1611   EXPECT_EQ(JNI_TRUE, is_copy);
   1612   EXPECT_STREQ("hello", utf);
   1613   env_->ReleaseStringUTFChars(s, utf);
   1614 }
   1615 
   1616 TEST_F(JniInternalTest, GetStringChars_ReleaseStringChars) {
   1617   jstring s = env_->NewStringUTF("hello");
   1618   ScopedObjectAccess soa(env_);
   1619   ObjPtr<mirror::String> s_m = soa.Decode<mirror::String>(s);
   1620   ASSERT_TRUE(s != nullptr);
   1621 
   1622   jchar expected[] = { 'h', 'e', 'l', 'l', 'o' };
   1623   const jchar* chars = env_->GetStringChars(s, nullptr);
   1624   EXPECT_EQ(expected[0], chars[0]);
   1625   EXPECT_EQ(expected[1], chars[1]);
   1626   EXPECT_EQ(expected[2], chars[2]);
   1627   EXPECT_EQ(expected[3], chars[3]);
   1628   EXPECT_EQ(expected[4], chars[4]);
   1629   env_->ReleaseStringChars(s, chars);
   1630 
   1631   jboolean is_copy = JNI_FALSE;
   1632   chars = env_->GetStringChars(s, &is_copy);
   1633   if (Runtime::Current()->GetHeap()->IsMovableObject(s_m)) {
   1634     EXPECT_EQ(JNI_TRUE, is_copy);
   1635   } else {
   1636     EXPECT_EQ(JNI_FALSE, is_copy);
   1637   }
   1638   EXPECT_EQ(expected[0], chars[0]);
   1639   EXPECT_EQ(expected[1], chars[1]);
   1640   EXPECT_EQ(expected[2], chars[2]);
   1641   EXPECT_EQ(expected[3], chars[3]);
   1642   EXPECT_EQ(expected[4], chars[4]);
   1643   env_->ReleaseStringChars(s, chars);
   1644 }
   1645 
   1646 TEST_F(JniInternalTest, GetStringCritical_ReleaseStringCritical) {
   1647   jstring s = env_->NewStringUTF("hello");
   1648   ASSERT_TRUE(s != nullptr);
   1649 
   1650   jchar expected[] = { 'h', 'e', 'l', 'l', 'o' };
   1651   const jchar* chars = env_->GetStringCritical(s, nullptr);
   1652   EXPECT_EQ(expected[0], chars[0]);
   1653   EXPECT_EQ(expected[1], chars[1]);
   1654   EXPECT_EQ(expected[2], chars[2]);
   1655   EXPECT_EQ(expected[3], chars[3]);
   1656   EXPECT_EQ(expected[4], chars[4]);
   1657   env_->ReleaseStringCritical(s, chars);
   1658 
   1659   jboolean is_copy = JNI_TRUE;
   1660   chars = env_->GetStringCritical(s, &is_copy);
   1661   if (mirror::kUseStringCompression) {
   1662     // is_copy has to be JNI_TRUE because "hello" is all-ASCII
   1663     EXPECT_EQ(JNI_TRUE, is_copy);
   1664   } else {
   1665     EXPECT_EQ(JNI_FALSE, is_copy);
   1666   }
   1667   EXPECT_EQ(expected[0], chars[0]);
   1668   EXPECT_EQ(expected[1], chars[1]);
   1669   EXPECT_EQ(expected[2], chars[2]);
   1670   EXPECT_EQ(expected[3], chars[3]);
   1671   EXPECT_EQ(expected[4], chars[4]);
   1672   env_->ReleaseStringCritical(s, chars);
   1673 
   1674   if (mirror::kUseStringCompression) {
   1675     // is_copy has to be JNI_FALSE because "\xed\xa0\x81\xed\xb0\x80" is incompressible
   1676     jboolean is_copy_16 = JNI_TRUE;
   1677     jstring s_16 = env_->NewStringUTF("\xed\xa0\x81\xed\xb0\x80");
   1678     chars = env_->GetStringCritical(s_16, &is_copy_16);
   1679     EXPECT_EQ(2, env_->GetStringLength(s_16));
   1680     EXPECT_EQ(4, env_->GetStringUTFLength(s_16));
   1681     env_->ReleaseStringCritical(s_16, chars);
   1682   }
   1683 }
   1684 
   1685 TEST_F(JniInternalTest, GetObjectArrayElement_SetObjectArrayElement) {
   1686   jclass java_lang_Class = env_->FindClass("java/lang/Class");
   1687   ASSERT_TRUE(java_lang_Class != nullptr);
   1688 
   1689   jobjectArray array = env_->NewObjectArray(1, java_lang_Class, nullptr);
   1690   EXPECT_NE(array, nullptr);
   1691   EXPECT_EQ(env_->GetObjectArrayElement(array, 0), nullptr);
   1692   env_->SetObjectArrayElement(array, 0, java_lang_Class);
   1693   EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(array, 0), java_lang_Class));
   1694 
   1695   // ArrayIndexOutOfBounds for negative index.
   1696   env_->SetObjectArrayElement(array, -1, java_lang_Class);
   1697   ExpectException(aioobe_);
   1698 
   1699   // ArrayIndexOutOfBounds for too-large index.
   1700   env_->SetObjectArrayElement(array, 1, java_lang_Class);
   1701   ExpectException(aioobe_);
   1702 
   1703   // ArrayStoreException thrown for bad types.
   1704   env_->SetObjectArrayElement(array, 0, env_->NewStringUTF("not a jclass!"));
   1705   ExpectException(ase_);
   1706 
   1707   // Null as array should fail.
   1708   CheckJniAbortCatcher jni_abort_catcher;
   1709   bool old_check_jni = vm_->SetCheckJniEnabled(false);
   1710   EXPECT_EQ(nullptr, env_->GetObjectArrayElement(nullptr, 0));
   1711   jni_abort_catcher.Check("java_array == null");
   1712   env_->SetObjectArrayElement(nullptr, 0, nullptr);
   1713   jni_abort_catcher.Check("java_array == null");
   1714   EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
   1715   EXPECT_EQ(nullptr, env_->GetObjectArrayElement(nullptr, 0));
   1716   jni_abort_catcher.Check("jarray was NULL");
   1717   env_->SetObjectArrayElement(nullptr, 0, nullptr);
   1718   jni_abort_catcher.Check("jarray was NULL");
   1719   EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
   1720 }
   1721 
   1722 #define EXPECT_STATIC_PRIMITIVE_FIELD(expect_eq, type, field_name, sig, value1, value2) \
   1723   do { \
   1724     jfieldID fid = env_->GetStaticFieldID(c, field_name, sig); \
   1725     EXPECT_NE(fid, nullptr); \
   1726     env_->SetStatic ## type ## Field(c, fid, value1); \
   1727     expect_eq(value1, env_->GetStatic ## type ## Field(c, fid)); \
   1728     env_->SetStatic ## type ## Field(c, fid, value2); \
   1729     expect_eq(value2, env_->GetStatic ## type ## Field(c, fid)); \
   1730     \
   1731     bool old_check_jni = vm_->SetCheckJniEnabled(false); \
   1732     { \
   1733       CheckJniAbortCatcher jni_abort_catcher; \
   1734       env_->GetStatic ## type ## Field(nullptr, fid); \
   1735       env_->SetStatic ## type ## Field(nullptr, fid, value1); \
   1736     } \
   1737     CheckJniAbortCatcher jni_abort_catcher; \
   1738     env_->GetStatic ## type ## Field(c, nullptr); \
   1739     jni_abort_catcher.Check("fid == null"); \
   1740     env_->SetStatic ## type ## Field(c, nullptr, value1); \
   1741     jni_abort_catcher.Check("fid == null"); \
   1742     \
   1743     EXPECT_FALSE(vm_->SetCheckJniEnabled(true)); \
   1744     env_->GetStatic ## type ## Field(nullptr, fid); \
   1745     jni_abort_catcher.Check("received NULL jclass"); \
   1746     env_->SetStatic ## type ## Field(nullptr, fid, value1); \
   1747     jni_abort_catcher.Check("received NULL jclass"); \
   1748     env_->GetStatic ## type ## Field(c, nullptr); \
   1749     jni_abort_catcher.Check("jfieldID was NULL"); \
   1750     env_->SetStatic ## type ## Field(c, nullptr, value1); \
   1751     jni_abort_catcher.Check("jfieldID was NULL"); \
   1752     EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni)); \
   1753   } while (false)
   1754 
   1755 #define EXPECT_PRIMITIVE_FIELD(expect_eq, instance, type, field_name, sig, value1, value2) \
   1756   do { \
   1757     jfieldID fid = env_->GetFieldID(c, field_name, sig); \
   1758     EXPECT_NE(fid, nullptr); \
   1759     env_->Set ## type ## Field(instance, fid, value1); \
   1760     expect_eq(value1, env_->Get ## type ## Field(instance, fid)); \
   1761     env_->Set ## type ## Field(instance, fid, value2); \
   1762     expect_eq(value2, env_->Get ## type ## Field(instance, fid)); \
   1763     \
   1764     bool old_check_jni = vm_->SetCheckJniEnabled(false); \
   1765     CheckJniAbortCatcher jni_abort_catcher; \
   1766     env_->Get ## type ## Field(nullptr, fid); \
   1767     jni_abort_catcher.Check("obj == null"); \
   1768     env_->Set ## type ## Field(nullptr, fid, value1); \
   1769     jni_abort_catcher.Check("obj == null"); \
   1770     env_->Get ## type ## Field(instance, nullptr); \
   1771     jni_abort_catcher.Check("fid == null"); \
   1772     env_->Set ## type ## Field(instance, nullptr, value1); \
   1773     jni_abort_catcher.Check("fid == null"); \
   1774     EXPECT_FALSE(vm_->SetCheckJniEnabled(true)); \
   1775     env_->Get ## type ## Field(nullptr, fid); \
   1776     jni_abort_catcher.Check("field operation on NULL object:"); \
   1777     env_->Set ## type ## Field(nullptr, fid, value1); \
   1778     jni_abort_catcher.Check("field operation on NULL object:"); \
   1779     env_->Get ## type ## Field(instance, nullptr); \
   1780     jni_abort_catcher.Check("jfieldID was NULL"); \
   1781     env_->Set ## type ## Field(instance, nullptr, value1); \
   1782     jni_abort_catcher.Check("jfieldID was NULL"); \
   1783     EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni)); \
   1784   } while (false)
   1785 
   1786 
   1787 TEST_F(JniInternalTest, GetPrimitiveField_SetPrimitiveField) {
   1788   Thread::Current()->TransitionFromSuspendedToRunnable();
   1789   LoadDex("AllFields");
   1790   bool started = runtime_->Start();
   1791   ASSERT_TRUE(started);
   1792 
   1793   jclass c = env_->FindClass("AllFields");
   1794   ASSERT_NE(c, nullptr);
   1795   jobject o = env_->AllocObject(c);
   1796   ASSERT_NE(o, nullptr);
   1797 
   1798   EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_EQ, Boolean, "sZ", "Z", JNI_TRUE, JNI_FALSE);
   1799   EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_EQ, Byte, "sB", "B", 1, 2);
   1800   EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_EQ, Char, "sC", "C", 'a', 'b');
   1801   EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_DOUBLE_EQ, Double, "sD", "D", 1.0, 2.0);
   1802   EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_FLOAT_EQ, Float, "sF", "F", 1.0, 2.0);
   1803   EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_EQ, Int, "sI", "I", 1, 2);
   1804   EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_EQ, Long, "sJ", "J", 1, 2);
   1805   EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_EQ, Short, "sS", "S", 1, 2);
   1806 
   1807   EXPECT_PRIMITIVE_FIELD(EXPECT_EQ, o, Boolean, "iZ", "Z", JNI_TRUE, JNI_FALSE);
   1808   EXPECT_PRIMITIVE_FIELD(EXPECT_EQ, o, Byte, "iB", "B", 1, 2);
   1809   EXPECT_PRIMITIVE_FIELD(EXPECT_EQ, o, Char, "iC", "C", 'a', 'b');
   1810   EXPECT_PRIMITIVE_FIELD(EXPECT_DOUBLE_EQ, o, Double, "iD", "D", 1.0, 2.0);
   1811   EXPECT_PRIMITIVE_FIELD(EXPECT_FLOAT_EQ, o, Float, "iF", "F", 1.0, 2.0);
   1812   EXPECT_PRIMITIVE_FIELD(EXPECT_EQ, o, Int, "iI", "I", 1, 2);
   1813   EXPECT_PRIMITIVE_FIELD(EXPECT_EQ, o, Long, "iJ", "J", 1, 2);
   1814   EXPECT_PRIMITIVE_FIELD(EXPECT_EQ, o, Short, "iS", "S", 1, 2);
   1815 }
   1816 
   1817 TEST_F(JniInternalTest, GetObjectField_SetObjectField) {
   1818   Thread::Current()->TransitionFromSuspendedToRunnable();
   1819   LoadDex("AllFields");
   1820   runtime_->Start();
   1821 
   1822   jclass c = env_->FindClass("AllFields");
   1823   ASSERT_NE(c, nullptr);
   1824   jobject o = env_->AllocObject(c);
   1825   ASSERT_NE(o, nullptr);
   1826 
   1827   jstring s1 = env_->NewStringUTF("hello");
   1828   ASSERT_NE(s1, nullptr);
   1829   jstring s2 = env_->NewStringUTF("world");
   1830   ASSERT_NE(s2, nullptr);
   1831 
   1832   jfieldID s_fid = env_->GetStaticFieldID(c, "sObject", "Ljava/lang/Object;");
   1833   ASSERT_NE(s_fid, nullptr);
   1834   jfieldID i_fid = env_->GetFieldID(c, "iObject", "Ljava/lang/Object;");
   1835   ASSERT_NE(i_fid, nullptr);
   1836 
   1837   env_->SetStaticObjectField(c, s_fid, s1);
   1838   ASSERT_TRUE(env_->IsSameObject(s1, env_->GetStaticObjectField(c, s_fid)));
   1839   env_->SetStaticObjectField(c, s_fid, s2);
   1840   ASSERT_TRUE(env_->IsSameObject(s2, env_->GetStaticObjectField(c, s_fid)));
   1841 
   1842   env_->SetObjectField(o, i_fid, s1);
   1843   ASSERT_TRUE(env_->IsSameObject(s1, env_->GetObjectField(o, i_fid)));
   1844   env_->SetObjectField(o, i_fid, s2);
   1845   ASSERT_TRUE(env_->IsSameObject(s2, env_->GetObjectField(o, i_fid)));
   1846 }
   1847 
   1848 TEST_F(JniInternalTest, NewLocalRef_nullptr) {
   1849   EXPECT_EQ(env_->NewLocalRef(nullptr), nullptr);
   1850 }
   1851 
   1852 TEST_F(JniInternalTest, NewLocalRef) {
   1853   jstring s = env_->NewStringUTF("");
   1854   ASSERT_NE(s, nullptr);
   1855   jobject o = env_->NewLocalRef(s);
   1856   EXPECT_NE(o, nullptr);
   1857   EXPECT_NE(o, s);
   1858 
   1859   EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(o));
   1860 }
   1861 
   1862 TEST_F(JniInternalTest, DeleteLocalRef_nullptr) {
   1863   env_->DeleteLocalRef(nullptr);
   1864 }
   1865 
   1866 TEST_F(JniInternalTest, DeleteLocalRef) {
   1867   // This tests leads to warnings and errors in the log.
   1868   ScopedLogSeverity sls(LogSeverity::FATAL);
   1869 
   1870   jstring s = env_->NewStringUTF("");
   1871   ASSERT_NE(s, nullptr);
   1872   env_->DeleteLocalRef(s);
   1873 
   1874   // Currently, deleting an already-deleted reference is just a CheckJNI warning.
   1875   {
   1876     bool old_check_jni = vm_->SetCheckJniEnabled(false);
   1877     {
   1878       CheckJniAbortCatcher check_jni_abort_catcher;
   1879       env_->DeleteLocalRef(s);
   1880     }
   1881     CheckJniAbortCatcher check_jni_abort_catcher;
   1882     EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
   1883     env_->DeleteLocalRef(s);
   1884     std::string expected(StringPrintf("use of deleted local reference %p", s));
   1885     check_jni_abort_catcher.Check(expected.c_str());
   1886     EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
   1887   }
   1888 
   1889   s = env_->NewStringUTF("");
   1890   ASSERT_NE(s, nullptr);
   1891   jobject o = env_->NewLocalRef(s);
   1892   ASSERT_NE(o, nullptr);
   1893 
   1894   env_->DeleteLocalRef(s);
   1895   env_->DeleteLocalRef(o);
   1896 }
   1897 
   1898 TEST_F(JniInternalTest, PushLocalFrame_10395422) {
   1899   // The JNI specification is ambiguous about whether the given capacity is to be interpreted as a
   1900   // maximum or as a minimum, but it seems like it's supposed to be a minimum, and that's how
   1901   // Android historically treated it, and it's how the RI treats it. It's also the more useful
   1902   // interpretation!
   1903   ASSERT_EQ(JNI_OK, env_->PushLocalFrame(0));
   1904   env_->PopLocalFrame(nullptr);
   1905 
   1906   // The following two tests will print errors to the log.
   1907   ScopedLogSeverity sls(LogSeverity::FATAL);
   1908 
   1909   // Negative capacities are not allowed.
   1910   ASSERT_EQ(JNI_ERR, env_->PushLocalFrame(-1));
   1911 
   1912   // And it's okay to have an upper limit. Ours is currently 512.
   1913   ASSERT_EQ(JNI_ERR, env_->PushLocalFrame(8192));
   1914 }
   1915 
   1916 TEST_F(JniInternalTest, PushLocalFrame_PopLocalFrame) {
   1917   // This tests leads to errors in the log.
   1918   ScopedLogSeverity sls(LogSeverity::FATAL);
   1919 
   1920   jobject original = env_->NewStringUTF("");
   1921   ASSERT_NE(original, nullptr);
   1922 
   1923   jobject outer;
   1924   jobject inner1, inner2;
   1925   ScopedObjectAccess soa(env_);
   1926   {
   1927     ASSERT_EQ(JNI_OK, env_->PushLocalFrame(4));
   1928     outer = env_->NewLocalRef(original);
   1929 
   1930     {
   1931       ASSERT_EQ(JNI_OK, env_->PushLocalFrame(4));
   1932       inner1 = env_->NewLocalRef(outer);
   1933       inner2 = env_->NewStringUTF("survivor");
   1934       EXPECT_NE(env_->PopLocalFrame(inner2), nullptr);
   1935     }
   1936 
   1937     EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(original));
   1938     EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(outer));
   1939     {
   1940       CheckJniAbortCatcher check_jni_abort_catcher;
   1941       EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner1));
   1942       check_jni_abort_catcher.Check("use of deleted local reference");
   1943     }
   1944 
   1945     // Our local reference for the survivor is invalid because the survivor
   1946     // gets a new local reference...
   1947     {
   1948       CheckJniAbortCatcher check_jni_abort_catcher;
   1949       EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner2));
   1950       check_jni_abort_catcher.Check("use of deleted local reference");
   1951     }
   1952 
   1953     EXPECT_EQ(env_->PopLocalFrame(nullptr), nullptr);
   1954   }
   1955   EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(original));
   1956   CheckJniAbortCatcher check_jni_abort_catcher;
   1957   EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(outer));
   1958   check_jni_abort_catcher.Check("use of deleted local reference");
   1959   EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner1));
   1960   check_jni_abort_catcher.Check("use of deleted local reference");
   1961   EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner2));
   1962   check_jni_abort_catcher.Check("use of deleted local reference");
   1963 }
   1964 
   1965 TEST_F(JniInternalTest, NewGlobalRef_nullptr) {
   1966   EXPECT_EQ(env_->NewGlobalRef(nullptr), nullptr);
   1967 }
   1968 
   1969 TEST_F(JniInternalTest, NewGlobalRef) {
   1970   jstring s = env_->NewStringUTF("");
   1971   ASSERT_NE(s, nullptr);
   1972   jobject o = env_->NewGlobalRef(s);
   1973   EXPECT_NE(o, nullptr);
   1974   EXPECT_NE(o, s);
   1975 
   1976   EXPECT_EQ(env_->GetObjectRefType(o), JNIGlobalRefType);
   1977 }
   1978 
   1979 TEST_F(JniInternalTest, DeleteGlobalRef_nullptr) {
   1980   env_->DeleteGlobalRef(nullptr);
   1981 }
   1982 
   1983 TEST_F(JniInternalTest, DeleteGlobalRef) {
   1984   // This tests leads to warnings and errors in the log.
   1985   ScopedLogSeverity sls(LogSeverity::FATAL);
   1986 
   1987   jstring s = env_->NewStringUTF("");
   1988   ASSERT_NE(s, nullptr);
   1989 
   1990   jobject o = env_->NewGlobalRef(s);
   1991   ASSERT_NE(o, nullptr);
   1992   env_->DeleteGlobalRef(o);
   1993 
   1994   // Currently, deleting an already-deleted reference is just a CheckJNI warning.
   1995   {
   1996     bool old_check_jni = vm_->SetCheckJniEnabled(false);
   1997     {
   1998       CheckJniAbortCatcher check_jni_abort_catcher;
   1999       env_->DeleteGlobalRef(o);
   2000     }
   2001     CheckJniAbortCatcher check_jni_abort_catcher;
   2002     EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
   2003     env_->DeleteGlobalRef(o);
   2004     std::string expected(StringPrintf("use of deleted global reference %p", o));
   2005     check_jni_abort_catcher.Check(expected.c_str());
   2006     EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
   2007   }
   2008 
   2009   jobject o1 = env_->NewGlobalRef(s);
   2010   ASSERT_NE(o1, nullptr);
   2011   jobject o2 = env_->NewGlobalRef(s);
   2012   ASSERT_NE(o2, nullptr);
   2013 
   2014   env_->DeleteGlobalRef(o1);
   2015   env_->DeleteGlobalRef(o2);
   2016 }
   2017 
   2018 TEST_F(JniInternalTest, NewWeakGlobalRef_nullptr) {
   2019   EXPECT_EQ(env_->NewWeakGlobalRef(nullptr),   nullptr);
   2020 }
   2021 
   2022 TEST_F(JniInternalTest, NewWeakGlobalRef) {
   2023   jstring s = env_->NewStringUTF("");
   2024   ASSERT_NE(s, nullptr);
   2025   jobject o = env_->NewWeakGlobalRef(s);
   2026   EXPECT_NE(o, nullptr);
   2027   EXPECT_NE(o, s);
   2028 
   2029   EXPECT_EQ(env_->GetObjectRefType(o), JNIWeakGlobalRefType);
   2030 }
   2031 
   2032 TEST_F(JniInternalTest, DeleteWeakGlobalRef_nullptr) {
   2033   env_->DeleteWeakGlobalRef(nullptr);
   2034 }
   2035 
   2036 TEST_F(JniInternalTest, DeleteWeakGlobalRef) {
   2037   // This tests leads to warnings and errors in the log.
   2038   ScopedLogSeverity sls(LogSeverity::FATAL);
   2039 
   2040   jstring s = env_->NewStringUTF("");
   2041   ASSERT_NE(s, nullptr);
   2042 
   2043   jobject o = env_->NewWeakGlobalRef(s);
   2044   ASSERT_NE(o, nullptr);
   2045   env_->DeleteWeakGlobalRef(o);
   2046 
   2047   // Currently, deleting an already-deleted reference is just a CheckJNI warning.
   2048   {
   2049     bool old_check_jni = vm_->SetCheckJniEnabled(false);
   2050     {
   2051       CheckJniAbortCatcher check_jni_abort_catcher;
   2052       env_->DeleteWeakGlobalRef(o);
   2053     }
   2054     CheckJniAbortCatcher check_jni_abort_catcher;
   2055     EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
   2056     env_->DeleteWeakGlobalRef(o);
   2057     std::string expected(StringPrintf("use of deleted weak global reference %p", o));
   2058     check_jni_abort_catcher.Check(expected.c_str());
   2059     EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
   2060   }
   2061 
   2062   jobject o1 = env_->NewWeakGlobalRef(s);
   2063   ASSERT_NE(o1, nullptr);
   2064   jobject o2 = env_->NewWeakGlobalRef(s);
   2065   ASSERT_NE(o2, nullptr);
   2066 
   2067   env_->DeleteWeakGlobalRef(o1);
   2068   env_->DeleteWeakGlobalRef(o2);
   2069 }
   2070 
   2071 TEST_F(JniInternalTest, ExceptionDescribe) {
   2072   // This checks how ExceptionDescribe handles call without exception.
   2073   env_->ExceptionClear();
   2074   env_->ExceptionDescribe();
   2075 }
   2076 
   2077 TEST_F(JniInternalTest, Throw) {
   2078   jclass exception_class = env_->FindClass("java/lang/RuntimeException");
   2079   ASSERT_TRUE(exception_class != nullptr);
   2080   jthrowable exception = reinterpret_cast<jthrowable>(env_->AllocObject(exception_class));
   2081   ASSERT_TRUE(exception != nullptr);
   2082 
   2083   EXPECT_EQ(JNI_OK, env_->Throw(exception));
   2084   EXPECT_TRUE(env_->ExceptionCheck());
   2085   jthrowable thrown_exception = env_->ExceptionOccurred();
   2086   env_->ExceptionClear();
   2087   EXPECT_TRUE(env_->IsSameObject(exception, thrown_exception));
   2088 
   2089   // Bad argument.
   2090   bool old_check_jni = vm_->SetCheckJniEnabled(false);
   2091   EXPECT_EQ(JNI_ERR, env_->Throw(nullptr));
   2092   EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
   2093   CheckJniAbortCatcher check_jni_abort_catcher;
   2094   EXPECT_EQ(JNI_ERR, env_->Throw(nullptr));
   2095   check_jni_abort_catcher.Check("Throw received NULL jthrowable");
   2096   EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
   2097 }
   2098 
   2099 TEST_F(JniInternalTest, ThrowNew) {
   2100   jclass exception_class = env_->FindClass("java/lang/RuntimeException");
   2101   ASSERT_TRUE(exception_class != nullptr);
   2102 
   2103   jthrowable thrown_exception;
   2104 
   2105   EXPECT_EQ(JNI_OK, env_->ThrowNew(exception_class, "hello world"));
   2106   EXPECT_TRUE(env_->ExceptionCheck());
   2107   thrown_exception = env_->ExceptionOccurred();
   2108   env_->ExceptionClear();
   2109   EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, exception_class));
   2110 
   2111   EXPECT_EQ(JNI_OK, env_->ThrowNew(exception_class, nullptr));
   2112   EXPECT_TRUE(env_->ExceptionCheck());
   2113   thrown_exception = env_->ExceptionOccurred();
   2114   env_->ExceptionClear();
   2115   EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, exception_class));
   2116 
   2117   // Bad argument.
   2118   bool old_check_jni = vm_->SetCheckJniEnabled(false);
   2119   CheckJniAbortCatcher check_jni_abort_catcher;
   2120   EXPECT_EQ(JNI_ERR, env_->ThrowNew(nullptr, nullptr));
   2121   check_jni_abort_catcher.Check("c == null");
   2122   EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
   2123   EXPECT_EQ(JNI_ERR, env_->ThrowNew(nullptr, nullptr));
   2124   check_jni_abort_catcher.Check("ThrowNew received NULL jclass");
   2125   EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
   2126 }
   2127 
   2128 TEST_F(JniInternalTest, NewDirectBuffer_GetDirectBufferAddress_GetDirectBufferCapacity) {
   2129   // Start runtime.
   2130   Thread* self = Thread::Current();
   2131   self->TransitionFromSuspendedToRunnable();
   2132   MakeExecutable(nullptr, "java.lang.Class");
   2133   MakeExecutable(nullptr, "java.lang.Object");
   2134   MakeExecutable(nullptr, "java.nio.DirectByteBuffer");
   2135   MakeExecutable(nullptr, "java.nio.Bits");
   2136   MakeExecutable(nullptr, "java.nio.MappedByteBuffer");
   2137   MakeExecutable(nullptr, "java.nio.ByteBuffer");
   2138   MakeExecutable(nullptr, "java.nio.Buffer");
   2139   // TODO: we only load a dex file here as starting the runtime relies upon it.
   2140   const char* class_name = "StaticLeafMethods";
   2141   LoadDex(class_name);
   2142   bool started = runtime_->Start();
   2143   ASSERT_TRUE(started);
   2144 
   2145   jclass buffer_class = env_->FindClass("java/nio/Buffer");
   2146   ASSERT_NE(buffer_class, nullptr);
   2147 
   2148   char bytes[1024];
   2149   jobject buffer = env_->NewDirectByteBuffer(bytes, sizeof(bytes));
   2150   ASSERT_NE(buffer, nullptr);
   2151   ASSERT_TRUE(env_->IsInstanceOf(buffer, buffer_class));
   2152   ASSERT_EQ(env_->GetDirectBufferAddress(buffer), bytes);
   2153   ASSERT_EQ(env_->GetDirectBufferCapacity(buffer), static_cast<jlong>(sizeof(bytes)));
   2154 
   2155   {
   2156     CheckJniAbortCatcher check_jni_abort_catcher;
   2157     env_->NewDirectByteBuffer(bytes, static_cast<jlong>(INT_MAX) + 1);
   2158     check_jni_abort_catcher.Check("in call to NewDirectByteBuffer");
   2159   }
   2160 }
   2161 
   2162 TEST_F(JniInternalTest, MonitorEnterExit) {
   2163   // This will print some error messages. Suppress.
   2164   ScopedLogSeverity sls(LogSeverity::FATAL);
   2165 
   2166   // Create an object to torture.
   2167   jclass object_class = env_->FindClass("java/lang/Object");
   2168   ASSERT_NE(object_class, nullptr);
   2169   jobject object = env_->AllocObject(object_class);
   2170   ASSERT_NE(object, nullptr);
   2171 
   2172   // Expected class of exceptions
   2173   jclass imse_class = env_->FindClass("java/lang/IllegalMonitorStateException");
   2174   ASSERT_NE(imse_class, nullptr);
   2175 
   2176   jthrowable thrown_exception;
   2177 
   2178   // Unlock of unowned monitor
   2179   env_->MonitorExit(object);
   2180   EXPECT_TRUE(env_->ExceptionCheck());
   2181   thrown_exception = env_->ExceptionOccurred();
   2182   env_->ExceptionClear();
   2183   EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, imse_class));
   2184 
   2185   // Lock of unowned monitor
   2186   env_->MonitorEnter(object);
   2187   EXPECT_FALSE(env_->ExceptionCheck());
   2188   // Regular unlock
   2189   env_->MonitorExit(object);
   2190   EXPECT_FALSE(env_->ExceptionCheck());
   2191 
   2192   // Recursively lock a lot
   2193   size_t max_recursive_lock = 1024;
   2194   for (size_t i = 0; i < max_recursive_lock; i++) {
   2195     env_->MonitorEnter(object);
   2196     EXPECT_FALSE(env_->ExceptionCheck());
   2197   }
   2198   // Recursively unlock a lot
   2199   for (size_t i = 0; i < max_recursive_lock; i++) {
   2200     env_->MonitorExit(object);
   2201     EXPECT_FALSE(env_->ExceptionCheck());
   2202   }
   2203 
   2204   // Unlock of unowned monitor
   2205   env_->MonitorExit(object);
   2206   EXPECT_TRUE(env_->ExceptionCheck());
   2207   thrown_exception = env_->ExceptionOccurred();
   2208   env_->ExceptionClear();
   2209   EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, imse_class));
   2210 
   2211   // It's an error to call MonitorEnter or MonitorExit on null.
   2212   {
   2213     CheckJniAbortCatcher check_jni_abort_catcher;
   2214     env_->MonitorEnter(nullptr);
   2215     check_jni_abort_catcher.Check("in call to MonitorEnter");
   2216     env_->MonitorExit(nullptr);
   2217     check_jni_abort_catcher.Check("in call to MonitorExit");
   2218   }
   2219 }
   2220 
   2221 void Java_MyClassNatives_foo_exit(JNIEnv* env, jobject thisObj) {
   2222   // Release the monitor on self. This should trigger an abort.
   2223   env->MonitorExit(thisObj);
   2224 }
   2225 
   2226 TEST_F(JniInternalTest, MonitorExitLockedInDifferentCall) {
   2227   SetUpForTest(false, "foo", "()V", reinterpret_cast<void*>(&Java_MyClassNatives_foo_exit));
   2228   ASSERT_NE(jobj_, nullptr);
   2229 
   2230   env_->MonitorEnter(jobj_);
   2231   EXPECT_FALSE(env_->ExceptionCheck());
   2232 
   2233   CheckJniAbortCatcher check_jni_abort_catcher;
   2234   env_->CallNonvirtualVoidMethod(jobj_, jklass_, jmethod_);
   2235   check_jni_abort_catcher.Check("Unlocking monitor that wasn't locked here");
   2236 }
   2237 
   2238 void Java_MyClassNatives_foo_enter_no_exit(JNIEnv* env, jobject thisObj) {
   2239   // Acquire but don't release the monitor on self. This should trigger an abort on return.
   2240   env->MonitorEnter(thisObj);
   2241 }
   2242 
   2243 TEST_F(JniInternalTest, MonitorExitNotAllUnlocked) {
   2244   SetUpForTest(false,
   2245                "foo",
   2246                "()V",
   2247                reinterpret_cast<void*>(&Java_MyClassNatives_foo_enter_no_exit));
   2248   ASSERT_NE(jobj_, nullptr);
   2249 
   2250   CheckJniAbortCatcher check_jni_abort_catcher;
   2251   env_->CallNonvirtualVoidMethod(jobj_, jklass_, jmethod_);
   2252   check_jni_abort_catcher.Check("Still holding a locked object on JNI end");
   2253 }
   2254 
   2255 static bool IsLocked(JNIEnv* env, jobject jobj) {
   2256   ScopedObjectAccess soa(env);
   2257   LockWord lock_word = soa.Decode<mirror::Object>(jobj)->GetLockWord(true);
   2258   switch (lock_word.GetState()) {
   2259     case LockWord::kHashCode:
   2260     case LockWord::kUnlocked:
   2261       return false;
   2262     case LockWord::kThinLocked:
   2263       return true;
   2264     case LockWord::kFatLocked:
   2265       return lock_word.FatLockMonitor()->IsLocked();
   2266     default: {
   2267       LOG(FATAL) << "Invalid monitor state " << lock_word.GetState();
   2268       UNREACHABLE();
   2269     }
   2270   }
   2271 }
   2272 
   2273 TEST_F(JniInternalTest, DetachThreadUnlockJNIMonitors) {
   2274   // We need to lock an object, detach, reattach, and check the locks.
   2275   //
   2276   // As re-attaching will create a different thread, we need to use a global
   2277   // ref to keep the object around.
   2278 
   2279   // Create an object to torture.
   2280   jobject global_ref;
   2281   {
   2282     jclass object_class = env_->FindClass("java/lang/Object");
   2283     ASSERT_NE(object_class, nullptr);
   2284     jobject object = env_->AllocObject(object_class);
   2285     ASSERT_NE(object, nullptr);
   2286     global_ref = env_->NewGlobalRef(object);
   2287   }
   2288 
   2289   // Lock it.
   2290   env_->MonitorEnter(global_ref);
   2291   ASSERT_TRUE(IsLocked(env_, global_ref));
   2292 
   2293   // Detach and re-attach.
   2294   jint detach_result = vm_->DetachCurrentThread();
   2295   ASSERT_EQ(detach_result, JNI_OK);
   2296   jint attach_result = vm_->AttachCurrentThread(&env_, nullptr);
   2297   ASSERT_EQ(attach_result, JNI_OK);
   2298 
   2299   // Look at the global ref, check whether it's still locked.
   2300   ASSERT_FALSE(IsLocked(env_, global_ref));
   2301 
   2302   // Delete the global ref.
   2303   env_->DeleteGlobalRef(global_ref);
   2304 }
   2305 
   2306 // Test the offset computation of IndirectReferenceTable offsets. b/26071368.
   2307 TEST_F(JniInternalTest, IndirectReferenceTableOffsets) {
   2308   // The segment_state_ field is private, and we want to avoid friend declaration. So we'll check
   2309   // by modifying memory.
   2310   // The parameters don't really matter here.
   2311   std::string error_msg;
   2312   IndirectReferenceTable irt(5,
   2313                              IndirectRefKind::kGlobal,
   2314                              IndirectReferenceTable::ResizableCapacity::kNo,
   2315                              &error_msg);
   2316   ASSERT_TRUE(irt.IsValid()) << error_msg;
   2317   IRTSegmentState old_state = irt.GetSegmentState();
   2318 
   2319   // Write some new state directly. We invert parts of old_state to ensure a new value.
   2320   IRTSegmentState new_state;
   2321   new_state.top_index = old_state.top_index ^ 0x07705005;
   2322   ASSERT_NE(old_state.top_index, new_state.top_index);
   2323 
   2324   uint8_t* base = reinterpret_cast<uint8_t*>(&irt);
   2325   int32_t segment_state_offset =
   2326       IndirectReferenceTable::SegmentStateOffset(sizeof(void*)).Int32Value();
   2327   *reinterpret_cast<IRTSegmentState*>(base + segment_state_offset) = new_state;
   2328 
   2329   // Read and compare.
   2330   EXPECT_EQ(new_state.top_index, irt.GetSegmentState().top_index);
   2331 }
   2332 
   2333 // Test the offset computation of JNIEnvExt offsets. b/26071368.
   2334 TEST_F(JniInternalTest, JNIEnvExtOffsets) {
   2335   EXPECT_EQ(OFFSETOF_MEMBER(JNIEnvExt, local_ref_cookie),
   2336             JNIEnvExt::LocalRefCookieOffset(sizeof(void*)).Uint32Value());
   2337 
   2338   EXPECT_EQ(OFFSETOF_MEMBER(JNIEnvExt, self), JNIEnvExt::SelfOffset(sizeof(void*)).Uint32Value());
   2339 
   2340   // segment_state_ is private in the IndirectReferenceTable. So this test isn't as good as we'd
   2341   // hope it to be.
   2342   uint32_t segment_state_now =
   2343       OFFSETOF_MEMBER(JNIEnvExt, locals) +
   2344       IndirectReferenceTable::SegmentStateOffset(sizeof(void*)).Uint32Value();
   2345   uint32_t segment_state_computed = JNIEnvExt::SegmentStateOffset(sizeof(void*)).Uint32Value();
   2346   EXPECT_EQ(segment_state_now, segment_state_computed);
   2347 }
   2348 
   2349 static size_t gGlobalRefCount = 0;
   2350 static const JNINativeInterface* gOriginalEnv = nullptr;
   2351 
   2352 static jobject CountNewGlobalRef(JNIEnv* env, jobject o) {
   2353   ++gGlobalRefCount;
   2354   return gOriginalEnv->NewGlobalRef(env, o);
   2355 }
   2356 
   2357 // Test the table override.
   2358 TEST_F(JniInternalTest, JNIEnvExtTableOverride) {
   2359   JNINativeInterface env_override;
   2360   memcpy(&env_override, env_->functions, sizeof(JNINativeInterface));
   2361 
   2362   gOriginalEnv = env_->functions;
   2363   env_override.NewGlobalRef = CountNewGlobalRef;
   2364   gGlobalRefCount = 0;
   2365 
   2366   jclass local = env_->FindClass("java/lang/Object");
   2367   ASSERT_TRUE(local != nullptr);
   2368 
   2369   // Set the table, add a global ref, see whether the counter increases.
   2370   JNIEnvExt::SetTableOverride(&env_override);
   2371 
   2372   jobject global = env_->NewGlobalRef(local);
   2373   EXPECT_EQ(1u, gGlobalRefCount);
   2374   env_->DeleteGlobalRef(global);
   2375 
   2376   // Reset
   2377   JNIEnvExt::SetTableOverride(nullptr);
   2378 
   2379   jobject global2 = env_->NewGlobalRef(local);
   2380   EXPECT_EQ(1u, gGlobalRefCount);
   2381   env_->DeleteGlobalRef(global2);
   2382 }
   2383 
   2384 }  // namespace art
   2385