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:
SetUp()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 
CleanUpJniEnv()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 
TearDown()75   virtual void TearDown() {
76     CleanUpJniEnv();
77     CommonCompilerTest::TearDown();
78   }
79 
GetPrimitiveClass(char descriptor)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 
ReflectionTestMakeExecutable(ArtMethod ** method,ObjPtr<mirror::Object> * receiver,bool is_static,const char * method_name,const char * method_signature)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 
InvokeNopMethod(bool is_static)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 
InvokeIdentityByteMethod(bool is_static)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 
InvokeIdentityIntMethod(bool is_static)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 
InvokeIdentityDoubleMethod(bool is_static)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 
InvokeSumIntIntMethod(bool is_static)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 
InvokeSumIntIntIntMethod(bool is_static)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 
InvokeSumIntIntIntIntMethod(bool is_static)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 
InvokeSumIntIntIntIntIntMethod(bool is_static)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 
InvokeSumDoubleDoubleMethod(bool is_static)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 
InvokeSumDoubleDoubleDoubleMethod(bool is_static)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 
InvokeSumDoubleDoubleDoubleDoubleMethod(bool is_static)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 
InvokeSumDoubleDoubleDoubleDoubleDoubleMethod(bool is_static)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 
TEST_F(ReflectionTest,StaticMainMethod)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 
TEST_F(ReflectionTest,StaticNopMethod)538 TEST_F(ReflectionTest, StaticNopMethod) {
539   InvokeNopMethod(true);
540 }
541 
TEST_F(ReflectionTest,NonStaticNopMethod)542 TEST_F(ReflectionTest, NonStaticNopMethod) {
543   InvokeNopMethod(false);
544 }
545 
TEST_F(ReflectionTest,StaticIdentityByteMethod)546 TEST_F(ReflectionTest, StaticIdentityByteMethod) {
547   InvokeIdentityByteMethod(true);
548 }
549 
TEST_F(ReflectionTest,NonStaticIdentityByteMethod)550 TEST_F(ReflectionTest, NonStaticIdentityByteMethod) {
551   InvokeIdentityByteMethod(false);
552 }
553 
TEST_F(ReflectionTest,StaticIdentityIntMethod)554 TEST_F(ReflectionTest, StaticIdentityIntMethod) {
555   InvokeIdentityIntMethod(true);
556 }
557 
TEST_F(ReflectionTest,NonStaticIdentityIntMethod)558 TEST_F(ReflectionTest, NonStaticIdentityIntMethod) {
559   InvokeIdentityIntMethod(false);
560 }
561 
TEST_F(ReflectionTest,StaticIdentityDoubleMethod)562 TEST_F(ReflectionTest, StaticIdentityDoubleMethod) {
563   InvokeIdentityDoubleMethod(true);
564 }
565 
TEST_F(ReflectionTest,NonStaticIdentityDoubleMethod)566 TEST_F(ReflectionTest, NonStaticIdentityDoubleMethod) {
567   InvokeIdentityDoubleMethod(false);
568 }
569 
TEST_F(ReflectionTest,StaticSumIntIntMethod)570 TEST_F(ReflectionTest, StaticSumIntIntMethod) {
571   InvokeSumIntIntMethod(true);
572 }
573 
TEST_F(ReflectionTest,NonStaticSumIntIntMethod)574 TEST_F(ReflectionTest, NonStaticSumIntIntMethod) {
575   InvokeSumIntIntMethod(false);
576 }
577 
TEST_F(ReflectionTest,StaticSumIntIntIntMethod)578 TEST_F(ReflectionTest, StaticSumIntIntIntMethod) {
579   InvokeSumIntIntIntMethod(true);
580 }
581 
TEST_F(ReflectionTest,NonStaticSumIntIntIntMethod)582 TEST_F(ReflectionTest, NonStaticSumIntIntIntMethod) {
583   InvokeSumIntIntIntMethod(false);
584 }
585 
TEST_F(ReflectionTest,StaticSumIntIntIntIntMethod)586 TEST_F(ReflectionTest, StaticSumIntIntIntIntMethod) {
587   InvokeSumIntIntIntIntMethod(true);
588 }
589 
TEST_F(ReflectionTest,NonStaticSumIntIntIntIntMethod)590 TEST_F(ReflectionTest, NonStaticSumIntIntIntIntMethod) {
591   InvokeSumIntIntIntIntMethod(false);
592 }
593 
TEST_F(ReflectionTest,StaticSumIntIntIntIntIntMethod)594 TEST_F(ReflectionTest, StaticSumIntIntIntIntIntMethod) {
595   InvokeSumIntIntIntIntIntMethod(true);
596 }
597 
TEST_F(ReflectionTest,NonStaticSumIntIntIntIntIntMethod)598 TEST_F(ReflectionTest, NonStaticSumIntIntIntIntIntMethod) {
599   InvokeSumIntIntIntIntIntMethod(false);
600 }
601 
TEST_F(ReflectionTest,StaticSumDoubleDoubleMethod)602 TEST_F(ReflectionTest, StaticSumDoubleDoubleMethod) {
603   InvokeSumDoubleDoubleMethod(true);
604 }
605 
TEST_F(ReflectionTest,NonStaticSumDoubleDoubleMethod)606 TEST_F(ReflectionTest, NonStaticSumDoubleDoubleMethod) {
607   InvokeSumDoubleDoubleMethod(false);
608 }
609 
TEST_F(ReflectionTest,StaticSumDoubleDoubleDoubleMethod)610 TEST_F(ReflectionTest, StaticSumDoubleDoubleDoubleMethod) {
611   InvokeSumDoubleDoubleDoubleMethod(true);
612 }
613 
TEST_F(ReflectionTest,NonStaticSumDoubleDoubleDoubleMethod)614 TEST_F(ReflectionTest, NonStaticSumDoubleDoubleDoubleMethod) {
615   InvokeSumDoubleDoubleDoubleMethod(false);
616 }
617 
TEST_F(ReflectionTest,StaticSumDoubleDoubleDoubleDoubleMethod)618 TEST_F(ReflectionTest, StaticSumDoubleDoubleDoubleDoubleMethod) {
619   InvokeSumDoubleDoubleDoubleDoubleMethod(true);
620 }
621 
TEST_F(ReflectionTest,NonStaticSumDoubleDoubleDoubleDoubleMethod)622 TEST_F(ReflectionTest, NonStaticSumDoubleDoubleDoubleDoubleMethod) {
623   InvokeSumDoubleDoubleDoubleDoubleMethod(false);
624 }
625 
TEST_F(ReflectionTest,StaticSumDoubleDoubleDoubleDoubleDoubleMethod)626 TEST_F(ReflectionTest, StaticSumDoubleDoubleDoubleDoubleDoubleMethod) {
627   InvokeSumDoubleDoubleDoubleDoubleDoubleMethod(true);
628 }
629 
TEST_F(ReflectionTest,NonStaticSumDoubleDoubleDoubleDoubleDoubleMethod)630 TEST_F(ReflectionTest, NonStaticSumDoubleDoubleDoubleDoubleDoubleMethod) {
631   InvokeSumDoubleDoubleDoubleDoubleDoubleMethod(false);
632 }
633 
634 }  // namespace art
635