blob: 63881fdccd6258719911bc308b10422a94a4dc82 [file] [log] [blame]
buzbeec143c552011-08-20 17:38:58 -07001// Copyright 2011 Google Inc. All Rights Reserved.
2
Elliott Hughes90a33692011-08-30 13:27:07 -07003#include "compiler.h"
4
5#include <stdint.h>
6#include <stdio.h>
7
8#include "UniquePtr.h"
buzbeec143c552011-08-20 17:38:58 -07009#include "class_linker.h"
10#include "common_test.h"
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -070011#include "dex_cache.h"
buzbeec143c552011-08-20 17:38:58 -070012#include "dex_file.h"
13#include "heap.h"
14#include "object.h"
buzbeec143c552011-08-20 17:38:58 -070015
16namespace art {
17
18class CompilerTest : public CommonTest {
Brian Carlstrombffb1552011-08-25 12:23:53 -070019 protected:
Brian Carlstrom8a487412011-08-29 20:08:52 -070020
21 const ClassLoader* LoadDex(const char* dex_name) {
22 dex_file_.reset(OpenTestDexFile(dex_name));
Brian Carlstrombffb1552011-08-25 12:23:53 -070023 class_linker_->RegisterDexFile(*dex_file_.get());
24 std::vector<const DexFile*> class_path;
25 class_path.push_back(dex_file_.get());
Brian Carlstrom8a487412011-08-29 20:08:52 -070026 const ClassLoader* class_loader = PathClassLoader::Alloc(class_path);
Brian Carlstrombffb1552011-08-25 12:23:53 -070027 Thread::Current()->SetClassLoaderOverride(class_loader);
Brian Carlstrom8a487412011-08-29 20:08:52 -070028 return class_loader;
Brian Carlstrombffb1552011-08-25 12:23:53 -070029 }
30
Brian Carlstrom8a487412011-08-29 20:08:52 -070031
32 void CompileDex(const char* dex_name) {
33 Compile(LoadDex(dex_name));
34 }
35
36 void CompileSystem() {
37 Compile(NULL);
38 }
39
40 void Compile(const ClassLoader* class_loader) {
41 Compiler compiler;
42 compiler.CompileAll(NULL);
43 }
44
45 std::string ConvertClassNameToClassDescriptor(const char* class_name) {
46 std::string desc;
47 desc += "L";
48 desc += class_name;
49 desc += ";";
50 std::replace(desc.begin(), desc.end(), '.', '/');
51 return desc;
52 }
53
54
55 void CompileDirectMethod(const ClassLoader* class_loader,
56 const char* class_name,
57 const char* method_name,
58 const char* signature) {
59 std::string class_descriptor = ConvertClassNameToClassDescriptor(class_name);
60 Class* klass = class_linker_->FindClass(class_descriptor, class_loader);
61 CHECK(klass != NULL) << "Class not found " << class_name;
62 Method* method = klass->FindDirectMethod(method_name, signature);
63 CHECK(method != NULL) << "Method not found " << method_name;
64 Compiler compiler;
65 compiler.CompileOne(method);
66 }
67
68 void CompileVirtualMethod(const ClassLoader* class_loader,
69 const char* class_name,
70 const char* method_name,
71 const char* signature) {
72 std::string class_descriptor = ConvertClassNameToClassDescriptor(class_name);
73 Class* klass = class_linker_->FindClass(class_descriptor, class_loader);
74 CHECK(klass != NULL) << "Class not found " << class_name;
75 Method* method = klass->FindVirtualMethod(method_name, signature);
76 CHECK(method != NULL) << "Method not found " << method_name;
77 Compiler compiler;
78 compiler.CompileOne(method);
79 }
80
81 void AssertStaticIntMethod(const ClassLoader* class_loader,
82 const char* klass, const char* method, const char* signature,
Brian Carlstrombffb1552011-08-25 12:23:53 -070083 jint expected, ...) {
Brian Carlstrom8a487412011-08-29 20:08:52 -070084 CompileDirectMethod(class_loader, klass, method, signature);
Brian Carlstrombffb1552011-08-25 12:23:53 -070085 JNIEnv* env = Thread::Current()->GetJniEnv();
86 jclass c = env->FindClass(klass);
Brian Carlstrom8a487412011-08-29 20:08:52 -070087 CHECK(c != NULL) << "Class not found " << klass;
Brian Carlstrombffb1552011-08-25 12:23:53 -070088 jmethodID m = env->GetStaticMethodID(c, method, signature);
Brian Carlstrom8a487412011-08-29 20:08:52 -070089 CHECK(m != NULL) << "Method not found " << method;
Brian Carlstrombffb1552011-08-25 12:23:53 -070090#if defined(__arm__)
91 va_list args;
92 va_start(args, expected);
93 jint result = env->CallStaticIntMethodV(c, m, args);
94 va_end(args);
95 LOG(INFO) << klass << "." << method << "(...) result is " << result;
96 EXPECT_EQ(expected, result);
97#endif // __arm__
98 }
Brian Carlstrom8a487412011-08-29 20:08:52 -070099 void AssertStaticLongMethod(const ClassLoader* class_loader,
100 const char* klass, const char* method, const char* signature,
101 jlong expected, ...) {
102 CompileDirectMethod(class_loader, klass, method, signature);
buzbeebafc3422011-08-25 15:22:55 -0700103 JNIEnv* env = Thread::Current()->GetJniEnv();
104 jclass c = env->FindClass(klass);
Brian Carlstrom8a487412011-08-29 20:08:52 -0700105 CHECK(c != NULL) << "Class not found " << klass;
buzbeebafc3422011-08-25 15:22:55 -0700106 jmethodID m = env->GetStaticMethodID(c, method, signature);
Brian Carlstrom8a487412011-08-29 20:08:52 -0700107 CHECK(m != NULL) << "Method not found " << method;
buzbeebafc3422011-08-25 15:22:55 -0700108#if defined(__arm__)
109 va_list args;
110 va_start(args, expected);
buzbeec5ef0462011-08-25 18:44:49 -0700111 jlong result = env->CallStaticLongMethodV(c, m, args);
buzbeebafc3422011-08-25 15:22:55 -0700112 va_end(args);
113 LOG(INFO) << klass << "." << method << "(...) result is " << result;
114 EXPECT_EQ(expected, result);
115#endif // __arm__
116 }
Brian Carlstrombffb1552011-08-25 12:23:53 -0700117 private:
Elliott Hughes90a33692011-08-30 13:27:07 -0700118 UniquePtr<const DexFile> dex_file_;
buzbeec143c552011-08-20 17:38:58 -0700119};
120
Brian Carlstrom8a487412011-08-29 20:08:52 -0700121// TODO renenable when compiler can handle libcore
122TEST_F(CompilerTest, DISABLED_CompileDexLibCore) {
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700123 Compiler compiler;
Brian Carlstrom8a487412011-08-29 20:08:52 -0700124 compiler.CompileAll(NULL);
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700125
126 // All libcore references should resolve
127 const DexFile* dex = java_lang_dex_file_.get();
128 DexCache* dex_cache = class_linker_->FindDexCache(*dex);
129 EXPECT_EQ(dex->NumStringIds(), dex_cache->NumStrings());
130 for (size_t i = 0; i < dex_cache->NumStrings(); i++) {
131 String* string = dex_cache->GetResolvedString(i);
132 EXPECT_TRUE(string != NULL);
133 }
Brian Carlstrom1caa2c22011-08-28 13:02:33 -0700134 EXPECT_EQ(dex->NumTypeIds(), dex_cache->NumResolvedTypes());
135 for (size_t i = 0; i < dex_cache->NumResolvedTypes(); i++) {
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700136 Class* type = dex_cache->GetResolvedType(i);
137 EXPECT_TRUE(type != NULL);
138 }
Brian Carlstrom1caa2c22011-08-28 13:02:33 -0700139 EXPECT_EQ(dex->NumMethodIds(), dex_cache->NumResolvedMethods());
140 for (size_t i = 0; i < dex_cache->NumResolvedMethods(); i++) {
Brian Carlstrom20cfffa2011-08-26 02:31:27 -0700141 Method* method = dex_cache->GetResolvedMethod(i);
142 EXPECT_TRUE(method != NULL);
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700143 }
Brian Carlstrom1caa2c22011-08-28 13:02:33 -0700144 EXPECT_EQ(dex->NumFieldIds(), dex_cache->NumResolvedFields());
145 for (size_t i = 0; i < dex_cache->NumResolvedFields(); i++) {
Brian Carlstrom20cfffa2011-08-26 02:31:27 -0700146 Field* field = dex_cache->GetResolvedField(i);
147 EXPECT_TRUE(field != NULL);
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700148 }
149
Brian Carlstrom83db7722011-08-26 17:32:56 -0700150 // TODO check Class::IsVerified for all classes
151
152 // TODO: check that all Method::GetCode() values are non-null
153
Brian Carlstrom9cc262e2011-08-28 12:45:30 -0700154 EXPECT_EQ(dex->NumMethodIds(), dex_cache->NumCodeAndDirectMethods());
155 CodeAndDirectMethods* code_and_direct_methods = dex_cache->GetCodeAndDirectMethods();
156 for (size_t i = 0; i < dex_cache->NumCodeAndDirectMethods(); i++) {
Brian Carlstrom83db7722011-08-26 17:32:56 -0700157 Method* method = dex_cache->GetResolvedMethod(i);
Brian Carlstrom9cc262e2011-08-28 12:45:30 -0700158 EXPECT_EQ(method->GetCode(), code_and_direct_methods->GetResolvedCode(i));
159 EXPECT_EQ(method, code_and_direct_methods->GetResolvedMethod(i));
Brian Carlstrom83db7722011-08-26 17:32:56 -0700160 }
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700161}
162
buzbeec143c552011-08-20 17:38:58 -0700163TEST_F(CompilerTest, BasicCodegen) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700164 AssertStaticIntMethod(LoadDex("Fibonacci"), "Fibonacci", "fibonacci", "(I)I", 55,
Brian Carlstrombffb1552011-08-25 12:23:53 -0700165 10);
buzbeec143c552011-08-20 17:38:58 -0700166}
buzbee3ea4ec52011-08-22 17:37:19 -0700167
buzbeee1931742011-08-28 21:15:53 -0700168TEST_F(CompilerTest, StaticFieldTest) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700169 AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "staticFieldTest", "(I)I", 1404,
buzbeee1931742011-08-28 21:15:53 -0700170 404);
171}
172
buzbee3ea4ec52011-08-22 17:37:19 -0700173TEST_F(CompilerTest, UnopTest) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700174 AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "unopTest", "(I)I", 37,
Brian Carlstrombffb1552011-08-25 12:23:53 -0700175 38);
buzbee3ea4ec52011-08-22 17:37:19 -0700176}
177
buzbee3ea4ec52011-08-22 17:37:19 -0700178TEST_F(CompilerTest, ShiftTest1) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700179 AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "shiftTest1", "()I", 0);
buzbee3ea4ec52011-08-22 17:37:19 -0700180}
buzbeec143c552011-08-20 17:38:58 -0700181
buzbee3ea4ec52011-08-22 17:37:19 -0700182TEST_F(CompilerTest, ShiftTest2) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700183 AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "shiftTest2", "()I", 0);
buzbee3ea4ec52011-08-22 17:37:19 -0700184}
buzbee3ea4ec52011-08-22 17:37:19 -0700185
186TEST_F(CompilerTest, UnsignedShiftTest) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700187 AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "unsignedShiftTest", "()I", 0);
buzbee3ea4ec52011-08-22 17:37:19 -0700188}
189
buzbee3ea4ec52011-08-22 17:37:19 -0700190TEST_F(CompilerTest, ConvTest) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700191 AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "convTest", "()I", 0);
buzbee3ea4ec52011-08-22 17:37:19 -0700192}
buzbee3ea4ec52011-08-22 17:37:19 -0700193
194TEST_F(CompilerTest, CharSubTest) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700195 AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "charSubTest", "()I", 0);
buzbee3ea4ec52011-08-22 17:37:19 -0700196}
197
buzbee3ea4ec52011-08-22 17:37:19 -0700198TEST_F(CompilerTest, IntOperTest) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700199 AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "intOperTest", "(II)I", 0,
Brian Carlstrombffb1552011-08-25 12:23:53 -0700200 70000, -3);
buzbee3ea4ec52011-08-22 17:37:19 -0700201}
buzbee3ea4ec52011-08-22 17:37:19 -0700202
buzbee3ea4ec52011-08-22 17:37:19 -0700203TEST_F(CompilerTest, Lit16Test) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700204 AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "lit16Test", "(I)I", 0,
Brian Carlstrombffb1552011-08-25 12:23:53 -0700205 77777);
buzbee3ea4ec52011-08-22 17:37:19 -0700206}
buzbee3ea4ec52011-08-22 17:37:19 -0700207
buzbee3ea4ec52011-08-22 17:37:19 -0700208TEST_F(CompilerTest, Lit8Test) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700209 AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "lit8Test", "(I)I", 0,
Brian Carlstrombffb1552011-08-25 12:23:53 -0700210 -55555);
buzbee3ea4ec52011-08-22 17:37:19 -0700211}
buzbee3ea4ec52011-08-22 17:37:19 -0700212
buzbee3ea4ec52011-08-22 17:37:19 -0700213TEST_F(CompilerTest, IntShiftTest) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700214 AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "intShiftTest", "(II)I", 0,
Brian Carlstrombffb1552011-08-25 12:23:53 -0700215 0xff00aa01, 8);
buzbee3ea4ec52011-08-22 17:37:19 -0700216}
buzbee3ea4ec52011-08-22 17:37:19 -0700217
buzbee3ea4ec52011-08-22 17:37:19 -0700218TEST_F(CompilerTest, LongOperTest) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700219 AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "longOperTest", "(JJ)I", 0,
buzbee439c4fa2011-08-27 15:59:07 -0700220 70000000000LL, -3LL);
buzbee3ea4ec52011-08-22 17:37:19 -0700221}
buzbee3ea4ec52011-08-22 17:37:19 -0700222
buzbee3ea4ec52011-08-22 17:37:19 -0700223TEST_F(CompilerTest, LongShiftTest) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700224 AssertStaticLongMethod(LoadDex("IntMath"), "IntMath", "longShiftTest", "(JI)J",
buzbee7b1b86d2011-08-26 18:59:10 -0700225 0x96deff00aa010000LL, 0xd5aa96deff00aa01LL, 16);
buzbee3ea4ec52011-08-22 17:37:19 -0700226}
buzbee3ea4ec52011-08-22 17:37:19 -0700227
buzbee9e0f9b02011-08-24 15:32:46 -0700228TEST_F(CompilerTest, SwitchTest1) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700229 AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "switchTest", "(I)I", 1234,
Brian Carlstrombffb1552011-08-25 12:23:53 -0700230 1);
buzbee9e0f9b02011-08-24 15:32:46 -0700231}
232
233TEST_F(CompilerTest, IntCompare) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700234 AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "testIntCompare", "(IIII)I", 1111,
Brian Carlstrombffb1552011-08-25 12:23:53 -0700235 -5, 4, 4, 0);
buzbee9e0f9b02011-08-24 15:32:46 -0700236}
237
238TEST_F(CompilerTest, LongCompare) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700239 AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "testLongCompare", "(JJJJ)I", 2222,
Brian Carlstrombffb1552011-08-25 12:23:53 -0700240 -5LL, -4294967287LL, 4LL, 8LL);
buzbee9e0f9b02011-08-24 15:32:46 -0700241}
242
243TEST_F(CompilerTest, FloatCompare) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700244 AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "testFloatCompare", "(FFFF)I", 3333,
Brian Carlstrombffb1552011-08-25 12:23:53 -0700245 -5.0f, 4.0f, 4.0f,
246 (1.0f/0.0f) / (1.0f/0.0f));
buzbee9e0f9b02011-08-24 15:32:46 -0700247}
248
249TEST_F(CompilerTest, DoubleCompare) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700250 AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "testDoubleCompare", "(DDDD)I", 4444,
Brian Carlstrombffb1552011-08-25 12:23:53 -0700251 -5.0, 4.0, 4.0,
252 (1.0/0.0) / (1.0/0.0));
buzbee9e0f9b02011-08-24 15:32:46 -0700253}
254
buzbeec5ef0462011-08-25 18:44:49 -0700255TEST_F(CompilerTest, RecursiveFibonacci) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700256 AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "fibonacci", "(I)I", 55,
buzbeec5ef0462011-08-25 18:44:49 -0700257 10);
258}
buzbeec5ef0462011-08-25 18:44:49 -0700259
buzbee7b1b86d2011-08-26 18:59:10 -0700260#if 0 // Need to complete try/catch block handling
261TEST_F(CompilerTest, ThrowAndCatch) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700262 AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "throwAndCatch", "()I", 4);
buzbee7b1b86d2011-08-26 18:59:10 -0700263}
264#endif
265
266TEST_F(CompilerTest, ManyArgs) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700267 AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "manyArgs",
buzbee7b1b86d2011-08-26 18:59:10 -0700268 "(IJIJIJIIDFDSICIIBZIIJJIIIII)I", -1,
269 0, 1LL, 2, 3LL, 4, 5LL, 6, 7, 8.0, 9.0f, 10.0,
270 (short)11, 12, (char)13, 14, 15, (int8_t)-16, true, 18,
271 19, 20LL, 21LL, 22, 23, 24, 25, 26);
272}
273
buzbee7b1b86d2011-08-26 18:59:10 -0700274TEST_F(CompilerTest, VirtualCall) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700275 CompileDirectMethod(NULL, "java.lang.Object", "<init>", "()V");
276 const ClassLoader* class_loader = LoadDex("IntMath");
277 CompileDirectMethod(class_loader, "IntMath", "<init>", "()V");
278 CompileVirtualMethod(class_loader, "IntMath", "virtualCall", "(I)I");
279 AssertStaticIntMethod(class_loader, "IntMath", "staticCall", "(I)I", 6,
buzbee7b1b86d2011-08-26 18:59:10 -0700280 3);
281}
buzbee7b1b86d2011-08-26 18:59:10 -0700282
buzbeedd3efae2011-08-28 14:39:07 -0700283TEST_F(CompilerTest, TestIGetPut) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700284 CompileDirectMethod(NULL, "java.lang.Object", "<init>", "()V");
285 const ClassLoader* class_loader = LoadDex("IntMath");
286 CompileDirectMethod(class_loader, "IntMath", "<init>", "(I)V");
287 CompileDirectMethod(class_loader, "IntMath", "<init>", "()V");
288 CompileVirtualMethod(class_loader, "IntMath", "getFoo", "()I");
289 CompileVirtualMethod(class_loader, "IntMath", "setFoo", "(I)V");
290 AssertStaticIntMethod(class_loader, "IntMath", "testIGetPut", "(I)I", 333,
buzbeedd3efae2011-08-28 14:39:07 -0700291 111);
292}
293
buzbeec143c552011-08-20 17:38:58 -0700294} // namespace art