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 <limits.h>
     20 #include <cfloat>
     21 #include <cmath>
     22 
     23 #include "common_test.h"
     24 #include "invoke_arg_array_builder.h"
     25 #include "mirror/art_method-inl.h"
     26 #include "mirror/class-inl.h"
     27 #include "mirror/object_array-inl.h"
     28 #include "mirror/object-inl.h"
     29 #include "ScopedLocalRef.h"
     30 #include "sirt_ref.h"
     31 
     32 namespace art {
     33 
     34 class JniInternalTest : public CommonTest {
     35  protected:
     36   virtual void SetUp() {
     37     CommonTest::SetUp();
     38 
     39     vm_ = Runtime::Current()->GetJavaVM();
     40 
     41     // Turn on -verbose:jni for the JNI tests.
     42     // gLogVerbosity.jni = true;
     43 
     44     vm_->AttachCurrentThread(&env_, NULL);
     45 
     46     ScopedLocalRef<jclass> aioobe(env_,
     47                                   env_->FindClass("java/lang/ArrayIndexOutOfBoundsException"));
     48     CHECK(aioobe.get() != NULL);
     49     aioobe_ = reinterpret_cast<jclass>(env_->NewGlobalRef(aioobe.get()));
     50 
     51     ScopedLocalRef<jclass> ase(env_, env_->FindClass("java/lang/ArrayStoreException"));
     52     CHECK(ase.get() != NULL);
     53     ase_ = reinterpret_cast<jclass>(env_->NewGlobalRef(ase.get()));
     54 
     55     ScopedLocalRef<jclass> sioobe(env_,
     56                                   env_->FindClass("java/lang/StringIndexOutOfBoundsException"));
     57     CHECK(sioobe.get() != NULL);
     58     sioobe_ = reinterpret_cast<jclass>(env_->NewGlobalRef(sioobe.get()));
     59   }
     60 
     61   void CleanUpJniEnv() {
     62     if (aioobe_ != NULL) {
     63       env_->DeleteGlobalRef(aioobe_);
     64       aioobe_ = NULL;
     65     }
     66     if (ase_ != NULL) {
     67       env_->DeleteGlobalRef(ase_);
     68       ase_ = NULL;
     69     }
     70     if (sioobe_ != NULL) {
     71       env_->DeleteGlobalRef(sioobe_);
     72       sioobe_ = NULL;
     73     }
     74   }
     75 
     76   virtual void TearDown() {
     77     CleanUpJniEnv();
     78     CommonTest::TearDown();
     79   }
     80 
     81   void DoCompile(mirror::ArtMethod*& method,
     82                  mirror::Object*& receiver,
     83                  bool is_static, const char* method_name,
     84                  const char* method_signature)
     85       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     86     const char* class_name = is_static ? "StaticLeafMethods" : "NonStaticLeafMethods";
     87     jobject jclass_loader(LoadDex(class_name));
     88     Thread* self = Thread::Current();
     89     SirtRef<mirror::ClassLoader>
     90         class_loader(self,
     91                      ScopedObjectAccessUnchecked(self).Decode<mirror::ClassLoader*>(jclass_loader));
     92     if (is_static) {
     93       CompileDirectMethod(class_loader.get(), class_name, method_name, method_signature);
     94     } else {
     95       CompileVirtualMethod(NULL, "java.lang.Class", "isFinalizable", "()Z");
     96       CompileDirectMethod(NULL, "java.lang.Object", "<init>", "()V");
     97       CompileVirtualMethod(class_loader.get(), class_name, method_name, method_signature);
     98     }
     99 
    100     mirror::Class* c = class_linker_->FindClass(DotToDescriptor(class_name).c_str(),
    101                                                 class_loader.get());
    102     CHECK(c != NULL);
    103 
    104     method = is_static ? c->FindDirectMethod(method_name, method_signature)
    105                        : c->FindVirtualMethod(method_name, method_signature);
    106     CHECK(method != NULL);
    107 
    108     receiver = (is_static ? NULL : c->AllocObject(self));
    109 
    110     // Start runtime.
    111     bool started = runtime_->Start();
    112     CHECK(started);
    113     self->TransitionFromSuspendedToRunnable();
    114   }
    115 
    116   void InvokeNopMethod(bool is_static) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    117     mirror::ArtMethod* method;
    118     mirror::Object* receiver;
    119     DoCompile(method, receiver, is_static, "nop", "()V");
    120 
    121     ArgArray arg_array(NULL, 0);
    122     JValue result;
    123 
    124     if (!is_static) {
    125       arg_array.Append(reinterpret_cast<uint32_t>(receiver));
    126     }
    127 
    128     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'V');
    129   }
    130 
    131   void InvokeIdentityByteMethod(bool is_static)
    132       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    133     mirror::ArtMethod* method;
    134     mirror::Object* receiver;
    135     DoCompile(method, receiver, is_static, "identity", "(I)I");
    136 
    137     ArgArray arg_array(NULL, 0);
    138     uint32_t* args = arg_array.GetArray();
    139     JValue result;
    140 
    141     if (!is_static) {
    142       arg_array.Append(reinterpret_cast<uint32_t>(receiver));
    143       args++;
    144     }
    145 
    146     arg_array.Append(0);
    147     result.SetB(-1);
    148     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'B');
    149     EXPECT_EQ(0, result.GetB());
    150 
    151     args[0] = -1;
    152     result.SetB(0);
    153     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'B');
    154     EXPECT_EQ(-1, result.GetB());
    155 
    156     args[0] = SCHAR_MAX;
    157     result.SetB(0);
    158     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'B');
    159     EXPECT_EQ(SCHAR_MAX, result.GetB());
    160 
    161     args[0] = (SCHAR_MIN << 24) >> 24;
    162     result.SetB(0);
    163     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'B');
    164     EXPECT_EQ(SCHAR_MIN, result.GetB());
    165   }
    166 
    167   void InvokeIdentityIntMethod(bool is_static)
    168       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    169     mirror::ArtMethod* method;
    170     mirror::Object* receiver;
    171     DoCompile(method, receiver, is_static, "identity", "(I)I");
    172 
    173     ArgArray arg_array(NULL, 0);
    174     uint32_t* args = arg_array.GetArray();
    175     JValue result;
    176 
    177     if (!is_static) {
    178       arg_array.Append(reinterpret_cast<uint32_t>(receiver));
    179       args++;
    180     }
    181 
    182     arg_array.Append(0);
    183     result.SetI(-1);
    184     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
    185     EXPECT_EQ(0, result.GetI());
    186 
    187     args[0] = -1;
    188     result.SetI(0);
    189     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
    190     EXPECT_EQ(-1, result.GetI());
    191 
    192     args[0] = INT_MAX;
    193     result.SetI(0);
    194     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
    195     EXPECT_EQ(INT_MAX, result.GetI());
    196 
    197     args[0] = INT_MIN;
    198     result.SetI(0);
    199     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
    200     EXPECT_EQ(INT_MIN, result.GetI());
    201   }
    202 
    203   void InvokeIdentityDoubleMethod(bool is_static)
    204       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    205     mirror::ArtMethod* method;
    206     mirror::Object* receiver;
    207     DoCompile(method, receiver, is_static, "identity", "(D)D");
    208 
    209     ArgArray arg_array(NULL, 0);
    210     uint32_t* args = arg_array.GetArray();
    211     JValue value;
    212     JValue result;
    213 
    214     if (!is_static) {
    215       arg_array.Append(reinterpret_cast<uint32_t>(receiver));
    216       args++;
    217     }
    218 
    219     value.SetD(0.0);
    220     arg_array.AppendWide(value.GetJ());
    221     result.SetD(-1.0);
    222     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
    223     EXPECT_EQ(0.0, result.GetD());
    224 
    225     value.SetD(-1.0);
    226     args[0] = value.GetJ();
    227     args[1] = value.GetJ() >> 32;
    228     result.SetD(0.0);
    229     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
    230     EXPECT_EQ(-1.0, result.GetD());
    231 
    232     value.SetD(DBL_MAX);
    233     args[0] = value.GetJ();
    234     args[1] = value.GetJ() >> 32;
    235     result.SetD(0.0);
    236     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
    237     EXPECT_EQ(DBL_MAX, result.GetD());
    238 
    239     value.SetD(DBL_MIN);
    240     args[0] = value.GetJ();
    241     args[1] = value.GetJ() >> 32;
    242     result.SetD(0.0);
    243     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
    244     EXPECT_EQ(DBL_MIN, result.GetD());
    245   }
    246 
    247   void InvokeSumIntIntMethod(bool is_static)
    248       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    249     mirror::ArtMethod* method;
    250     mirror::Object* receiver;
    251     DoCompile(method, receiver, is_static, "sum", "(II)I");
    252 
    253     ArgArray arg_array(NULL, 0);
    254     uint32_t* args = arg_array.GetArray();
    255     JValue result;
    256 
    257     if (!is_static) {
    258       arg_array.Append(reinterpret_cast<uint32_t>(receiver));
    259       args++;
    260     }
    261 
    262     arg_array.Append(0);
    263     arg_array.Append(0);
    264     result.SetI(-1);
    265     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
    266     EXPECT_EQ(0, result.GetI());
    267 
    268     args[0] = 1;
    269     args[1] = 2;
    270     result.SetI(0);
    271     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
    272     EXPECT_EQ(3, result.GetI());
    273 
    274     args[0] = -2;
    275     args[1] = 5;
    276     result.SetI(0);
    277     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
    278     EXPECT_EQ(3, result.GetI());
    279 
    280     args[0] = INT_MAX;
    281     args[1] = INT_MIN;
    282     result.SetI(1234);
    283     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
    284     EXPECT_EQ(-1, result.GetI());
    285 
    286     args[0] = INT_MAX;
    287     args[1] = INT_MAX;
    288     result.SetI(INT_MIN);
    289     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
    290     EXPECT_EQ(-2, result.GetI());
    291   }
    292 
    293   void InvokeSumIntIntIntMethod(bool is_static)
    294       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    295     mirror::ArtMethod* method;
    296     mirror::Object* receiver;
    297     DoCompile(method, receiver, is_static, "sum", "(III)I");
    298 
    299     ArgArray arg_array(NULL, 0);
    300     uint32_t* args = arg_array.GetArray();
    301     JValue result;
    302 
    303     if (!is_static) {
    304       arg_array.Append(reinterpret_cast<uint32_t>(receiver));
    305       args++;
    306     }
    307 
    308     arg_array.Append(0);
    309     arg_array.Append(0);
    310     arg_array.Append(0);
    311     result.SetI(-1);
    312     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
    313     EXPECT_EQ(0, result.GetI());
    314 
    315     args[0] = 1;
    316     args[1] = 2;
    317     args[2] = 3;
    318     result.SetI(0);
    319     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
    320     EXPECT_EQ(6, result.GetI());
    321 
    322     args[0] = -1;
    323     args[1] = 2;
    324     args[2] = -3;
    325     result.SetI(0);
    326     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
    327     EXPECT_EQ(-2, result.GetI());
    328 
    329     args[0] = INT_MAX;
    330     args[1] = INT_MIN;
    331     args[2] = INT_MAX;
    332     result.SetI(1234);
    333     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
    334     EXPECT_EQ(2147483646, result.GetI());
    335 
    336     args[0] = INT_MAX;
    337     args[1] = INT_MAX;
    338     args[2] = INT_MAX;
    339     result.SetI(INT_MIN);
    340     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
    341     EXPECT_EQ(2147483645, result.GetI());
    342   }
    343 
    344   void InvokeSumIntIntIntIntMethod(bool is_static)
    345       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    346     mirror::ArtMethod* method;
    347     mirror::Object* receiver;
    348     DoCompile(method, receiver, is_static, "sum", "(IIII)I");
    349 
    350     ArgArray arg_array(NULL, 0);
    351     uint32_t* args = arg_array.GetArray();
    352     JValue result;
    353 
    354     if (!is_static) {
    355       arg_array.Append(reinterpret_cast<uint32_t>(receiver));
    356       args++;
    357     }
    358 
    359     arg_array.Append(0);
    360     arg_array.Append(0);
    361     arg_array.Append(0);
    362     arg_array.Append(0);
    363     result.SetI(-1);
    364     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
    365     EXPECT_EQ(0, result.GetI());
    366 
    367     args[0] = 1;
    368     args[1] = 2;
    369     args[2] = 3;
    370     args[3] = 4;
    371     result.SetI(0);
    372     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
    373     EXPECT_EQ(10, result.GetI());
    374 
    375     args[0] = -1;
    376     args[1] = 2;
    377     args[2] = -3;
    378     args[3] = 4;
    379     result.SetI(0);
    380     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
    381     EXPECT_EQ(2, result.GetI());
    382 
    383     args[0] = INT_MAX;
    384     args[1] = INT_MIN;
    385     args[2] = INT_MAX;
    386     args[3] = INT_MIN;
    387     result.SetI(1234);
    388     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
    389     EXPECT_EQ(-2, result.GetI());
    390 
    391     args[0] = INT_MAX;
    392     args[1] = INT_MAX;
    393     args[2] = INT_MAX;
    394     args[3] = INT_MAX;
    395     result.SetI(INT_MIN);
    396     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
    397     EXPECT_EQ(-4, result.GetI());
    398   }
    399 
    400   void InvokeSumIntIntIntIntIntMethod(bool is_static)
    401       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    402     mirror::ArtMethod* method;
    403     mirror::Object* receiver;
    404     DoCompile(method, receiver, is_static, "sum", "(IIIII)I");
    405 
    406     ArgArray arg_array(NULL, 0);
    407     uint32_t* args = arg_array.GetArray();
    408     JValue result;
    409 
    410     if (!is_static) {
    411       arg_array.Append(reinterpret_cast<uint32_t>(receiver));
    412       args++;
    413     }
    414 
    415     arg_array.Append(0);
    416     arg_array.Append(0);
    417     arg_array.Append(0);
    418     arg_array.Append(0);
    419     arg_array.Append(0);
    420     result.SetI(-1.0);
    421     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
    422     EXPECT_EQ(0, result.GetI());
    423 
    424     args[0] = 1;
    425     args[1] = 2;
    426     args[2] = 3;
    427     args[3] = 4;
    428     args[4] = 5;
    429     result.SetI(0);
    430     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
    431     EXPECT_EQ(15, result.GetI());
    432 
    433     args[0] = -1;
    434     args[1] = 2;
    435     args[2] = -3;
    436     args[3] = 4;
    437     args[4] = -5;
    438     result.SetI(0);
    439     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
    440     EXPECT_EQ(-3, result.GetI());
    441 
    442     args[0] = INT_MAX;
    443     args[1] = INT_MIN;
    444     args[2] = INT_MAX;
    445     args[3] = INT_MIN;
    446     args[4] = INT_MAX;
    447     result.SetI(1234);
    448     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
    449     EXPECT_EQ(2147483645, result.GetI());
    450 
    451     args[0] = INT_MAX;
    452     args[1] = INT_MAX;
    453     args[2] = INT_MAX;
    454     args[3] = INT_MAX;
    455     args[4] = INT_MAX;
    456     result.SetI(INT_MIN);
    457     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
    458     EXPECT_EQ(2147483643, result.GetI());
    459   }
    460 
    461   void InvokeSumDoubleDoubleMethod(bool is_static)
    462       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    463     mirror::ArtMethod* method;
    464     mirror::Object* receiver;
    465     DoCompile(method, receiver, is_static, "sum", "(DD)D");
    466 
    467     ArgArray arg_array(NULL, 0);
    468     uint32_t* args = arg_array.GetArray();
    469     JValue value;
    470     JValue value2;
    471     JValue result;
    472 
    473     if (!is_static) {
    474       arg_array.Append(reinterpret_cast<uint32_t>(receiver));
    475       args++;
    476     }
    477 
    478     value.SetD(0.0);
    479     value2.SetD(0.0);
    480     arg_array.AppendWide(value.GetJ());
    481     arg_array.AppendWide(value2.GetJ());
    482     result.SetD(-1.0);
    483     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
    484     EXPECT_EQ(0.0, result.GetD());
    485 
    486     value.SetD(1.0);
    487     value2.SetD(2.0);
    488     args[0] = value.GetJ();
    489     args[1] = value.GetJ() >> 32;
    490     args[2] = value2.GetJ();
    491     args[3] = value2.GetJ() >> 32;
    492     result.SetD(0.0);
    493     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
    494     EXPECT_EQ(3.0, result.GetD());
    495 
    496     value.SetD(1.0);
    497     value2.SetD(-2.0);
    498     args[0] = value.GetJ();
    499     args[1] = value.GetJ() >> 32;
    500     args[2] = value2.GetJ();
    501     args[3] = value2.GetJ() >> 32;
    502     result.SetD(0.0);
    503     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
    504     EXPECT_EQ(-1.0, result.GetD());
    505 
    506     value.SetD(DBL_MAX);
    507     value2.SetD(DBL_MIN);
    508     args[0] = value.GetJ();
    509     args[1] = value.GetJ() >> 32;
    510     args[2] = value2.GetJ();
    511     args[3] = value2.GetJ() >> 32;
    512     result.SetD(0.0);
    513     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
    514     EXPECT_EQ(1.7976931348623157e308, result.GetD());
    515 
    516     value.SetD(DBL_MAX);
    517     value2.SetD(DBL_MAX);
    518     args[0] = value.GetJ();
    519     args[1] = value.GetJ() >> 32;
    520     args[2] = value2.GetJ();
    521     args[3] = value2.GetJ() >> 32;
    522     result.SetD(0.0);
    523     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
    524     EXPECT_EQ(INFINITY, result.GetD());
    525   }
    526 
    527   void InvokeSumDoubleDoubleDoubleMethod(bool is_static)
    528       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    529     mirror::ArtMethod* method;
    530     mirror::Object* receiver;
    531     DoCompile(method, receiver, is_static, "sum", "(DDD)D");
    532 
    533     ArgArray arg_array(NULL, 0);
    534     uint32_t* args = arg_array.GetArray();
    535     JValue value;
    536     JValue value2;
    537     JValue value3;
    538     JValue result;
    539 
    540     if (!is_static) {
    541       arg_array.Append(reinterpret_cast<uint32_t>(receiver));
    542       args++;
    543     }
    544 
    545     value.SetD(0.0);
    546     value2.SetD(0.0);
    547     value3.SetD(0.0);
    548     arg_array.AppendWide(value.GetJ());
    549     arg_array.AppendWide(value2.GetJ());
    550     arg_array.AppendWide(value3.GetJ());
    551     result.SetD(-1.0);
    552     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
    553     EXPECT_EQ(0.0, result.GetD());
    554 
    555     value.SetD(1.0);
    556     value2.SetD(2.0);
    557     value3.SetD(3.0);
    558     args[0] = value.GetJ();
    559     args[1] = value.GetJ() >> 32;
    560     args[2] = value2.GetJ();
    561     args[3] = value2.GetJ() >> 32;
    562     args[4] = value3.GetJ();
    563     args[5] = value3.GetJ() >> 32;
    564     result.SetD(0.0);
    565     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
    566     EXPECT_EQ(6.0, result.GetD());
    567 
    568     value.SetD(1.0);
    569     value2.SetD(-2.0);
    570     value3.SetD(3.0);
    571     args[0] = value.GetJ();
    572     args[1] = value.GetJ() >> 32;
    573     args[2] = value2.GetJ();
    574     args[3] = value2.GetJ() >> 32;
    575     args[4] = value3.GetJ();
    576     args[5] = value3.GetJ() >> 32;
    577     result.SetD(0.0);
    578     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
    579     EXPECT_EQ(2.0, result.GetD());
    580   }
    581 
    582   void InvokeSumDoubleDoubleDoubleDoubleMethod(bool is_static)
    583       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    584     mirror::ArtMethod* method;
    585     mirror::Object* receiver;
    586     DoCompile(method, receiver, is_static, "sum", "(DDDD)D");
    587 
    588     ArgArray arg_array(NULL, 0);
    589     uint32_t* args = arg_array.GetArray();
    590     JValue value;
    591     JValue value2;
    592     JValue value3;
    593     JValue value4;
    594     JValue result;
    595 
    596     if (!is_static) {
    597       arg_array.Append(reinterpret_cast<uint32_t>(receiver));
    598       args++;
    599     }
    600 
    601     value.SetD(0.0);
    602     value2.SetD(0.0);
    603     value3.SetD(0.0);
    604     value4.SetD(0.0);
    605     arg_array.AppendWide(value.GetJ());
    606     arg_array.AppendWide(value2.GetJ());
    607     arg_array.AppendWide(value3.GetJ());
    608     arg_array.AppendWide(value4.GetJ());
    609     result.SetD(-1.0);
    610     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
    611     EXPECT_EQ(0.0, result.GetD());
    612 
    613     value.SetD(1.0);
    614     value2.SetD(2.0);
    615     value3.SetD(3.0);
    616     value4.SetD(4.0);
    617     args[0] = value.GetJ();
    618     args[1] = value.GetJ() >> 32;
    619     args[2] = value2.GetJ();
    620     args[3] = value2.GetJ() >> 32;
    621     args[4] = value3.GetJ();
    622     args[5] = value3.GetJ() >> 32;
    623     args[6] = value4.GetJ();
    624     args[7] = value4.GetJ() >> 32;
    625     result.SetD(0.0);
    626     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
    627     EXPECT_EQ(10.0, result.GetD());
    628 
    629     value.SetD(1.0);
    630     value2.SetD(-2.0);
    631     value3.SetD(3.0);
    632     value4.SetD(-4.0);
    633     args[0] = value.GetJ();
    634     args[1] = value.GetJ() >> 32;
    635     args[2] = value2.GetJ();
    636     args[3] = value2.GetJ() >> 32;
    637     args[4] = value3.GetJ();
    638     args[5] = value3.GetJ() >> 32;
    639     args[6] = value4.GetJ();
    640     args[7] = value4.GetJ() >> 32;
    641     result.SetD(0.0);
    642     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
    643     EXPECT_EQ(-2.0, result.GetD());
    644   }
    645 
    646   void InvokeSumDoubleDoubleDoubleDoubleDoubleMethod(bool is_static)
    647       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    648     mirror::ArtMethod* method;
    649     mirror::Object* receiver;
    650     DoCompile(method, receiver, is_static, "sum", "(DDDDD)D");
    651 
    652     ArgArray arg_array(NULL, 0);
    653     uint32_t* args = arg_array.GetArray();
    654     JValue value;
    655     JValue value2;
    656     JValue value3;
    657     JValue value4;
    658     JValue value5;
    659     JValue result;
    660 
    661     if (!is_static) {
    662       arg_array.Append(reinterpret_cast<uint32_t>(receiver));
    663       args++;
    664     }
    665 
    666     value.SetD(0.0);
    667     value2.SetD(0.0);
    668     value3.SetD(0.0);
    669     value4.SetD(0.0);
    670     value5.SetD(0.0);
    671     arg_array.AppendWide(value.GetJ());
    672     arg_array.AppendWide(value2.GetJ());
    673     arg_array.AppendWide(value3.GetJ());
    674     arg_array.AppendWide(value4.GetJ());
    675     arg_array.AppendWide(value5.GetJ());
    676     result.SetD(-1.0);
    677     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
    678     EXPECT_EQ(0.0, result.GetD());
    679 
    680     value.SetD(1.0);
    681     value2.SetD(2.0);
    682     value3.SetD(3.0);
    683     value4.SetD(4.0);
    684     value5.SetD(5.0);
    685     args[0] = value.GetJ();
    686     args[1] = value.GetJ() >> 32;
    687     args[2] = value2.GetJ();
    688     args[3] = value2.GetJ() >> 32;
    689     args[4] = value3.GetJ();
    690     args[5] = value3.GetJ() >> 32;
    691     args[6] = value4.GetJ();
    692     args[7] = value4.GetJ() >> 32;
    693     args[8] = value5.GetJ();
    694     args[9] = value5.GetJ() >> 32;
    695     result.SetD(0.0);
    696     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
    697     EXPECT_EQ(15.0, result.GetD());
    698 
    699     value.SetD(1.0);
    700     value2.SetD(-2.0);
    701     value3.SetD(3.0);
    702     value4.SetD(-4.0);
    703     value5.SetD(5.0);
    704     args[0] = value.GetJ();
    705     args[1] = value.GetJ() >> 32;
    706     args[2] = value2.GetJ();
    707     args[3] = value2.GetJ() >> 32;
    708     args[4] = value3.GetJ();
    709     args[5] = value3.GetJ() >> 32;
    710     args[6] = value4.GetJ();
    711     args[7] = value4.GetJ() >> 32;
    712     args[8] = value5.GetJ();
    713     args[9] = value5.GetJ() >> 32;
    714     result.SetD(0.0);
    715     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
    716     EXPECT_EQ(3.0, result.GetD());
    717   }
    718 
    719   JavaVMExt* vm_;
    720   JNIEnv* env_;
    721   jclass aioobe_;
    722   jclass ase_;
    723   jclass sioobe_;
    724 };
    725 
    726 TEST_F(JniInternalTest, AllocObject) {
    727   jclass c = env_->FindClass("java/lang/String");
    728   ASSERT_TRUE(c != NULL);
    729   jobject o = env_->AllocObject(c);
    730   ASSERT_TRUE(o != NULL);
    731 
    732   // We have an instance of the class we asked for...
    733   ASSERT_TRUE(env_->IsInstanceOf(o, c));
    734   // ...whose fields haven't been initialized because
    735   // we didn't call a constructor.
    736   ASSERT_EQ(0, env_->GetIntField(o, env_->GetFieldID(c, "count", "I")));
    737   ASSERT_EQ(0, env_->GetIntField(o, env_->GetFieldID(c, "offset", "I")));
    738   ASSERT_TRUE(env_->GetObjectField(o, env_->GetFieldID(c, "value", "[C")) == NULL);
    739 }
    740 
    741 TEST_F(JniInternalTest, GetVersion) {
    742   ASSERT_EQ(JNI_VERSION_1_6, env_->GetVersion());
    743 }
    744 
    745 #define EXPECT_CLASS_FOUND(NAME) \
    746   EXPECT_TRUE(env_->FindClass(NAME) != NULL); \
    747   EXPECT_FALSE(env_->ExceptionCheck())
    748 
    749 #define EXPECT_CLASS_NOT_FOUND(NAME) \
    750   EXPECT_TRUE(env_->FindClass(NAME) == NULL); \
    751   EXPECT_TRUE(env_->ExceptionCheck()); \
    752   env_->ExceptionClear()
    753 
    754 TEST_F(JniInternalTest, FindClass) {
    755   // Reference types...
    756   EXPECT_CLASS_FOUND("java/lang/String");
    757   // ...for arrays too, where you must include "L;".
    758   EXPECT_CLASS_FOUND("[Ljava/lang/String;");
    759   // Primitive arrays are okay too, if the primitive type is valid.
    760   EXPECT_CLASS_FOUND("[C");
    761 
    762   {
    763     // We support . as well as / for compatibility, if -Xcheck:jni is off.
    764     CheckJniAbortCatcher check_jni_abort_catcher;
    765     EXPECT_CLASS_FOUND("java.lang.String");
    766     check_jni_abort_catcher.Check("illegal class name 'java.lang.String'");
    767     EXPECT_CLASS_NOT_FOUND("Ljava.lang.String;");
    768     check_jni_abort_catcher.Check("illegal class name 'Ljava.lang.String;'");
    769     EXPECT_CLASS_FOUND("[Ljava.lang.String;");
    770     check_jni_abort_catcher.Check("illegal class name '[Ljava.lang.String;'");
    771     EXPECT_CLASS_NOT_FOUND("[java.lang.String");
    772     check_jni_abort_catcher.Check("illegal class name '[java.lang.String'");
    773 
    774     // You can't include the "L;" in a JNI class descriptor.
    775     EXPECT_CLASS_NOT_FOUND("Ljava/lang/String;");
    776     check_jni_abort_catcher.Check("illegal class name 'Ljava/lang/String;'");
    777 
    778     // But you must include it for an array of any reference type.
    779     EXPECT_CLASS_NOT_FOUND("[java/lang/String");
    780     check_jni_abort_catcher.Check("illegal class name '[java/lang/String'");
    781 
    782     EXPECT_CLASS_NOT_FOUND("[K");
    783     check_jni_abort_catcher.Check("illegal class name '[K'");
    784   }
    785 
    786   // But primitive types aren't allowed...
    787   EXPECT_CLASS_NOT_FOUND("C");
    788   EXPECT_CLASS_NOT_FOUND("K");
    789 }
    790 
    791 #define EXPECT_EXCEPTION(exception_class) \
    792   do { \
    793     EXPECT_TRUE(env_->ExceptionCheck()); \
    794     jthrowable exception = env_->ExceptionOccurred(); \
    795     EXPECT_NE(static_cast<jthrowable>(NULL), exception); \
    796     env_->ExceptionClear(); \
    797     EXPECT_TRUE(env_->IsInstanceOf(exception, exception_class)); \
    798   } while (false)
    799 
    800 TEST_F(JniInternalTest, GetFieldID) {
    801   jclass jlnsfe = env_->FindClass("java/lang/NoSuchFieldError");
    802   ASSERT_TRUE(jlnsfe != NULL);
    803   jclass c = env_->FindClass("java/lang/String");
    804   ASSERT_TRUE(c != NULL);
    805 
    806   // Wrong type.
    807   jfieldID fid = env_->GetFieldID(c, "count", "J");
    808   EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
    809   EXPECT_EXCEPTION(jlnsfe);
    810 
    811   // Wrong type where type doesn't exist.
    812   fid = env_->GetFieldID(c, "count", "Lrod/jane/freddy;");
    813   EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
    814   EXPECT_EXCEPTION(jlnsfe);
    815 
    816   // Wrong name.
    817   fid = env_->GetFieldID(c, "Count", "I");
    818   EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
    819   EXPECT_EXCEPTION(jlnsfe);
    820 
    821   // Good declared field lookup.
    822   fid = env_->GetFieldID(c, "count", "I");
    823   EXPECT_NE(static_cast<jfieldID>(NULL), fid);
    824   EXPECT_TRUE(fid != NULL);
    825   EXPECT_FALSE(env_->ExceptionCheck());
    826 
    827   // Good superclass field lookup.
    828   c = env_->FindClass("java/lang/StringBuilder");
    829   fid = env_->GetFieldID(c, "count", "I");
    830   EXPECT_NE(static_cast<jfieldID>(NULL), fid);
    831   EXPECT_TRUE(fid != NULL);
    832   EXPECT_FALSE(env_->ExceptionCheck());
    833 
    834   // Not instance.
    835   fid = env_->GetFieldID(c, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
    836   EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
    837   EXPECT_EXCEPTION(jlnsfe);
    838 }
    839 
    840 TEST_F(JniInternalTest, GetStaticFieldID) {
    841   jclass jlnsfe = env_->FindClass("java/lang/NoSuchFieldError");
    842   ASSERT_TRUE(jlnsfe != NULL);
    843   jclass c = env_->FindClass("java/lang/String");
    844   ASSERT_TRUE(c != NULL);
    845 
    846   // Wrong type.
    847   jfieldID fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "J");
    848   EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
    849   EXPECT_EXCEPTION(jlnsfe);
    850 
    851   // Wrong type where type doesn't exist.
    852   fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "Lrod/jane/freddy;");
    853   EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
    854   EXPECT_EXCEPTION(jlnsfe);
    855 
    856   // Wrong name.
    857   fid = env_->GetStaticFieldID(c, "cASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
    858   EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
    859   EXPECT_EXCEPTION(jlnsfe);
    860 
    861   // Good declared field lookup.
    862   fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
    863   EXPECT_NE(static_cast<jfieldID>(NULL), fid);
    864   EXPECT_TRUE(fid != NULL);
    865   EXPECT_FALSE(env_->ExceptionCheck());
    866 
    867   // Not static.
    868   fid = env_->GetStaticFieldID(c, "count", "I");
    869   EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
    870   EXPECT_EXCEPTION(jlnsfe);
    871 }
    872 
    873 TEST_F(JniInternalTest, GetMethodID) {
    874   jclass jlobject = env_->FindClass("java/lang/Object");
    875   jclass jlstring = env_->FindClass("java/lang/String");
    876   jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
    877 
    878   // Sanity check that no exceptions are pending
    879   ASSERT_FALSE(env_->ExceptionCheck());
    880 
    881   // Check that java.lang.Object.foo() doesn't exist and NoSuchMethodError is
    882   // a pending exception
    883   jmethodID method = env_->GetMethodID(jlobject, "foo", "()V");
    884   EXPECT_EQ(static_cast<jmethodID>(NULL), method);
    885   EXPECT_EXCEPTION(jlnsme);
    886 
    887   // Check that java.lang.Object.equals() does exist
    888   method = env_->GetMethodID(jlobject, "equals", "(Ljava/lang/Object;)Z");
    889   EXPECT_NE(static_cast<jmethodID>(NULL), method);
    890   EXPECT_FALSE(env_->ExceptionCheck());
    891 
    892   // Check that GetMethodID for java.lang.String.valueOf(int) fails as the
    893   // method is static
    894   method = env_->GetMethodID(jlstring, "valueOf", "(I)Ljava/lang/String;");
    895   EXPECT_EQ(static_cast<jmethodID>(NULL), method);
    896   EXPECT_EXCEPTION(jlnsme);
    897 
    898   // Check that GetMethodID for java.lang.NoSuchMethodError.<init>(String) finds the constructor
    899   method = env_->GetMethodID(jlnsme, "<init>", "(Ljava/lang/String;)V");
    900   EXPECT_NE(static_cast<jmethodID>(NULL), method);
    901   EXPECT_FALSE(env_->ExceptionCheck());
    902 }
    903 
    904 TEST_F(JniInternalTest, GetStaticMethodID) {
    905   jclass jlobject = env_->FindClass("java/lang/Object");
    906   jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
    907 
    908   // Sanity check that no exceptions are pending
    909   ASSERT_FALSE(env_->ExceptionCheck());
    910 
    911   // Check that java.lang.Object.foo() doesn't exist and NoSuchMethodError is
    912   // a pending exception
    913   jmethodID method = env_->GetStaticMethodID(jlobject, "foo", "()V");
    914   EXPECT_EQ(static_cast<jmethodID>(NULL), method);
    915   EXPECT_EXCEPTION(jlnsme);
    916 
    917   // Check that GetStaticMethodID for java.lang.Object.equals(Object) fails as
    918   // the method is not static
    919   method = env_->GetStaticMethodID(jlobject, "equals", "(Ljava/lang/Object;)Z");
    920   EXPECT_EQ(static_cast<jmethodID>(NULL), method);
    921   EXPECT_EXCEPTION(jlnsme);
    922 
    923   // Check that java.lang.String.valueOf(int) does exist
    924   jclass jlstring = env_->FindClass("java/lang/String");
    925   method = env_->GetStaticMethodID(jlstring, "valueOf",
    926                                    "(I)Ljava/lang/String;");
    927   EXPECT_NE(static_cast<jmethodID>(NULL), method);
    928   EXPECT_FALSE(env_->ExceptionCheck());
    929 }
    930 
    931 TEST_F(JniInternalTest, FromReflectedField_ToReflectedField) {
    932   jclass jlrField = env_->FindClass("java/lang/reflect/Field");
    933   jclass c = env_->FindClass("java/lang/String");
    934   ASSERT_TRUE(c != NULL);
    935   jfieldID fid = env_->GetFieldID(c, "count", "I");
    936   ASSERT_TRUE(fid != NULL);
    937   // Turn the fid into a java.lang.reflect.Field...
    938   jobject field = env_->ToReflectedField(c, fid, JNI_FALSE);
    939   ASSERT_TRUE(c != NULL);
    940   ASSERT_TRUE(env_->IsInstanceOf(field, jlrField));
    941   // ...and back again.
    942   jfieldID fid2 = env_->FromReflectedField(field);
    943   ASSERT_TRUE(fid2 != NULL);
    944   // Make sure we can actually use it.
    945   jstring s = env_->NewStringUTF("poop");
    946   ASSERT_EQ(4, env_->GetIntField(s, fid2));
    947 }
    948 
    949 TEST_F(JniInternalTest, FromReflectedMethod_ToReflectedMethod) {
    950   jclass jlrMethod = env_->FindClass("java/lang/reflect/Method");
    951   jclass c = env_->FindClass("java/lang/String");
    952   ASSERT_TRUE(c != NULL);
    953   jmethodID mid = env_->GetMethodID(c, "length", "()I");
    954   ASSERT_TRUE(mid != NULL);
    955   // Turn the mid into a java.lang.reflect.Method...
    956   jobject method = env_->ToReflectedMethod(c, mid, JNI_FALSE);
    957   ASSERT_TRUE(c != NULL);
    958   ASSERT_TRUE(env_->IsInstanceOf(method, jlrMethod));
    959   // ...and back again.
    960   jmethodID mid2 = env_->FromReflectedMethod(method);
    961   ASSERT_TRUE(mid2 != NULL);
    962   // Make sure we can actually use it.
    963   jstring s = env_->NewStringUTF("poop");
    964   // TODO: this should return 4, but the runtime skips the method
    965   // invoke because the runtime isn't started. In the future it would
    966   // be nice to use interpretter for things like this. This still does
    967   // validate that we have a sane jmethodID value.
    968   ASSERT_EQ(0, env_->CallIntMethod(s, mid2));
    969 }
    970 
    971 void BogusMethod() {
    972   // You can't pass NULL function pointers to RegisterNatives.
    973 }
    974 
    975 TEST_F(JniInternalTest, RegisterNatives) {
    976   jclass jlobject = env_->FindClass("java/lang/Object");
    977   jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
    978 
    979   // Sanity check that no exceptions are pending
    980   ASSERT_FALSE(env_->ExceptionCheck());
    981 
    982   // Check that registering to a non-existent java.lang.Object.foo() causes a
    983   // NoSuchMethodError
    984   {
    985     JNINativeMethod methods[] = { { "foo", "()V", NULL } };
    986     env_->RegisterNatives(jlobject, methods, 1);
    987   }
    988   EXPECT_EXCEPTION(jlnsme);
    989 
    990   // Check that registering non-native methods causes a NoSuchMethodError
    991   {
    992     JNINativeMethod methods[] = { { "equals", "(Ljava/lang/Object;)Z", NULL } };
    993     env_->RegisterNatives(jlobject, methods, 1);
    994   }
    995   EXPECT_EXCEPTION(jlnsme);
    996 
    997   // Check that registering native methods is successful
    998   {
    999     JNINativeMethod methods[] = { { "notify", "()V", reinterpret_cast<void*>(BogusMethod) } };
   1000     env_->RegisterNatives(jlobject, methods, 1);
   1001   }
   1002   EXPECT_FALSE(env_->ExceptionCheck());
   1003 
   1004   env_->UnregisterNatives(jlobject);
   1005 }
   1006 
   1007 #define EXPECT_PRIMITIVE_ARRAY(new_fn, \
   1008                                get_region_fn, \
   1009                                set_region_fn, \
   1010                                get_elements_fn, \
   1011                                release_elements_fn, \
   1012                                scalar_type, \
   1013                                expected_class_descriptor) \
   1014   jsize size = 4; \
   1015   /* Allocate an array and check it has the right type and length. */ \
   1016   scalar_type ## Array a = env_->new_fn(size); \
   1017   EXPECT_TRUE(a != NULL); \
   1018   EXPECT_TRUE(env_->IsInstanceOf(a, env_->FindClass(expected_class_descriptor))); \
   1019   EXPECT_EQ(size, env_->GetArrayLength(a)); \
   1020   /* AIOOBE for negative start offset. */ \
   1021   env_->get_region_fn(a, -1, 1, NULL); \
   1022   EXPECT_EXCEPTION(aioobe_); \
   1023   env_->set_region_fn(a, -1, 1, NULL); \
   1024   EXPECT_EXCEPTION(aioobe_); \
   1025   /* AIOOBE for negative length. */ \
   1026   env_->get_region_fn(a, 0, -1, NULL); \
   1027   EXPECT_EXCEPTION(aioobe_); \
   1028   env_->set_region_fn(a, 0, -1, NULL); \
   1029   EXPECT_EXCEPTION(aioobe_); \
   1030   /* AIOOBE for buffer overrun. */ \
   1031   env_->get_region_fn(a, size - 1, size, NULL); \
   1032   EXPECT_EXCEPTION(aioobe_); \
   1033   env_->set_region_fn(a, size - 1, size, NULL); \
   1034   EXPECT_EXCEPTION(aioobe_); \
   1035   /* Prepare a couple of buffers. */ \
   1036   UniquePtr<scalar_type[]> src_buf(new scalar_type[size]); \
   1037   UniquePtr<scalar_type[]> dst_buf(new scalar_type[size]); \
   1038   for (jsize i = 0; i < size; ++i) { src_buf[i] = scalar_type(i); } \
   1039   for (jsize i = 0; i < size; ++i) { dst_buf[i] = scalar_type(-1); } \
   1040   /* Copy all of src_buf onto the heap. */ \
   1041   env_->set_region_fn(a, 0, size, &src_buf[0]); \
   1042   /* Copy back only part. */ \
   1043   env_->get_region_fn(a, 1, size - 2, &dst_buf[1]); \
   1044   EXPECT_NE(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) \
   1045     << "short copy equal"; \
   1046   /* Copy the missing pieces. */ \
   1047   env_->get_region_fn(a, 0, 1, &dst_buf[0]); \
   1048   env_->get_region_fn(a, size - 1, 1, &dst_buf[size - 1]); \
   1049   EXPECT_EQ(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) \
   1050     << "fixed copy not equal"; \
   1051   /* Copy back the whole array. */ \
   1052   env_->get_region_fn(a, 0, size, &dst_buf[0]); \
   1053   EXPECT_EQ(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) \
   1054     << "full copy not equal"; \
   1055   /* GetPrimitiveArrayCritical */ \
   1056   void* v = env_->GetPrimitiveArrayCritical(a, NULL); \
   1057   EXPECT_EQ(memcmp(&src_buf[0], v, size * sizeof(scalar_type)), 0) \
   1058     << "GetPrimitiveArrayCritical not equal"; \
   1059   env_->ReleasePrimitiveArrayCritical(a, v, 0); \
   1060   /* GetXArrayElements */ \
   1061   scalar_type* xs = env_->get_elements_fn(a, NULL); \
   1062   EXPECT_EQ(memcmp(&src_buf[0], xs, size * sizeof(scalar_type)), 0) \
   1063     << # get_elements_fn " not equal"; \
   1064   env_->release_elements_fn(a, xs, 0); \
   1065   EXPECT_EQ(reinterpret_cast<uintptr_t>(v), reinterpret_cast<uintptr_t>(xs))
   1066 
   1067 TEST_F(JniInternalTest, BooleanArrays) {
   1068   EXPECT_PRIMITIVE_ARRAY(NewBooleanArray, GetBooleanArrayRegion, SetBooleanArrayRegion,
   1069                          GetBooleanArrayElements, ReleaseBooleanArrayElements, jboolean, "[Z");
   1070 }
   1071 TEST_F(JniInternalTest, ByteArrays) {
   1072   EXPECT_PRIMITIVE_ARRAY(NewByteArray, GetByteArrayRegion, SetByteArrayRegion,
   1073                          GetByteArrayElements, ReleaseByteArrayElements, jbyte, "[B");
   1074 }
   1075 TEST_F(JniInternalTest, CharArrays) {
   1076   EXPECT_PRIMITIVE_ARRAY(NewCharArray, GetCharArrayRegion, SetCharArrayRegion,
   1077                          GetCharArrayElements, ReleaseCharArrayElements, jchar, "[C");
   1078 }
   1079 TEST_F(JniInternalTest, DoubleArrays) {
   1080   EXPECT_PRIMITIVE_ARRAY(NewDoubleArray, GetDoubleArrayRegion, SetDoubleArrayRegion,
   1081                          GetDoubleArrayElements, ReleaseDoubleArrayElements, jdouble, "[D");
   1082 }
   1083 TEST_F(JniInternalTest, FloatArrays) {
   1084   EXPECT_PRIMITIVE_ARRAY(NewFloatArray, GetFloatArrayRegion, SetFloatArrayRegion,
   1085                          GetFloatArrayElements, ReleaseFloatArrayElements, jfloat, "[F");
   1086 }
   1087 TEST_F(JniInternalTest, IntArrays) {
   1088   EXPECT_PRIMITIVE_ARRAY(NewIntArray, GetIntArrayRegion, SetIntArrayRegion,
   1089                          GetIntArrayElements, ReleaseIntArrayElements, jint, "[I");
   1090 }
   1091 TEST_F(JniInternalTest, LongArrays) {
   1092   EXPECT_PRIMITIVE_ARRAY(NewLongArray, GetLongArrayRegion, SetLongArrayRegion,
   1093                          GetLongArrayElements, ReleaseLongArrayElements, jlong, "[J");
   1094 }
   1095 TEST_F(JniInternalTest, ShortArrays) {
   1096   EXPECT_PRIMITIVE_ARRAY(NewShortArray, GetShortArrayRegion, SetShortArrayRegion,
   1097                          GetShortArrayElements, ReleaseShortArrayElements, jshort, "[S");
   1098 }
   1099 
   1100 TEST_F(JniInternalTest, NewObjectArray) {
   1101   // TODO: death tests for negative array sizes.
   1102 
   1103   // TODO: check non-NULL initial elements.
   1104 
   1105   jclass element_class = env_->FindClass("java/lang/String");
   1106   ASSERT_TRUE(element_class != NULL);
   1107   jclass array_class = env_->FindClass("[Ljava/lang/String;");
   1108   ASSERT_TRUE(array_class != NULL);
   1109 
   1110   jobjectArray a;
   1111 
   1112   a = env_->NewObjectArray(0, element_class, NULL);
   1113   EXPECT_TRUE(a != NULL);
   1114   EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
   1115   EXPECT_EQ(0, env_->GetArrayLength(a));
   1116 
   1117   a = env_->NewObjectArray(1, element_class, NULL);
   1118   EXPECT_TRUE(a != NULL);
   1119   EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
   1120   EXPECT_EQ(1, env_->GetArrayLength(a));
   1121   EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 0), NULL));
   1122 
   1123   jstring s = env_->NewStringUTF("poop");
   1124   a = env_->NewObjectArray(2, element_class, s);
   1125   EXPECT_TRUE(a != NULL);
   1126   EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
   1127   EXPECT_EQ(2, env_->GetArrayLength(a));
   1128   EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 0), s));
   1129   EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 1), s));
   1130 }
   1131 
   1132 TEST_F(JniInternalTest, GetArrayLength) {
   1133   // Already tested in NewObjectArray/NewPrimitiveArray.
   1134 }
   1135 
   1136 TEST_F(JniInternalTest, GetObjectClass) {
   1137   jclass string_class = env_->FindClass("java/lang/String");
   1138   ASSERT_TRUE(string_class != NULL);
   1139   jclass class_class = env_->FindClass("java/lang/Class");
   1140   ASSERT_TRUE(class_class != NULL);
   1141 
   1142   jstring s = env_->NewStringUTF("poop");
   1143   jclass c = env_->GetObjectClass(s);
   1144   ASSERT_TRUE(env_->IsSameObject(string_class, c));
   1145 
   1146   jclass c2 = env_->GetObjectClass(c);
   1147   ASSERT_TRUE(env_->IsSameObject(class_class, env_->GetObjectClass(c2)));
   1148 }
   1149 
   1150 TEST_F(JniInternalTest, GetSuperclass) {
   1151   jclass object_class = env_->FindClass("java/lang/Object");
   1152   ASSERT_TRUE(object_class != NULL);
   1153   jclass string_class = env_->FindClass("java/lang/String");
   1154   ASSERT_TRUE(string_class != NULL);
   1155   jclass runnable_interface = env_->FindClass("java/lang/Runnable");
   1156   ASSERT_TRUE(runnable_interface != NULL);
   1157   ASSERT_TRUE(env_->IsSameObject(object_class, env_->GetSuperclass(string_class)));
   1158   ASSERT_TRUE(env_->GetSuperclass(object_class) == NULL);
   1159   ASSERT_TRUE(env_->IsSameObject(object_class, env_->GetSuperclass(runnable_interface)));
   1160 }
   1161 
   1162 TEST_F(JniInternalTest, IsAssignableFrom) {
   1163   jclass object_class = env_->FindClass("java/lang/Object");
   1164   ASSERT_TRUE(object_class != NULL);
   1165   jclass string_class = env_->FindClass("java/lang/String");
   1166   ASSERT_TRUE(string_class != NULL);
   1167 
   1168   ASSERT_TRUE(env_->IsAssignableFrom(object_class, string_class));
   1169   ASSERT_FALSE(env_->IsAssignableFrom(string_class, object_class));
   1170 }
   1171 
   1172 TEST_F(JniInternalTest, GetObjectRefType) {
   1173   jclass local = env_->FindClass("java/lang/Object");
   1174   ASSERT_TRUE(local != NULL);
   1175   EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(local));
   1176 
   1177   jobject global = env_->NewGlobalRef(local);
   1178   EXPECT_EQ(JNIGlobalRefType, env_->GetObjectRefType(global));
   1179 
   1180   jweak weak_global = env_->NewWeakGlobalRef(local);
   1181   EXPECT_EQ(JNIWeakGlobalRefType, env_->GetObjectRefType(weak_global));
   1182 
   1183   jobject invalid = reinterpret_cast<jobject>(this);
   1184   EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(invalid));
   1185 
   1186   // TODO: invoke a native method and test that its arguments are considered local references.
   1187 }
   1188 
   1189 TEST_F(JniInternalTest, NewStringUTF) {
   1190   EXPECT_TRUE(env_->NewStringUTF(NULL) == NULL);
   1191   jstring s;
   1192 
   1193   s = env_->NewStringUTF("");
   1194   EXPECT_TRUE(s != NULL);
   1195   EXPECT_EQ(0, env_->GetStringLength(s));
   1196   EXPECT_EQ(0, env_->GetStringUTFLength(s));
   1197   s = env_->NewStringUTF("hello");
   1198   EXPECT_TRUE(s != NULL);
   1199   EXPECT_EQ(5, env_->GetStringLength(s));
   1200   EXPECT_EQ(5, env_->GetStringUTFLength(s));
   1201 
   1202   // TODO: check some non-ASCII strings.
   1203 }
   1204 
   1205 TEST_F(JniInternalTest, NewString) {
   1206   jchar chars[] = { 'h', 'i' };
   1207   jstring s;
   1208   s = env_->NewString(chars, 0);
   1209   EXPECT_TRUE(s != NULL);
   1210   EXPECT_EQ(0, env_->GetStringLength(s));
   1211   EXPECT_EQ(0, env_->GetStringUTFLength(s));
   1212   s = env_->NewString(chars, 2);
   1213   EXPECT_TRUE(s != NULL);
   1214   EXPECT_EQ(2, env_->GetStringLength(s));
   1215   EXPECT_EQ(2, env_->GetStringUTFLength(s));
   1216 
   1217   // TODO: check some non-ASCII strings.
   1218 }
   1219 
   1220 TEST_F(JniInternalTest, NewStringNullCharsZeroLength) {
   1221   jstring s = env_->NewString(NULL, 0);
   1222   EXPECT_TRUE(s != NULL);
   1223   EXPECT_EQ(0, env_->GetStringLength(s));
   1224 }
   1225 
   1226 // TODO: fix gtest death tests on host http://b/5690440 (and target)
   1227 TEST_F(JniInternalTest, DISABLED_NewStringNullCharsNonzeroLength) {
   1228   ASSERT_DEATH(env_->NewString(NULL, 1), "");
   1229 }
   1230 
   1231 TEST_F(JniInternalTest, GetStringLength_GetStringUTFLength) {
   1232   // Already tested in the NewString/NewStringUTF tests.
   1233 }
   1234 
   1235 TEST_F(JniInternalTest, GetStringRegion_GetStringUTFRegion) {
   1236   jstring s = env_->NewStringUTF("hello");
   1237   ASSERT_TRUE(s != NULL);
   1238 
   1239   env_->GetStringRegion(s, -1, 0, NULL);
   1240   EXPECT_EXCEPTION(sioobe_);
   1241   env_->GetStringRegion(s, 0, -1, NULL);
   1242   EXPECT_EXCEPTION(sioobe_);
   1243   env_->GetStringRegion(s, 0, 10, NULL);
   1244   EXPECT_EXCEPTION(sioobe_);
   1245   env_->GetStringRegion(s, 10, 1, NULL);
   1246   EXPECT_EXCEPTION(sioobe_);
   1247 
   1248   jchar chars[4] = { 'x', 'x', 'x', 'x' };
   1249   env_->GetStringRegion(s, 1, 2, &chars[1]);
   1250   EXPECT_EQ('x', chars[0]);
   1251   EXPECT_EQ('e', chars[1]);
   1252   EXPECT_EQ('l', chars[2]);
   1253   EXPECT_EQ('x', chars[3]);
   1254 
   1255   env_->GetStringUTFRegion(s, -1, 0, NULL);
   1256   EXPECT_EXCEPTION(sioobe_);
   1257   env_->GetStringUTFRegion(s, 0, -1, NULL);
   1258   EXPECT_EXCEPTION(sioobe_);
   1259   env_->GetStringUTFRegion(s, 0, 10, NULL);
   1260   EXPECT_EXCEPTION(sioobe_);
   1261   env_->GetStringUTFRegion(s, 10, 1, NULL);
   1262   EXPECT_EXCEPTION(sioobe_);
   1263 
   1264   char bytes[4] = { 'x', 'x', 'x', 'x' };
   1265   env_->GetStringUTFRegion(s, 1, 2, &bytes[1]);
   1266   EXPECT_EQ('x', bytes[0]);
   1267   EXPECT_EQ('e', bytes[1]);
   1268   EXPECT_EQ('l', bytes[2]);
   1269   EXPECT_EQ('x', bytes[3]);
   1270 }
   1271 
   1272 TEST_F(JniInternalTest, GetStringUTFChars_ReleaseStringUTFChars) {
   1273   // Passing in a NULL jstring is ignored normally, but caught by -Xcheck:jni.
   1274   {
   1275     CheckJniAbortCatcher check_jni_abort_catcher;
   1276     EXPECT_TRUE(env_->GetStringUTFChars(NULL, NULL) == NULL);
   1277     check_jni_abort_catcher.Check("GetStringUTFChars received null jstring");
   1278   }
   1279 
   1280   jstring s = env_->NewStringUTF("hello");
   1281   ASSERT_TRUE(s != NULL);
   1282 
   1283   const char* utf = env_->GetStringUTFChars(s, NULL);
   1284   EXPECT_STREQ("hello", utf);
   1285   env_->ReleaseStringUTFChars(s, utf);
   1286 
   1287   jboolean is_copy = JNI_FALSE;
   1288   utf = env_->GetStringUTFChars(s, &is_copy);
   1289   EXPECT_EQ(JNI_TRUE, is_copy);
   1290   EXPECT_STREQ("hello", utf);
   1291   env_->ReleaseStringUTFChars(s, utf);
   1292 }
   1293 
   1294 TEST_F(JniInternalTest, GetStringChars_ReleaseStringChars) {
   1295   jstring s = env_->NewStringUTF("hello");
   1296   ASSERT_TRUE(s != NULL);
   1297 
   1298   jchar expected[] = { 'h', 'e', 'l', 'l', 'o' };
   1299   const jchar* chars = env_->GetStringChars(s, NULL);
   1300   EXPECT_EQ(expected[0], chars[0]);
   1301   EXPECT_EQ(expected[1], chars[1]);
   1302   EXPECT_EQ(expected[2], chars[2]);
   1303   EXPECT_EQ(expected[3], chars[3]);
   1304   EXPECT_EQ(expected[4], chars[4]);
   1305   env_->ReleaseStringChars(s, chars);
   1306 
   1307   jboolean is_copy = JNI_FALSE;
   1308   chars = env_->GetStringChars(s, &is_copy);
   1309   EXPECT_EQ(JNI_FALSE, is_copy);
   1310   EXPECT_EQ(expected[0], chars[0]);
   1311   EXPECT_EQ(expected[1], chars[1]);
   1312   EXPECT_EQ(expected[2], chars[2]);
   1313   EXPECT_EQ(expected[3], chars[3]);
   1314   EXPECT_EQ(expected[4], chars[4]);
   1315   env_->ReleaseStringChars(s, chars);
   1316 }
   1317 
   1318 TEST_F(JniInternalTest, GetStringCritical_ReleaseStringCritical) {
   1319   jstring s = env_->NewStringUTF("hello");
   1320   ASSERT_TRUE(s != NULL);
   1321 
   1322   jchar expected[] = { 'h', 'e', 'l', 'l', 'o' };
   1323   const jchar* chars = env_->GetStringCritical(s, NULL);
   1324   EXPECT_EQ(expected[0], chars[0]);
   1325   EXPECT_EQ(expected[1], chars[1]);
   1326   EXPECT_EQ(expected[2], chars[2]);
   1327   EXPECT_EQ(expected[3], chars[3]);
   1328   EXPECT_EQ(expected[4], chars[4]);
   1329   env_->ReleaseStringCritical(s, chars);
   1330 
   1331   jboolean is_copy = JNI_FALSE;
   1332   chars = env_->GetStringCritical(s, &is_copy);
   1333   EXPECT_EQ(JNI_FALSE, is_copy);
   1334   EXPECT_EQ(expected[0], chars[0]);
   1335   EXPECT_EQ(expected[1], chars[1]);
   1336   EXPECT_EQ(expected[2], chars[2]);
   1337   EXPECT_EQ(expected[3], chars[3]);
   1338   EXPECT_EQ(expected[4], chars[4]);
   1339   env_->ReleaseStringCritical(s, chars);
   1340 }
   1341 
   1342 TEST_F(JniInternalTest, GetObjectArrayElement_SetObjectArrayElement) {
   1343   jclass java_lang_Class = env_->FindClass("java/lang/Class");
   1344   ASSERT_TRUE(java_lang_Class != NULL);
   1345 
   1346   jobjectArray array = env_->NewObjectArray(1, java_lang_Class, NULL);
   1347   EXPECT_TRUE(array != NULL);
   1348   EXPECT_TRUE(env_->GetObjectArrayElement(array, 0) == NULL);
   1349   env_->SetObjectArrayElement(array, 0, java_lang_Class);
   1350   EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(array, 0), java_lang_Class));
   1351 
   1352   // ArrayIndexOutOfBounds for negative index.
   1353   env_->SetObjectArrayElement(array, -1, java_lang_Class);
   1354   EXPECT_EXCEPTION(aioobe_);
   1355 
   1356   // ArrayIndexOutOfBounds for too-large index.
   1357   env_->SetObjectArrayElement(array, 1, java_lang_Class);
   1358   EXPECT_EXCEPTION(aioobe_);
   1359 
   1360   // ArrayStoreException thrown for bad types.
   1361   env_->SetObjectArrayElement(array, 0, env_->NewStringUTF("not a jclass!"));
   1362   EXPECT_EXCEPTION(ase_);
   1363 }
   1364 
   1365 #define EXPECT_STATIC_PRIMITIVE_FIELD(type, field_name, sig, value1, value2) \
   1366   do { \
   1367     jfieldID fid = env_->GetStaticFieldID(c, field_name, sig); \
   1368     EXPECT_TRUE(fid != NULL); \
   1369     env_->SetStatic ## type ## Field(c, fid, value1); \
   1370     EXPECT_TRUE(value1 == env_->GetStatic ## type ## Field(c, fid)); \
   1371     env_->SetStatic ## type ## Field(c, fid, value2); \
   1372     EXPECT_TRUE(value2 == env_->GetStatic ## type ## Field(c, fid)); \
   1373   } while (false)
   1374 
   1375 #define EXPECT_PRIMITIVE_FIELD(instance, type, field_name, sig, value1, value2) \
   1376   do { \
   1377     jfieldID fid = env_->GetFieldID(c, field_name, sig); \
   1378     EXPECT_TRUE(fid != NULL); \
   1379     env_->Set ## type ## Field(instance, fid, value1); \
   1380     EXPECT_TRUE(value1 == env_->Get ## type ## Field(instance, fid)); \
   1381     env_->Set ## type ## Field(instance, fid, value2); \
   1382     EXPECT_TRUE(value2 == env_->Get ## type ## Field(instance, fid)); \
   1383   } while (false)
   1384 
   1385 
   1386 #if !defined(ART_USE_PORTABLE_COMPILER)
   1387 TEST_F(JniInternalTest, GetPrimitiveField_SetPrimitiveField) {
   1388   Thread::Current()->TransitionFromSuspendedToRunnable();
   1389   LoadDex("AllFields");
   1390   bool started = runtime_->Start();
   1391   CHECK(started);
   1392 
   1393   jclass c = env_->FindClass("AllFields");
   1394   ASSERT_TRUE(c != NULL);
   1395   jobject o = env_->AllocObject(c);
   1396   ASSERT_TRUE(o != NULL);
   1397 
   1398   EXPECT_STATIC_PRIMITIVE_FIELD(Boolean, "sZ", "Z", true, false);
   1399   EXPECT_STATIC_PRIMITIVE_FIELD(Byte, "sB", "B", 1, 2);
   1400   EXPECT_STATIC_PRIMITIVE_FIELD(Char, "sC", "C", 'a', 'b');
   1401   EXPECT_STATIC_PRIMITIVE_FIELD(Double, "sD", "D", 1.0, 2.0);
   1402   EXPECT_STATIC_PRIMITIVE_FIELD(Float, "sF", "F", 1.0, 2.0);
   1403   EXPECT_STATIC_PRIMITIVE_FIELD(Int, "sI", "I", 1, 2);
   1404   EXPECT_STATIC_PRIMITIVE_FIELD(Long, "sJ", "J", 1, 2);
   1405   EXPECT_STATIC_PRIMITIVE_FIELD(Short, "sS", "S", 1, 2);
   1406 
   1407   EXPECT_PRIMITIVE_FIELD(o, Boolean, "iZ", "Z", true, false);
   1408   EXPECT_PRIMITIVE_FIELD(o, Byte, "iB", "B", 1, 2);
   1409   EXPECT_PRIMITIVE_FIELD(o, Char, "iC", "C", 'a', 'b');
   1410   EXPECT_PRIMITIVE_FIELD(o, Double, "iD", "D", 1.0, 2.0);
   1411   EXPECT_PRIMITIVE_FIELD(o, Float, "iF", "F", 1.0, 2.0);
   1412   EXPECT_PRIMITIVE_FIELD(o, Int, "iI", "I", 1, 2);
   1413   EXPECT_PRIMITIVE_FIELD(o, Long, "iJ", "J", 1, 2);
   1414   EXPECT_PRIMITIVE_FIELD(o, Short, "iS", "S", 1, 2);
   1415 }
   1416 
   1417 TEST_F(JniInternalTest, GetObjectField_SetObjectField) {
   1418   Thread::Current()->TransitionFromSuspendedToRunnable();
   1419   LoadDex("AllFields");
   1420   runtime_->Start();
   1421 
   1422   jclass c = env_->FindClass("AllFields");
   1423   ASSERT_TRUE(c != NULL);
   1424   jobject o = env_->AllocObject(c);
   1425   ASSERT_TRUE(o != NULL);
   1426 
   1427   jstring s1 = env_->NewStringUTF("hello");
   1428   ASSERT_TRUE(s1 != NULL);
   1429   jstring s2 = env_->NewStringUTF("world");
   1430   ASSERT_TRUE(s2 != NULL);
   1431 
   1432   jfieldID s_fid = env_->GetStaticFieldID(c, "sObject", "Ljava/lang/Object;");
   1433   ASSERT_TRUE(s_fid != NULL);
   1434   jfieldID i_fid = env_->GetFieldID(c, "iObject", "Ljava/lang/Object;");
   1435   ASSERT_TRUE(i_fid != NULL);
   1436 
   1437   env_->SetStaticObjectField(c, s_fid, s1);
   1438   ASSERT_TRUE(env_->IsSameObject(s1, env_->GetStaticObjectField(c, s_fid)));
   1439   env_->SetStaticObjectField(c, s_fid, s2);
   1440   ASSERT_TRUE(env_->IsSameObject(s2, env_->GetStaticObjectField(c, s_fid)));
   1441 
   1442   env_->SetObjectField(o, i_fid, s1);
   1443   ASSERT_TRUE(env_->IsSameObject(s1, env_->GetObjectField(o, i_fid)));
   1444   env_->SetObjectField(o, i_fid, s2);
   1445   ASSERT_TRUE(env_->IsSameObject(s2, env_->GetObjectField(o, i_fid)));
   1446 }
   1447 #endif
   1448 
   1449 TEST_F(JniInternalTest, NewLocalRef_NULL) {
   1450   EXPECT_TRUE(env_->NewLocalRef(NULL) == NULL);
   1451 }
   1452 
   1453 TEST_F(JniInternalTest, NewLocalRef) {
   1454   jstring s = env_->NewStringUTF("");
   1455   ASSERT_TRUE(s != NULL);
   1456   jobject o = env_->NewLocalRef(s);
   1457   EXPECT_TRUE(o != NULL);
   1458   EXPECT_TRUE(o != s);
   1459 
   1460   EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(o));
   1461 }
   1462 
   1463 TEST_F(JniInternalTest, DeleteLocalRef_NULL) {
   1464   env_->DeleteLocalRef(NULL);
   1465 }
   1466 
   1467 TEST_F(JniInternalTest, DeleteLocalRef) {
   1468   jstring s = env_->NewStringUTF("");
   1469   ASSERT_TRUE(s != NULL);
   1470   env_->DeleteLocalRef(s);
   1471 
   1472   // Currently, deleting an already-deleted reference is just a CheckJNI warning.
   1473   {
   1474     CheckJniAbortCatcher check_jni_abort_catcher;
   1475     env_->DeleteLocalRef(s);
   1476 
   1477     std::string expected(StringPrintf("native code passing in reference to "
   1478                                       "invalid local reference: %p", s));
   1479     check_jni_abort_catcher.Check(expected.c_str());
   1480   }
   1481 
   1482   s = env_->NewStringUTF("");
   1483   ASSERT_TRUE(s != NULL);
   1484   jobject o = env_->NewLocalRef(s);
   1485   ASSERT_TRUE(o != NULL);
   1486 
   1487   env_->DeleteLocalRef(s);
   1488   env_->DeleteLocalRef(o);
   1489 }
   1490 
   1491 TEST_F(JniInternalTest, PushLocalFrame_10395422) {
   1492   // The JNI specification is ambiguous about whether the given capacity is to be interpreted as a
   1493   // maximum or as a minimum, but it seems like it's supposed to be a minimum, and that's how
   1494   // Android historically treated it, and it's how the RI treats it. It's also the more useful
   1495   // interpretation!
   1496   ASSERT_EQ(JNI_OK, env_->PushLocalFrame(0));
   1497   env_->PopLocalFrame(NULL);
   1498 
   1499   // Negative capacities are not allowed.
   1500   ASSERT_EQ(JNI_ERR, env_->PushLocalFrame(-1));
   1501 
   1502   // And it's okay to have an upper limit. Ours is currently 512.
   1503   ASSERT_EQ(JNI_ERR, env_->PushLocalFrame(8192));
   1504 }
   1505 
   1506 TEST_F(JniInternalTest, PushLocalFrame_PopLocalFrame) {
   1507   jobject original = env_->NewStringUTF("");
   1508   ASSERT_TRUE(original != NULL);
   1509 
   1510   jobject outer;
   1511   jobject inner1, inner2;
   1512   ScopedObjectAccess soa(env_);
   1513   mirror::Object* inner2_direct_pointer;
   1514   {
   1515     ASSERT_EQ(JNI_OK, env_->PushLocalFrame(4));
   1516     outer = env_->NewLocalRef(original);
   1517 
   1518     {
   1519       ASSERT_EQ(JNI_OK, env_->PushLocalFrame(4));
   1520       inner1 = env_->NewLocalRef(outer);
   1521       inner2 = env_->NewStringUTF("survivor");
   1522       inner2_direct_pointer = soa.Decode<mirror::Object*>(inner2);
   1523       env_->PopLocalFrame(inner2);
   1524     }
   1525 
   1526     EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(original));
   1527     EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(outer));
   1528     EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner1));
   1529 
   1530     // Our local reference for the survivor is invalid because the survivor
   1531     // gets a new local reference...
   1532     EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner2));
   1533     // ...but the survivor should be in the local reference table.
   1534     JNIEnvExt* env = reinterpret_cast<JNIEnvExt*>(env_);
   1535     EXPECT_TRUE(env->locals.ContainsDirectPointer(inner2_direct_pointer));
   1536 
   1537     env_->PopLocalFrame(NULL);
   1538   }
   1539   EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(original));
   1540   EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(outer));
   1541   EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner1));
   1542   EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner2));
   1543 }
   1544 
   1545 TEST_F(JniInternalTest, NewGlobalRef_NULL) {
   1546   EXPECT_TRUE(env_->NewGlobalRef(NULL) == NULL);
   1547 }
   1548 
   1549 TEST_F(JniInternalTest, NewGlobalRef) {
   1550   jstring s = env_->NewStringUTF("");
   1551   ASSERT_TRUE(s != NULL);
   1552   jobject o = env_->NewGlobalRef(s);
   1553   EXPECT_TRUE(o != NULL);
   1554   EXPECT_TRUE(o != s);
   1555 
   1556   // TODO: check that o is a global reference.
   1557 }
   1558 
   1559 TEST_F(JniInternalTest, DeleteGlobalRef_NULL) {
   1560   env_->DeleteGlobalRef(NULL);
   1561 }
   1562 
   1563 TEST_F(JniInternalTest, DeleteGlobalRef) {
   1564   jstring s = env_->NewStringUTF("");
   1565   ASSERT_TRUE(s != NULL);
   1566 
   1567   jobject o = env_->NewGlobalRef(s);
   1568   ASSERT_TRUE(o != NULL);
   1569   env_->DeleteGlobalRef(o);
   1570 
   1571   // Currently, deleting an already-deleted reference is just a CheckJNI warning.
   1572   {
   1573     CheckJniAbortCatcher check_jni_abort_catcher;
   1574     env_->DeleteGlobalRef(o);
   1575 
   1576     std::string expected(StringPrintf("native code passing in reference to "
   1577                                       "invalid global reference: %p", o));
   1578     check_jni_abort_catcher.Check(expected.c_str());
   1579   }
   1580 
   1581   jobject o1 = env_->NewGlobalRef(s);
   1582   ASSERT_TRUE(o1 != NULL);
   1583   jobject o2 = env_->NewGlobalRef(s);
   1584   ASSERT_TRUE(o2 != NULL);
   1585 
   1586   env_->DeleteGlobalRef(o1);
   1587   env_->DeleteGlobalRef(o2);
   1588 }
   1589 
   1590 TEST_F(JniInternalTest, NewWeakGlobalRef_NULL) {
   1591   EXPECT_TRUE(env_->NewWeakGlobalRef(NULL) == NULL);
   1592 }
   1593 
   1594 TEST_F(JniInternalTest, NewWeakGlobalRef) {
   1595   jstring s = env_->NewStringUTF("");
   1596   ASSERT_TRUE(s != NULL);
   1597   jobject o = env_->NewWeakGlobalRef(s);
   1598   EXPECT_TRUE(o != NULL);
   1599   EXPECT_TRUE(o != s);
   1600 
   1601   // TODO: check that o is a weak global reference.
   1602 }
   1603 
   1604 TEST_F(JniInternalTest, DeleteWeakGlobalRef_NULL) {
   1605   env_->DeleteWeakGlobalRef(NULL);
   1606 }
   1607 
   1608 TEST_F(JniInternalTest, DeleteWeakGlobalRef) {
   1609   jstring s = env_->NewStringUTF("");
   1610   ASSERT_TRUE(s != NULL);
   1611 
   1612   jobject o = env_->NewWeakGlobalRef(s);
   1613   ASSERT_TRUE(o != NULL);
   1614   env_->DeleteWeakGlobalRef(o);
   1615 
   1616   // Currently, deleting an already-deleted reference is just a CheckJNI warning.
   1617   {
   1618     CheckJniAbortCatcher check_jni_abort_catcher;
   1619     env_->DeleteWeakGlobalRef(o);
   1620 
   1621     std::string expected(StringPrintf("native code passing in reference to "
   1622                                       "invalid weak global reference: %p", o));
   1623     check_jni_abort_catcher.Check(expected.c_str());
   1624   }
   1625 
   1626   jobject o1 = env_->NewWeakGlobalRef(s);
   1627   ASSERT_TRUE(o1 != NULL);
   1628   jobject o2 = env_->NewWeakGlobalRef(s);
   1629   ASSERT_TRUE(o2 != NULL);
   1630 
   1631   env_->DeleteWeakGlobalRef(o1);
   1632   env_->DeleteWeakGlobalRef(o2);
   1633 }
   1634 
   1635 TEST_F(JniInternalTest, StaticMainMethod) {
   1636   TEST_DISABLED_FOR_PORTABLE();
   1637   ScopedObjectAccess soa(Thread::Current());
   1638   jobject jclass_loader = LoadDex("Main");
   1639   SirtRef<mirror::ClassLoader>
   1640       class_loader(soa.Self(), soa.Decode<mirror::ClassLoader*>(jclass_loader));
   1641   CompileDirectMethod(class_loader.get(), "Main", "main", "([Ljava/lang/String;)V");
   1642 
   1643   mirror::Class* klass = class_linker_->FindClass("LMain;", class_loader.get());
   1644   ASSERT_TRUE(klass != NULL);
   1645 
   1646   mirror::ArtMethod* method = klass->FindDirectMethod("main", "([Ljava/lang/String;)V");
   1647   ASSERT_TRUE(method != NULL);
   1648 
   1649   ArgArray arg_array(NULL, 0);
   1650   arg_array.Append(0);
   1651   JValue result;
   1652 
   1653   // Start runtime.
   1654   bool started = runtime_->Start();
   1655   CHECK(started);
   1656   Thread::Current()->TransitionFromSuspendedToRunnable();
   1657 
   1658   method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'V');
   1659 }
   1660 
   1661 TEST_F(JniInternalTest, StaticNopMethod) {
   1662   TEST_DISABLED_FOR_PORTABLE();
   1663   ScopedObjectAccess soa(Thread::Current());
   1664   InvokeNopMethod(true);
   1665 }
   1666 
   1667 TEST_F(JniInternalTest, NonStaticNopMethod) {
   1668   TEST_DISABLED_FOR_PORTABLE();
   1669   ScopedObjectAccess soa(Thread::Current());
   1670   InvokeNopMethod(false);
   1671 }
   1672 
   1673 TEST_F(JniInternalTest, StaticIdentityByteMethod) {
   1674   TEST_DISABLED_FOR_PORTABLE();
   1675   ScopedObjectAccess soa(Thread::Current());
   1676   InvokeIdentityByteMethod(true);
   1677 }
   1678 
   1679 TEST_F(JniInternalTest, NonStaticIdentityByteMethod) {
   1680   TEST_DISABLED_FOR_PORTABLE();
   1681   ScopedObjectAccess soa(Thread::Current());
   1682   InvokeIdentityByteMethod(false);
   1683 }
   1684 
   1685 TEST_F(JniInternalTest, StaticIdentityIntMethod) {
   1686   TEST_DISABLED_FOR_PORTABLE();
   1687   ScopedObjectAccess soa(Thread::Current());
   1688   InvokeIdentityIntMethod(true);
   1689 }
   1690 
   1691 TEST_F(JniInternalTest, NonStaticIdentityIntMethod) {
   1692   TEST_DISABLED_FOR_PORTABLE();
   1693   ScopedObjectAccess soa(Thread::Current());
   1694   InvokeIdentityIntMethod(false);
   1695 }
   1696 
   1697 TEST_F(JniInternalTest, StaticIdentityDoubleMethod) {
   1698   TEST_DISABLED_FOR_PORTABLE();
   1699   ScopedObjectAccess soa(Thread::Current());
   1700   InvokeIdentityDoubleMethod(true);
   1701 }
   1702 
   1703 TEST_F(JniInternalTest, NonStaticIdentityDoubleMethod) {
   1704   TEST_DISABLED_FOR_PORTABLE();
   1705   ScopedObjectAccess soa(Thread::Current());
   1706   InvokeIdentityDoubleMethod(false);
   1707 }
   1708 
   1709 TEST_F(JniInternalTest, StaticSumIntIntMethod) {
   1710   TEST_DISABLED_FOR_PORTABLE();
   1711   ScopedObjectAccess soa(Thread::Current());
   1712   InvokeSumIntIntMethod(true);
   1713 }
   1714 
   1715 TEST_F(JniInternalTest, NonStaticSumIntIntMethod) {
   1716   TEST_DISABLED_FOR_PORTABLE();
   1717   ScopedObjectAccess soa(Thread::Current());
   1718   InvokeSumIntIntMethod(false);
   1719 }
   1720 
   1721 TEST_F(JniInternalTest, StaticSumIntIntIntMethod) {
   1722   TEST_DISABLED_FOR_PORTABLE();
   1723   ScopedObjectAccess soa(Thread::Current());
   1724   InvokeSumIntIntIntMethod(true);
   1725 }
   1726 
   1727 TEST_F(JniInternalTest, NonStaticSumIntIntIntMethod) {
   1728   TEST_DISABLED_FOR_PORTABLE();
   1729   ScopedObjectAccess soa(Thread::Current());
   1730   InvokeSumIntIntIntMethod(false);
   1731 }
   1732 
   1733 TEST_F(JniInternalTest, StaticSumIntIntIntIntMethod) {
   1734   TEST_DISABLED_FOR_PORTABLE();
   1735   ScopedObjectAccess soa(Thread::Current());
   1736   InvokeSumIntIntIntIntMethod(true);
   1737 }
   1738 
   1739 TEST_F(JniInternalTest, NonStaticSumIntIntIntIntMethod) {
   1740   TEST_DISABLED_FOR_PORTABLE();
   1741   ScopedObjectAccess soa(Thread::Current());
   1742   InvokeSumIntIntIntIntMethod(false);
   1743 }
   1744 
   1745 TEST_F(JniInternalTest, StaticSumIntIntIntIntIntMethod) {
   1746   TEST_DISABLED_FOR_PORTABLE();
   1747   ScopedObjectAccess soa(Thread::Current());
   1748   InvokeSumIntIntIntIntIntMethod(true);
   1749 }
   1750 
   1751 TEST_F(JniInternalTest, NonStaticSumIntIntIntIntIntMethod) {
   1752   TEST_DISABLED_FOR_PORTABLE();
   1753   ScopedObjectAccess soa(Thread::Current());
   1754   InvokeSumIntIntIntIntIntMethod(false);
   1755 }
   1756 
   1757 TEST_F(JniInternalTest, StaticSumDoubleDoubleMethod) {
   1758   TEST_DISABLED_FOR_PORTABLE();
   1759   ScopedObjectAccess soa(Thread::Current());
   1760   InvokeSumDoubleDoubleMethod(true);
   1761 }
   1762 
   1763 TEST_F(JniInternalTest, NonStaticSumDoubleDoubleMethod) {
   1764   TEST_DISABLED_FOR_PORTABLE();
   1765   ScopedObjectAccess soa(Thread::Current());
   1766   InvokeSumDoubleDoubleMethod(false);
   1767 }
   1768 
   1769 TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleMethod) {
   1770   TEST_DISABLED_FOR_PORTABLE();
   1771   ScopedObjectAccess soa(Thread::Current());
   1772   InvokeSumDoubleDoubleDoubleMethod(true);
   1773 }
   1774 
   1775 TEST_F(JniInternalTest, NonStaticSumDoubleDoubleDoubleMethod) {
   1776   TEST_DISABLED_FOR_PORTABLE();
   1777   ScopedObjectAccess soa(Thread::Current());
   1778   InvokeSumDoubleDoubleDoubleMethod(false);
   1779 }
   1780 
   1781 TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleDoubleMethod) {
   1782   TEST_DISABLED_FOR_PORTABLE();
   1783   ScopedObjectAccess soa(Thread::Current());
   1784   InvokeSumDoubleDoubleDoubleDoubleMethod(true);
   1785 }
   1786 
   1787 TEST_F(JniInternalTest, NonStaticSumDoubleDoubleDoubleDoubleMethod) {
   1788   TEST_DISABLED_FOR_PORTABLE();
   1789   ScopedObjectAccess soa(Thread::Current());
   1790   InvokeSumDoubleDoubleDoubleDoubleMethod(false);
   1791 }
   1792 
   1793 TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleDoubleDoubleMethod) {
   1794   TEST_DISABLED_FOR_PORTABLE();
   1795   ScopedObjectAccess soa(Thread::Current());
   1796   InvokeSumDoubleDoubleDoubleDoubleDoubleMethod(true);
   1797 }
   1798 
   1799 TEST_F(JniInternalTest, NonStaticSumDoubleDoubleDoubleDoubleDoubleMethod) {
   1800   TEST_DISABLED_FOR_PORTABLE();
   1801   ScopedObjectAccess soa(Thread::Current());
   1802   InvokeSumDoubleDoubleDoubleDoubleDoubleMethod(false);
   1803 }
   1804 
   1805 TEST_F(JniInternalTest, Throw) {
   1806   EXPECT_EQ(JNI_ERR, env_->Throw(NULL));
   1807 
   1808   jclass exception_class = env_->FindClass("java/lang/RuntimeException");
   1809   ASSERT_TRUE(exception_class != NULL);
   1810   jthrowable exception = reinterpret_cast<jthrowable>(env_->AllocObject(exception_class));
   1811   ASSERT_TRUE(exception != NULL);
   1812 
   1813   EXPECT_EQ(JNI_OK, env_->Throw(exception));
   1814   EXPECT_TRUE(env_->ExceptionCheck());
   1815   jthrowable thrown_exception = env_->ExceptionOccurred();
   1816   env_->ExceptionClear();
   1817   EXPECT_TRUE(env_->IsSameObject(exception, thrown_exception));
   1818 }
   1819 
   1820 TEST_F(JniInternalTest, ThrowNew) {
   1821   EXPECT_EQ(JNI_ERR, env_->Throw(NULL));
   1822 
   1823   jclass exception_class = env_->FindClass("java/lang/RuntimeException");
   1824   ASSERT_TRUE(exception_class != NULL);
   1825 
   1826   jthrowable thrown_exception;
   1827 
   1828   EXPECT_EQ(JNI_OK, env_->ThrowNew(exception_class, "hello world"));
   1829   EXPECT_TRUE(env_->ExceptionCheck());
   1830   thrown_exception = env_->ExceptionOccurred();
   1831   env_->ExceptionClear();
   1832   EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, exception_class));
   1833 
   1834   EXPECT_EQ(JNI_OK, env_->ThrowNew(exception_class, NULL));
   1835   EXPECT_TRUE(env_->ExceptionCheck());
   1836   thrown_exception = env_->ExceptionOccurred();
   1837   env_->ExceptionClear();
   1838   EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, exception_class));
   1839 }
   1840 
   1841 // TODO: this test is DISABLED until we can actually run java.nio.Buffer's <init>.
   1842 TEST_F(JniInternalTest, DISABLED_NewDirectBuffer_GetDirectBufferAddress_GetDirectBufferCapacity) {
   1843   jclass buffer_class = env_->FindClass("java/nio/Buffer");
   1844   ASSERT_TRUE(buffer_class != NULL);
   1845 
   1846   char bytes[1024];
   1847   jobject buffer = env_->NewDirectByteBuffer(bytes, sizeof(bytes));
   1848   ASSERT_TRUE(buffer != NULL);
   1849   ASSERT_TRUE(env_->IsInstanceOf(buffer, buffer_class));
   1850   ASSERT_TRUE(env_->GetDirectBufferAddress(buffer) == bytes);
   1851   ASSERT_TRUE(env_->GetDirectBufferCapacity(buffer) == sizeof(bytes));
   1852 }
   1853 
   1854 TEST_F(JniInternalTest, MonitorEnterExit) {
   1855   // Create an object to torture
   1856   jclass object_class = env_->FindClass("java/lang/Object");
   1857   ASSERT_TRUE(object_class != NULL);
   1858   jobject object = env_->AllocObject(object_class);
   1859   ASSERT_TRUE(object != NULL);
   1860 
   1861   // Expected class of exceptions
   1862   jclass imse_class = env_->FindClass("java/lang/IllegalMonitorStateException");
   1863   ASSERT_TRUE(imse_class != NULL);
   1864 
   1865   jthrowable thrown_exception;
   1866 
   1867   // Unlock of unowned monitor
   1868   env_->MonitorExit(object);
   1869   EXPECT_TRUE(env_->ExceptionCheck());
   1870   thrown_exception = env_->ExceptionOccurred();
   1871   env_->ExceptionClear();
   1872   EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, imse_class));
   1873 
   1874   // Lock of unowned monitor
   1875   env_->MonitorEnter(object);
   1876   EXPECT_FALSE(env_->ExceptionCheck());
   1877   // Regular unlock
   1878   env_->MonitorExit(object);
   1879   EXPECT_FALSE(env_->ExceptionCheck());
   1880 
   1881   // Recursively lock a lot
   1882   size_t max_recursive_lock = 1024;
   1883   for (size_t i = 0; i < max_recursive_lock; i++) {
   1884     env_->MonitorEnter(object);
   1885     EXPECT_FALSE(env_->ExceptionCheck());
   1886   }
   1887   // Recursively unlock a lot
   1888   for (size_t i = 0; i < max_recursive_lock; i++) {
   1889     env_->MonitorExit(object);
   1890     EXPECT_FALSE(env_->ExceptionCheck());
   1891   }
   1892 
   1893   // Unlock of unowned monitor
   1894   env_->MonitorExit(object);
   1895   EXPECT_TRUE(env_->ExceptionCheck());
   1896   thrown_exception = env_->ExceptionOccurred();
   1897   env_->ExceptionClear();
   1898   EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, imse_class));
   1899 
   1900   // It's an error to call MonitorEnter or MonitorExit on NULL.
   1901   {
   1902     CheckJniAbortCatcher check_jni_abort_catcher;
   1903     env_->MonitorEnter(NULL);
   1904     check_jni_abort_catcher.Check("in call to MonitorEnter");
   1905 
   1906     env_->MonitorExit(NULL);
   1907     check_jni_abort_catcher.Check("in call to MonitorExit");
   1908   }
   1909 }
   1910 
   1911 TEST_F(JniInternalTest, DetachCurrentThread) {
   1912   CleanUpJniEnv();  // cleanup now so TearDown won't have junk from wrong JNIEnv
   1913   jint ok = vm_->DetachCurrentThread();
   1914   EXPECT_EQ(JNI_OK, ok);
   1915 
   1916   jint err = vm_->DetachCurrentThread();
   1917   EXPECT_EQ(JNI_ERR, err);
   1918   vm_->AttachCurrentThread(&env_, NULL);  // need attached thread for CommonTest::TearDown
   1919 }
   1920 
   1921 }  // namespace art
   1922