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