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 "reflection.h"
     18 
     19 #include <float.h>
     20 #include <limits.h>
     21 #include "ScopedLocalRef.h"
     22 
     23 #include "art_method-inl.h"
     24 #include "base/enums.h"
     25 #include "common_compiler_test.h"
     26 #include "java_vm_ext.h"
     27 #include "jni_internal.h"
     28 #include "scoped_thread_state_change-inl.h"
     29 
     30 namespace art {
     31 
     32 // TODO: Convert to CommonRuntimeTest. Currently MakeExecutable is used.
     33 class ReflectionTest : public CommonCompilerTest {
     34  protected:
     35   virtual void SetUp() {
     36     CommonCompilerTest::SetUp();
     37 
     38     vm_ = Runtime::Current()->GetJavaVM();
     39 
     40     // Turn on -verbose:jni for the JNI tests.
     41     // gLogVerbosity.jni = true;
     42 
     43     vm_->AttachCurrentThread(&env_, nullptr);
     44 
     45     ScopedLocalRef<jclass> aioobe(env_,
     46                                   env_->FindClass("java/lang/ArrayIndexOutOfBoundsException"));
     47     CHECK(aioobe.get() != nullptr);
     48     aioobe_ = reinterpret_cast<jclass>(env_->NewGlobalRef(aioobe.get()));
     49 
     50     ScopedLocalRef<jclass> ase(env_, env_->FindClass("java/lang/ArrayStoreException"));
     51     CHECK(ase.get() != nullptr);
     52     ase_ = reinterpret_cast<jclass>(env_->NewGlobalRef(ase.get()));
     53 
     54     ScopedLocalRef<jclass> sioobe(env_,
     55                                   env_->FindClass("java/lang/StringIndexOutOfBoundsException"));
     56     CHECK(sioobe.get() != nullptr);
     57     sioobe_ = reinterpret_cast<jclass>(env_->NewGlobalRef(sioobe.get()));
     58   }
     59 
     60   void CleanUpJniEnv() {
     61     if (aioobe_ != nullptr) {
     62       env_->DeleteGlobalRef(aioobe_);
     63       aioobe_ = nullptr;
     64     }
     65     if (ase_ != nullptr) {
     66       env_->DeleteGlobalRef(ase_);
     67       ase_ = nullptr;
     68     }
     69     if (sioobe_ != nullptr) {
     70       env_->DeleteGlobalRef(sioobe_);
     71       sioobe_ = nullptr;
     72     }
     73   }
     74 
     75   virtual void TearDown() {
     76     CleanUpJniEnv();
     77     CommonCompilerTest::TearDown();
     78   }
     79 
     80   jclass GetPrimitiveClass(char descriptor) {
     81     ScopedObjectAccess soa(env_);
     82     mirror::Class* c = class_linker_->FindPrimitiveClass(descriptor);
     83     CHECK(c != nullptr);
     84     return soa.AddLocalReference<jclass>(c);
     85   }
     86 
     87   void ReflectionTestMakeExecutable(ArtMethod** method,
     88                                     ObjPtr<mirror::Object>* receiver,
     89                                     bool is_static,
     90                                     const char* method_name,
     91                                     const char* method_signature)
     92       REQUIRES_SHARED(Locks::mutator_lock_) {
     93     const char* class_name = is_static ? "StaticLeafMethods" : "NonStaticLeafMethods";
     94     jobject jclass_loader(LoadDex(class_name));
     95     Thread* self = Thread::Current();
     96     StackHandleScope<3> hs(self);
     97     Handle<mirror::ClassLoader> class_loader(
     98         hs.NewHandle(
     99             ScopedObjectAccessUnchecked(self).Decode<mirror::ClassLoader>(jclass_loader)));
    100     if (!is_static) {
    101       MakeExecutable(nullptr, "java.lang.Class");
    102       MakeExecutable(nullptr, "java.lang.Object");
    103     }
    104     MakeExecutable(class_loader.Get(), class_name);
    105 
    106     ObjPtr<mirror::Class> c = class_linker_->FindClass(self,
    107                                                        DotToDescriptor(class_name).c_str(),
    108                                                        class_loader);
    109     CHECK(c != nullptr);
    110 
    111     *method = is_static ? c->FindDirectMethod(method_name, method_signature, kRuntimePointerSize)
    112                         : c->FindVirtualMethod(method_name, method_signature, kRuntimePointerSize);
    113     CHECK(method != nullptr);
    114 
    115     if (is_static) {
    116       *receiver = nullptr;
    117     } else {
    118       // Ensure class is initialized before allocating object
    119       {
    120         StackHandleScope<1> hs2(self);
    121         HandleWrapperObjPtr<mirror::Class> h_class(hs2.NewHandleWrapper(&c));
    122         bool initialized = class_linker_->EnsureInitialized(self, h_class, true, true);
    123         CHECK(initialized);
    124       }
    125       *receiver = c->AllocObject(self);
    126     }
    127 
    128     // Start runtime.
    129     HandleWrapperObjPtr<mirror::Object> h(hs.NewHandleWrapper(receiver));
    130     bool started = runtime_->Start();
    131     CHECK(started);
    132     self->TransitionFromSuspendedToRunnable();
    133   }
    134 
    135   void InvokeNopMethod(bool is_static) {
    136     ScopedObjectAccess soa(env_);
    137     ArtMethod* method;
    138     ObjPtr<mirror::Object> receiver;
    139     ReflectionTestMakeExecutable(&method, &receiver, is_static, "nop", "()V");
    140     ScopedLocalRef<jobject> receiver_ref(soa.Env(), soa.AddLocalReference<jobject>(receiver));
    141     InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), nullptr);
    142   }
    143 
    144   void InvokeIdentityByteMethod(bool is_static) {
    145     ScopedObjectAccess soa(env_);
    146     ArtMethod* method;
    147     ObjPtr<mirror::Object> receiver;
    148     ReflectionTestMakeExecutable(&method, &receiver, is_static, "identity", "(B)B");
    149     ScopedLocalRef<jobject> receiver_ref(soa.Env(), soa.AddLocalReference<jobject>(receiver));
    150     jvalue args[1];
    151 
    152     args[0].b = 0;
    153     JValue result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
    154     EXPECT_EQ(0, result.GetB());
    155 
    156     args[0].b = -1;
    157     result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
    158     EXPECT_EQ(-1, result.GetB());
    159 
    160     args[0].b = SCHAR_MAX;
    161     result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
    162     EXPECT_EQ(SCHAR_MAX, result.GetB());
    163 
    164     static_assert(SCHAR_MIN == -128, "SCHAR_MIN unexpected");
    165     args[0].b = SCHAR_MIN;
    166     result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
    167     EXPECT_EQ(SCHAR_MIN, result.GetB());
    168   }
    169 
    170   void InvokeIdentityIntMethod(bool is_static) {
    171     ScopedObjectAccess soa(env_);
    172     ArtMethod* method;
    173     ObjPtr<mirror::Object> receiver;
    174     ReflectionTestMakeExecutable(&method, &receiver, is_static, "identity", "(I)I");
    175     ScopedLocalRef<jobject> receiver_ref(soa.Env(), soa.AddLocalReference<jobject>(receiver));
    176     jvalue args[1];
    177 
    178     args[0].i = 0;
    179     JValue result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
    180     EXPECT_EQ(0, result.GetI());
    181 
    182     args[0].i = -1;
    183     result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
    184     EXPECT_EQ(-1, result.GetI());
    185 
    186     args[0].i = INT_MAX;
    187     result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
    188     EXPECT_EQ(INT_MAX, result.GetI());
    189 
    190     args[0].i = INT_MIN;
    191     result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
    192     EXPECT_EQ(INT_MIN, result.GetI());
    193   }
    194 
    195   void InvokeIdentityDoubleMethod(bool is_static) {
    196     ScopedObjectAccess soa(env_);
    197     ArtMethod* method;
    198     ObjPtr<mirror::Object> receiver;
    199     ReflectionTestMakeExecutable(&method, &receiver, is_static, "identity", "(D)D");
    200     ScopedLocalRef<jobject> receiver_ref(soa.Env(), soa.AddLocalReference<jobject>(receiver));
    201     jvalue args[1];
    202 
    203     args[0].d = 0.0;
    204     JValue result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
    205     EXPECT_DOUBLE_EQ(0.0, result.GetD());
    206 
    207     args[0].d = -1.0;
    208     result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
    209     EXPECT_DOUBLE_EQ(-1.0, result.GetD());
    210 
    211     args[0].d = DBL_MAX;
    212     result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
    213     EXPECT_DOUBLE_EQ(DBL_MAX, result.GetD());
    214 
    215     args[0].d = DBL_MIN;
    216     result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
    217     EXPECT_DOUBLE_EQ(DBL_MIN, result.GetD());
    218   }
    219 
    220   void InvokeSumIntIntMethod(bool is_static) {
    221     ScopedObjectAccess soa(env_);
    222     ArtMethod* method;
    223     ObjPtr<mirror::Object> receiver;
    224     ReflectionTestMakeExecutable(&method, &receiver, is_static, "sum", "(II)I");
    225     ScopedLocalRef<jobject> receiver_ref(soa.Env(), soa.AddLocalReference<jobject>(receiver));
    226     jvalue args[2];
    227 
    228     args[0].i = 1;
    229     args[1].i = 2;
    230     JValue result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
    231     EXPECT_EQ(3, result.GetI());
    232 
    233     args[0].i = -2;
    234     args[1].i = 5;
    235     result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
    236     EXPECT_EQ(3, result.GetI());
    237 
    238     args[0].i = INT_MAX;
    239     args[1].i = INT_MIN;
    240     result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
    241     EXPECT_EQ(-1, result.GetI());
    242 
    243     args[0].i = INT_MAX;
    244     args[1].i = INT_MAX;
    245     result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
    246     EXPECT_EQ(-2, result.GetI());
    247   }
    248 
    249   void InvokeSumIntIntIntMethod(bool is_static) {
    250     ScopedObjectAccess soa(env_);
    251     ArtMethod* method;
    252     ObjPtr<mirror::Object> receiver;
    253     ReflectionTestMakeExecutable(&method, &receiver, is_static, "sum", "(III)I");
    254     ScopedLocalRef<jobject> receiver_ref(soa.Env(), soa.AddLocalReference<jobject>(receiver));
    255     jvalue args[3];
    256 
    257     args[0].i = 0;
    258     args[1].i = 0;
    259     args[2].i = 0;
    260     JValue result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
    261     EXPECT_EQ(0, result.GetI());
    262 
    263     args[0].i = 1;
    264     args[1].i = 2;
    265     args[2].i = 3;
    266     result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
    267     EXPECT_EQ(6, result.GetI());
    268 
    269     args[0].i = -1;
    270     args[1].i = 2;
    271     args[2].i = -3;
    272     result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
    273     EXPECT_EQ(-2, result.GetI());
    274 
    275     args[0].i = INT_MAX;
    276     args[1].i = INT_MIN;
    277     args[2].i = INT_MAX;
    278     result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
    279     EXPECT_EQ(2147483646, result.GetI());
    280 
    281     args[0].i = INT_MAX;
    282     args[1].i = INT_MAX;
    283     args[2].i = INT_MAX;
    284     result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
    285     EXPECT_EQ(2147483645, result.GetI());
    286   }
    287 
    288   void InvokeSumIntIntIntIntMethod(bool is_static) {
    289     ScopedObjectAccess soa(env_);
    290     ArtMethod* method;
    291     ObjPtr<mirror::Object> receiver;
    292     ReflectionTestMakeExecutable(&method, &receiver, is_static, "sum", "(IIII)I");
    293     ScopedLocalRef<jobject> receiver_ref(soa.Env(), soa.AddLocalReference<jobject>(receiver));
    294     jvalue args[4];
    295 
    296     args[0].i = 0;
    297     args[1].i = 0;
    298     args[2].i = 0;
    299     args[3].i = 0;
    300     JValue result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
    301     EXPECT_EQ(0, result.GetI());
    302 
    303     args[0].i = 1;
    304     args[1].i = 2;
    305     args[2].i = 3;
    306     args[3].i = 4;
    307     result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
    308     EXPECT_EQ(10, result.GetI());
    309 
    310     args[0].i = -1;
    311     args[1].i = 2;
    312     args[2].i = -3;
    313     args[3].i = 4;
    314     result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
    315     EXPECT_EQ(2, result.GetI());
    316 
    317     args[0].i = INT_MAX;
    318     args[1].i = INT_MIN;
    319     args[2].i = INT_MAX;
    320     args[3].i = INT_MIN;
    321     result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
    322     EXPECT_EQ(-2, result.GetI());
    323 
    324     args[0].i = INT_MAX;
    325     args[1].i = INT_MAX;
    326     args[2].i = INT_MAX;
    327     args[3].i = INT_MAX;
    328     result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
    329     EXPECT_EQ(-4, result.GetI());
    330   }
    331 
    332   void InvokeSumIntIntIntIntIntMethod(bool is_static) {
    333     ScopedObjectAccess soa(env_);
    334     ArtMethod* method;
    335     ObjPtr<mirror::Object> receiver;
    336     ReflectionTestMakeExecutable(&method, &receiver, is_static, "sum", "(IIIII)I");
    337     ScopedLocalRef<jobject> receiver_ref(soa.Env(), soa.AddLocalReference<jobject>(receiver));
    338     jvalue args[5];
    339 
    340     args[0].i = 0;
    341     args[1].i = 0;
    342     args[2].i = 0;
    343     args[3].i = 0;
    344     args[4].i = 0;
    345     JValue result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
    346     EXPECT_EQ(0, result.GetI());
    347 
    348     args[0].i = 1;
    349     args[1].i = 2;
    350     args[2].i = 3;
    351     args[3].i = 4;
    352     args[4].i = 5;
    353     result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
    354     EXPECT_EQ(15, result.GetI());
    355 
    356     args[0].i = -1;
    357     args[1].i = 2;
    358     args[2].i = -3;
    359     args[3].i = 4;
    360     args[4].i = -5;
    361     result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
    362     EXPECT_EQ(-3, result.GetI());
    363 
    364     args[0].i = INT_MAX;
    365     args[1].i = INT_MIN;
    366     args[2].i = INT_MAX;
    367     args[3].i = INT_MIN;
    368     args[4].i = INT_MAX;
    369     result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
    370     EXPECT_EQ(2147483645, result.GetI());
    371 
    372     args[0].i = INT_MAX;
    373     args[1].i = INT_MAX;
    374     args[2].i = INT_MAX;
    375     args[3].i = INT_MAX;
    376     args[4].i = INT_MAX;
    377     result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
    378     EXPECT_EQ(2147483643, result.GetI());
    379   }
    380 
    381   void InvokeSumDoubleDoubleMethod(bool is_static) {
    382     ScopedObjectAccess soa(env_);
    383     ArtMethod* method;
    384     ObjPtr<mirror::Object> receiver;
    385     ReflectionTestMakeExecutable(&method, &receiver, is_static, "sum", "(DD)D");
    386     ScopedLocalRef<jobject> receiver_ref(soa.Env(), soa.AddLocalReference<jobject>(receiver));
    387     jvalue args[2];
    388 
    389     args[0].d = 0.0;
    390     args[1].d = 0.0;
    391     JValue result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
    392     EXPECT_DOUBLE_EQ(0.0, result.GetD());
    393 
    394     args[0].d = 1.0;
    395     args[1].d = 2.0;
    396     result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
    397     EXPECT_DOUBLE_EQ(3.0, result.GetD());
    398 
    399     args[0].d = 1.0;
    400     args[1].d = -2.0;
    401     result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
    402     EXPECT_DOUBLE_EQ(-1.0, result.GetD());
    403 
    404     args[0].d = DBL_MAX;
    405     args[1].d = DBL_MIN;
    406     result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
    407     EXPECT_DOUBLE_EQ(1.7976931348623157e308, result.GetD());
    408 
    409     args[0].d = DBL_MAX;
    410     args[1].d = DBL_MAX;
    411     result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
    412     EXPECT_DOUBLE_EQ(INFINITY, result.GetD());
    413   }
    414 
    415   void InvokeSumDoubleDoubleDoubleMethod(bool is_static) {
    416     ScopedObjectAccess soa(env_);
    417     ArtMethod* method;
    418     ObjPtr<mirror::Object> receiver;
    419     ReflectionTestMakeExecutable(&method, &receiver, is_static, "sum", "(DDD)D");
    420     ScopedLocalRef<jobject> receiver_ref(soa.Env(), soa.AddLocalReference<jobject>(receiver));
    421     jvalue args[3];
    422 
    423     args[0].d = 0.0;
    424     args[1].d = 0.0;
    425     args[2].d = 0.0;
    426     JValue result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
    427     EXPECT_DOUBLE_EQ(0.0, result.GetD());
    428 
    429     args[0].d = 1.0;
    430     args[1].d = 2.0;
    431     args[2].d = 3.0;
    432     result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
    433     EXPECT_DOUBLE_EQ(6.0, result.GetD());
    434 
    435     args[0].d = 1.0;
    436     args[1].d = -2.0;
    437     args[2].d = 3.0;
    438     result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
    439     EXPECT_DOUBLE_EQ(2.0, result.GetD());
    440   }
    441 
    442   void InvokeSumDoubleDoubleDoubleDoubleMethod(bool is_static) {
    443     ScopedObjectAccess soa(env_);
    444     ArtMethod* method;
    445     ObjPtr<mirror::Object> receiver;
    446     ReflectionTestMakeExecutable(&method, &receiver, is_static, "sum", "(DDDD)D");
    447     ScopedLocalRef<jobject> receiver_ref(soa.Env(), soa.AddLocalReference<jobject>(receiver));
    448     jvalue args[4];
    449 
    450     args[0].d = 0.0;
    451     args[1].d = 0.0;
    452     args[2].d = 0.0;
    453     args[3].d = 0.0;
    454     JValue result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
    455     EXPECT_DOUBLE_EQ(0.0, result.GetD());
    456 
    457     args[0].d = 1.0;
    458     args[1].d = 2.0;
    459     args[2].d = 3.0;
    460     args[3].d = 4.0;
    461     result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
    462     EXPECT_DOUBLE_EQ(10.0, result.GetD());
    463 
    464     args[0].d = 1.0;
    465     args[1].d = -2.0;
    466     args[2].d = 3.0;
    467     args[3].d = -4.0;
    468     result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
    469     EXPECT_DOUBLE_EQ(-2.0, result.GetD());
    470   }
    471 
    472   void InvokeSumDoubleDoubleDoubleDoubleDoubleMethod(bool is_static) {
    473     ScopedObjectAccess soa(env_);
    474     ArtMethod* method;
    475     ObjPtr<mirror::Object> receiver;
    476     ReflectionTestMakeExecutable(&method, &receiver, is_static, "sum", "(DDDDD)D");
    477     ScopedLocalRef<jobject> receiver_ref(soa.Env(), soa.AddLocalReference<jobject>(receiver));
    478     jvalue args[5];
    479 
    480     args[0].d = 0.0;
    481     args[1].d = 0.0;
    482     args[2].d = 0.0;
    483     args[3].d = 0.0;
    484     args[4].d = 0.0;
    485     JValue result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
    486     EXPECT_DOUBLE_EQ(0.0, result.GetD());
    487 
    488     args[0].d = 1.0;
    489     args[1].d = 2.0;
    490     args[2].d = 3.0;
    491     args[3].d = 4.0;
    492     args[4].d = 5.0;
    493     result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
    494     EXPECT_DOUBLE_EQ(15.0, result.GetD());
    495 
    496     args[0].d = 1.0;
    497     args[1].d = -2.0;
    498     args[2].d = 3.0;
    499     args[3].d = -4.0;
    500     args[4].d = 5.0;
    501     result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
    502     EXPECT_DOUBLE_EQ(3.0, result.GetD());
    503   }
    504 
    505   JavaVMExt* vm_;
    506   JNIEnv* env_;
    507   jclass aioobe_;
    508   jclass ase_;
    509   jclass sioobe_;
    510 };
    511 
    512 TEST_F(ReflectionTest, StaticMainMethod) {
    513   ScopedObjectAccess soa(Thread::Current());
    514   jobject jclass_loader = LoadDex("Main");
    515   StackHandleScope<1> hs(soa.Self());
    516   Handle<mirror::ClassLoader> class_loader(
    517       hs.NewHandle(soa.Decode<mirror::ClassLoader>(jclass_loader)));
    518   CompileDirectMethod(class_loader, "Main", "main", "([Ljava/lang/String;)V");
    519 
    520   mirror::Class* klass = class_linker_->FindClass(soa.Self(), "LMain;", class_loader);
    521   ASSERT_TRUE(klass != nullptr);
    522 
    523   ArtMethod* method = klass->FindDirectMethod("main",
    524                                               "([Ljava/lang/String;)V",
    525                                               kRuntimePointerSize);
    526   ASSERT_TRUE(method != nullptr);
    527 
    528   // Start runtime.
    529   bool started = runtime_->Start();
    530   CHECK(started);
    531   soa.Self()->TransitionFromSuspendedToRunnable();
    532 
    533   jvalue args[1];
    534   args[0].l = nullptr;
    535   InvokeWithJValues(soa, nullptr, jni::EncodeArtMethod(method), args);
    536 }
    537 
    538 TEST_F(ReflectionTest, StaticNopMethod) {
    539   InvokeNopMethod(true);
    540 }
    541 
    542 TEST_F(ReflectionTest, NonStaticNopMethod) {
    543   InvokeNopMethod(false);
    544 }
    545 
    546 TEST_F(ReflectionTest, StaticIdentityByteMethod) {
    547   InvokeIdentityByteMethod(true);
    548 }
    549 
    550 TEST_F(ReflectionTest, NonStaticIdentityByteMethod) {
    551   InvokeIdentityByteMethod(false);
    552 }
    553 
    554 TEST_F(ReflectionTest, StaticIdentityIntMethod) {
    555   InvokeIdentityIntMethod(true);
    556 }
    557 
    558 TEST_F(ReflectionTest, NonStaticIdentityIntMethod) {
    559   InvokeIdentityIntMethod(false);
    560 }
    561 
    562 TEST_F(ReflectionTest, StaticIdentityDoubleMethod) {
    563   InvokeIdentityDoubleMethod(true);
    564 }
    565 
    566 TEST_F(ReflectionTest, NonStaticIdentityDoubleMethod) {
    567   InvokeIdentityDoubleMethod(false);
    568 }
    569 
    570 TEST_F(ReflectionTest, StaticSumIntIntMethod) {
    571   InvokeSumIntIntMethod(true);
    572 }
    573 
    574 TEST_F(ReflectionTest, NonStaticSumIntIntMethod) {
    575   InvokeSumIntIntMethod(false);
    576 }
    577 
    578 TEST_F(ReflectionTest, StaticSumIntIntIntMethod) {
    579   InvokeSumIntIntIntMethod(true);
    580 }
    581 
    582 TEST_F(ReflectionTest, NonStaticSumIntIntIntMethod) {
    583   InvokeSumIntIntIntMethod(false);
    584 }
    585 
    586 TEST_F(ReflectionTest, StaticSumIntIntIntIntMethod) {
    587   InvokeSumIntIntIntIntMethod(true);
    588 }
    589 
    590 TEST_F(ReflectionTest, NonStaticSumIntIntIntIntMethod) {
    591   InvokeSumIntIntIntIntMethod(false);
    592 }
    593 
    594 TEST_F(ReflectionTest, StaticSumIntIntIntIntIntMethod) {
    595   InvokeSumIntIntIntIntIntMethod(true);
    596 }
    597 
    598 TEST_F(ReflectionTest, NonStaticSumIntIntIntIntIntMethod) {
    599   InvokeSumIntIntIntIntIntMethod(false);
    600 }
    601 
    602 TEST_F(ReflectionTest, StaticSumDoubleDoubleMethod) {
    603   InvokeSumDoubleDoubleMethod(true);
    604 }
    605 
    606 TEST_F(ReflectionTest, NonStaticSumDoubleDoubleMethod) {
    607   InvokeSumDoubleDoubleMethod(false);
    608 }
    609 
    610 TEST_F(ReflectionTest, StaticSumDoubleDoubleDoubleMethod) {
    611   InvokeSumDoubleDoubleDoubleMethod(true);
    612 }
    613 
    614 TEST_F(ReflectionTest, NonStaticSumDoubleDoubleDoubleMethod) {
    615   InvokeSumDoubleDoubleDoubleMethod(false);
    616 }
    617 
    618 TEST_F(ReflectionTest, StaticSumDoubleDoubleDoubleDoubleMethod) {
    619   InvokeSumDoubleDoubleDoubleDoubleMethod(true);
    620 }
    621 
    622 TEST_F(ReflectionTest, NonStaticSumDoubleDoubleDoubleDoubleMethod) {
    623   InvokeSumDoubleDoubleDoubleDoubleMethod(false);
    624 }
    625 
    626 TEST_F(ReflectionTest, StaticSumDoubleDoubleDoubleDoubleDoubleMethod) {
    627   InvokeSumDoubleDoubleDoubleDoubleDoubleMethod(true);
    628 }
    629 
    630 TEST_F(ReflectionTest, NonStaticSumDoubleDoubleDoubleDoubleDoubleMethod) {
    631   InvokeSumDoubleDoubleDoubleDoubleDoubleMethod(false);
    632 }
    633 
    634 }  // namespace art
    635