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