blob: 229235a855b035812c35b75f0a78e55a5169622d [file] [log] [blame]
buzbeec143c552011-08-20 17:38:58 -07001// Copyright 2011 Google Inc. All Rights Reserved.
2
3#include "class_linker.h"
4#include "common_test.h"
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -07005#include "compiler.h"
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -07006#include "dex_cache.h"
buzbeec143c552011-08-20 17:38:58 -07007#include "dex_file.h"
8#include "heap.h"
9#include "object.h"
10#include "scoped_ptr.h"
11
12#include <stdint.h>
13#include <stdio.h>
buzbeec143c552011-08-20 17:38:58 -070014
15namespace art {
16
17class CompilerTest : public CommonTest {
Brian Carlstrombffb1552011-08-25 12:23:53 -070018 protected:
Brian Carlstrom8a487412011-08-29 20:08:52 -070019
20 const ClassLoader* LoadDex(const char* dex_name) {
21 dex_file_.reset(OpenTestDexFile(dex_name));
Brian Carlstrombffb1552011-08-25 12:23:53 -070022 class_linker_->RegisterDexFile(*dex_file_.get());
23 std::vector<const DexFile*> class_path;
24 class_path.push_back(dex_file_.get());
Brian Carlstrom8a487412011-08-29 20:08:52 -070025 const ClassLoader* class_loader = PathClassLoader::Alloc(class_path);
Brian Carlstrombffb1552011-08-25 12:23:53 -070026 Thread::Current()->SetClassLoaderOverride(class_loader);
Brian Carlstrom8a487412011-08-29 20:08:52 -070027 return class_loader;
Brian Carlstrombffb1552011-08-25 12:23:53 -070028 }
29
Brian Carlstrom8a487412011-08-29 20:08:52 -070030
31 void CompileDex(const char* dex_name) {
32 Compile(LoadDex(dex_name));
33 }
34
35 void CompileSystem() {
36 Compile(NULL);
37 }
38
39 void Compile(const ClassLoader* class_loader) {
40 Compiler compiler;
41 compiler.CompileAll(NULL);
42 }
43
44 std::string ConvertClassNameToClassDescriptor(const char* class_name) {
45 std::string desc;
46 desc += "L";
47 desc += class_name;
48 desc += ";";
49 std::replace(desc.begin(), desc.end(), '.', '/');
50 return desc;
51 }
52
53
54 void CompileDirectMethod(const ClassLoader* class_loader,
55 const char* class_name,
56 const char* method_name,
57 const char* signature) {
58 std::string class_descriptor = ConvertClassNameToClassDescriptor(class_name);
59 Class* klass = class_linker_->FindClass(class_descriptor, class_loader);
60 CHECK(klass != NULL) << "Class not found " << class_name;
61 Method* method = klass->FindDirectMethod(method_name, signature);
62 CHECK(method != NULL) << "Method not found " << method_name;
63 Compiler compiler;
64 compiler.CompileOne(method);
65 }
66
67 void CompileVirtualMethod(const ClassLoader* class_loader,
68 const char* class_name,
69 const char* method_name,
70 const char* signature) {
71 std::string class_descriptor = ConvertClassNameToClassDescriptor(class_name);
72 Class* klass = class_linker_->FindClass(class_descriptor, class_loader);
73 CHECK(klass != NULL) << "Class not found " << class_name;
74 Method* method = klass->FindVirtualMethod(method_name, signature);
75 CHECK(method != NULL) << "Method not found " << method_name;
76 Compiler compiler;
77 compiler.CompileOne(method);
78 }
79
80 void AssertStaticIntMethod(const ClassLoader* class_loader,
81 const char* klass, const char* method, const char* signature,
Brian Carlstrombffb1552011-08-25 12:23:53 -070082 jint expected, ...) {
Brian Carlstrom8a487412011-08-29 20:08:52 -070083 CompileDirectMethod(class_loader, klass, method, signature);
Brian Carlstrombffb1552011-08-25 12:23:53 -070084 JNIEnv* env = Thread::Current()->GetJniEnv();
85 jclass c = env->FindClass(klass);
Brian Carlstrom8a487412011-08-29 20:08:52 -070086 CHECK(c != NULL) << "Class not found " << klass;
Brian Carlstrombffb1552011-08-25 12:23:53 -070087 jmethodID m = env->GetStaticMethodID(c, method, signature);
Brian Carlstrom8a487412011-08-29 20:08:52 -070088 CHECK(m != NULL) << "Method not found " << method;
Brian Carlstrombffb1552011-08-25 12:23:53 -070089#if defined(__arm__)
90 va_list args;
91 va_start(args, expected);
92 jint result = env->CallStaticIntMethodV(c, m, args);
93 va_end(args);
94 LOG(INFO) << klass << "." << method << "(...) result is " << result;
95 EXPECT_EQ(expected, result);
96#endif // __arm__
97 }
Brian Carlstrom8a487412011-08-29 20:08:52 -070098 void AssertStaticLongMethod(const ClassLoader* class_loader,
99 const char* klass, const char* method, const char* signature,
100 jlong expected, ...) {
101 CompileDirectMethod(class_loader, klass, method, signature);
buzbeebafc3422011-08-25 15:22:55 -0700102 JNIEnv* env = Thread::Current()->GetJniEnv();
103 jclass c = env->FindClass(klass);
Brian Carlstrom8a487412011-08-29 20:08:52 -0700104 CHECK(c != NULL) << "Class not found " << klass;
buzbeebafc3422011-08-25 15:22:55 -0700105 jmethodID m = env->GetStaticMethodID(c, method, signature);
Brian Carlstrom8a487412011-08-29 20:08:52 -0700106 CHECK(m != NULL) << "Method not found " << method;
buzbeebafc3422011-08-25 15:22:55 -0700107#if defined(__arm__)
108 va_list args;
109 va_start(args, expected);
buzbeec5ef0462011-08-25 18:44:49 -0700110 jlong result = env->CallStaticLongMethodV(c, m, args);
buzbeebafc3422011-08-25 15:22:55 -0700111 va_end(args);
112 LOG(INFO) << klass << "." << method << "(...) result is " << result;
113 EXPECT_EQ(expected, result);
114#endif // __arm__
115 }
Brian Carlstrombffb1552011-08-25 12:23:53 -0700116 private:
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700117 scoped_ptr<const DexFile> dex_file_;
buzbeec143c552011-08-20 17:38:58 -0700118};
119
Brian Carlstrom8a487412011-08-29 20:08:52 -0700120// TODO renenable when compiler can handle libcore
121TEST_F(CompilerTest, DISABLED_CompileDexLibCore) {
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700122 Compiler compiler;
Brian Carlstrom8a487412011-08-29 20:08:52 -0700123 compiler.CompileAll(NULL);
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700124
125 // All libcore references should resolve
126 const DexFile* dex = java_lang_dex_file_.get();
127 DexCache* dex_cache = class_linker_->FindDexCache(*dex);
128 EXPECT_EQ(dex->NumStringIds(), dex_cache->NumStrings());
129 for (size_t i = 0; i < dex_cache->NumStrings(); i++) {
130 String* string = dex_cache->GetResolvedString(i);
131 EXPECT_TRUE(string != NULL);
132 }
Brian Carlstrom1caa2c22011-08-28 13:02:33 -0700133 EXPECT_EQ(dex->NumTypeIds(), dex_cache->NumResolvedTypes());
134 for (size_t i = 0; i < dex_cache->NumResolvedTypes(); i++) {
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700135 Class* type = dex_cache->GetResolvedType(i);
136 EXPECT_TRUE(type != NULL);
137 }
Brian Carlstrom1caa2c22011-08-28 13:02:33 -0700138 EXPECT_EQ(dex->NumMethodIds(), dex_cache->NumResolvedMethods());
139 for (size_t i = 0; i < dex_cache->NumResolvedMethods(); i++) {
Brian Carlstrom20cfffa2011-08-26 02:31:27 -0700140 Method* method = dex_cache->GetResolvedMethod(i);
141 EXPECT_TRUE(method != NULL);
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700142 }
Brian Carlstrom1caa2c22011-08-28 13:02:33 -0700143 EXPECT_EQ(dex->NumFieldIds(), dex_cache->NumResolvedFields());
144 for (size_t i = 0; i < dex_cache->NumResolvedFields(); i++) {
Brian Carlstrom20cfffa2011-08-26 02:31:27 -0700145 Field* field = dex_cache->GetResolvedField(i);
146 EXPECT_TRUE(field != NULL);
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700147 }
148
Brian Carlstrom83db7722011-08-26 17:32:56 -0700149 // TODO check Class::IsVerified for all classes
150
151 // TODO: check that all Method::GetCode() values are non-null
152
Brian Carlstrom9cc262e2011-08-28 12:45:30 -0700153 EXPECT_EQ(dex->NumMethodIds(), dex_cache->NumCodeAndDirectMethods());
154 CodeAndDirectMethods* code_and_direct_methods = dex_cache->GetCodeAndDirectMethods();
155 for (size_t i = 0; i < dex_cache->NumCodeAndDirectMethods(); i++) {
Brian Carlstrom83db7722011-08-26 17:32:56 -0700156 Method* method = dex_cache->GetResolvedMethod(i);
Brian Carlstrom9cc262e2011-08-28 12:45:30 -0700157 EXPECT_EQ(method->GetCode(), code_and_direct_methods->GetResolvedCode(i));
158 EXPECT_EQ(method, code_and_direct_methods->GetResolvedMethod(i));
Brian Carlstrom83db7722011-08-26 17:32:56 -0700159 }
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700160}
161
buzbeec143c552011-08-20 17:38:58 -0700162TEST_F(CompilerTest, BasicCodegen) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700163 AssertStaticIntMethod(LoadDex("Fibonacci"), "Fibonacci", "fibonacci", "(I)I", 55,
Brian Carlstrombffb1552011-08-25 12:23:53 -0700164 10);
buzbeec143c552011-08-20 17:38:58 -0700165}
buzbee3ea4ec52011-08-22 17:37:19 -0700166
buzbeee1931742011-08-28 21:15:53 -0700167TEST_F(CompilerTest, StaticFieldTest) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700168 AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "staticFieldTest", "(I)I", 1404,
buzbeee1931742011-08-28 21:15:53 -0700169 404);
170}
171
buzbee3ea4ec52011-08-22 17:37:19 -0700172TEST_F(CompilerTest, UnopTest) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700173 AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "unopTest", "(I)I", 37,
Brian Carlstrombffb1552011-08-25 12:23:53 -0700174 38);
buzbee3ea4ec52011-08-22 17:37:19 -0700175}
176
buzbee3ea4ec52011-08-22 17:37:19 -0700177TEST_F(CompilerTest, ShiftTest1) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700178 AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "shiftTest1", "()I", 0);
buzbee3ea4ec52011-08-22 17:37:19 -0700179}
buzbeec143c552011-08-20 17:38:58 -0700180
buzbee3ea4ec52011-08-22 17:37:19 -0700181TEST_F(CompilerTest, ShiftTest2) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700182 AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "shiftTest2", "()I", 0);
buzbee3ea4ec52011-08-22 17:37:19 -0700183}
buzbee3ea4ec52011-08-22 17:37:19 -0700184
185TEST_F(CompilerTest, UnsignedShiftTest) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700186 AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "unsignedShiftTest", "()I", 0);
buzbee3ea4ec52011-08-22 17:37:19 -0700187}
188
buzbee3ea4ec52011-08-22 17:37:19 -0700189TEST_F(CompilerTest, ConvTest) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700190 AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "convTest", "()I", 0);
buzbee3ea4ec52011-08-22 17:37:19 -0700191}
buzbee3ea4ec52011-08-22 17:37:19 -0700192
193TEST_F(CompilerTest, CharSubTest) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700194 AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "charSubTest", "()I", 0);
buzbee3ea4ec52011-08-22 17:37:19 -0700195}
196
buzbee3ea4ec52011-08-22 17:37:19 -0700197TEST_F(CompilerTest, IntOperTest) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700198 AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "intOperTest", "(II)I", 0,
Brian Carlstrombffb1552011-08-25 12:23:53 -0700199 70000, -3);
buzbee3ea4ec52011-08-22 17:37:19 -0700200}
buzbee3ea4ec52011-08-22 17:37:19 -0700201
buzbee3ea4ec52011-08-22 17:37:19 -0700202TEST_F(CompilerTest, Lit16Test) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700203 AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "lit16Test", "(I)I", 0,
Brian Carlstrombffb1552011-08-25 12:23:53 -0700204 77777);
buzbee3ea4ec52011-08-22 17:37:19 -0700205}
buzbee3ea4ec52011-08-22 17:37:19 -0700206
buzbee3ea4ec52011-08-22 17:37:19 -0700207TEST_F(CompilerTest, Lit8Test) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700208 AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "lit8Test", "(I)I", 0,
Brian Carlstrombffb1552011-08-25 12:23:53 -0700209 -55555);
buzbee3ea4ec52011-08-22 17:37:19 -0700210}
buzbee3ea4ec52011-08-22 17:37:19 -0700211
buzbee3ea4ec52011-08-22 17:37:19 -0700212TEST_F(CompilerTest, IntShiftTest) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700213 AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "intShiftTest", "(II)I", 0,
Brian Carlstrombffb1552011-08-25 12:23:53 -0700214 0xff00aa01, 8);
buzbee3ea4ec52011-08-22 17:37:19 -0700215}
buzbee3ea4ec52011-08-22 17:37:19 -0700216
buzbee3ea4ec52011-08-22 17:37:19 -0700217TEST_F(CompilerTest, LongOperTest) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700218 AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "longOperTest", "(JJ)I", 0,
buzbee439c4fa2011-08-27 15:59:07 -0700219 70000000000LL, -3LL);
buzbee3ea4ec52011-08-22 17:37:19 -0700220}
buzbee3ea4ec52011-08-22 17:37:19 -0700221
buzbee3ea4ec52011-08-22 17:37:19 -0700222TEST_F(CompilerTest, LongShiftTest) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700223 AssertStaticLongMethod(LoadDex("IntMath"), "IntMath", "longShiftTest", "(JI)J",
buzbee7b1b86d2011-08-26 18:59:10 -0700224 0x96deff00aa010000LL, 0xd5aa96deff00aa01LL, 16);
buzbee3ea4ec52011-08-22 17:37:19 -0700225}
buzbee3ea4ec52011-08-22 17:37:19 -0700226
buzbee9e0f9b02011-08-24 15:32:46 -0700227TEST_F(CompilerTest, SwitchTest1) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700228 AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "switchTest", "(I)I", 1234,
Brian Carlstrombffb1552011-08-25 12:23:53 -0700229 1);
buzbee9e0f9b02011-08-24 15:32:46 -0700230}
231
232TEST_F(CompilerTest, IntCompare) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700233 AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "testIntCompare", "(IIII)I", 1111,
Brian Carlstrombffb1552011-08-25 12:23:53 -0700234 -5, 4, 4, 0);
buzbee9e0f9b02011-08-24 15:32:46 -0700235}
236
237TEST_F(CompilerTest, LongCompare) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700238 AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "testLongCompare", "(JJJJ)I", 2222,
Brian Carlstrombffb1552011-08-25 12:23:53 -0700239 -5LL, -4294967287LL, 4LL, 8LL);
buzbee9e0f9b02011-08-24 15:32:46 -0700240}
241
242TEST_F(CompilerTest, FloatCompare) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700243 AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "testFloatCompare", "(FFFF)I", 3333,
Brian Carlstrombffb1552011-08-25 12:23:53 -0700244 -5.0f, 4.0f, 4.0f,
245 (1.0f/0.0f) / (1.0f/0.0f));
buzbee9e0f9b02011-08-24 15:32:46 -0700246}
247
248TEST_F(CompilerTest, DoubleCompare) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700249 AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "testDoubleCompare", "(DDDD)I", 4444,
Brian Carlstrombffb1552011-08-25 12:23:53 -0700250 -5.0, 4.0, 4.0,
251 (1.0/0.0) / (1.0/0.0));
buzbee9e0f9b02011-08-24 15:32:46 -0700252}
253
buzbeec5ef0462011-08-25 18:44:49 -0700254TEST_F(CompilerTest, RecursiveFibonacci) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700255 AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "fibonacci", "(I)I", 55,
buzbeec5ef0462011-08-25 18:44:49 -0700256 10);
257}
buzbeec5ef0462011-08-25 18:44:49 -0700258
buzbee7b1b86d2011-08-26 18:59:10 -0700259#if 0 // Need to complete try/catch block handling
260TEST_F(CompilerTest, ThrowAndCatch) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700261 AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "throwAndCatch", "()I", 4);
buzbee7b1b86d2011-08-26 18:59:10 -0700262}
263#endif
264
265TEST_F(CompilerTest, ManyArgs) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700266 AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "manyArgs",
buzbee7b1b86d2011-08-26 18:59:10 -0700267 "(IJIJIJIIDFDSICIIBZIIJJIIIII)I", -1,
268 0, 1LL, 2, 3LL, 4, 5LL, 6, 7, 8.0, 9.0f, 10.0,
269 (short)11, 12, (char)13, 14, 15, (int8_t)-16, true, 18,
270 19, 20LL, 21LL, 22, 23, 24, 25, 26);
271}
272
buzbee7b1b86d2011-08-26 18:59:10 -0700273TEST_F(CompilerTest, VirtualCall) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700274 CompileDirectMethod(NULL, "java.lang.Object", "<init>", "()V");
275 const ClassLoader* class_loader = LoadDex("IntMath");
276 CompileDirectMethod(class_loader, "IntMath", "<init>", "()V");
277 CompileVirtualMethod(class_loader, "IntMath", "virtualCall", "(I)I");
278 AssertStaticIntMethod(class_loader, "IntMath", "staticCall", "(I)I", 6,
buzbee7b1b86d2011-08-26 18:59:10 -0700279 3);
280}
buzbee7b1b86d2011-08-26 18:59:10 -0700281
buzbeedd3efae2011-08-28 14:39:07 -0700282TEST_F(CompilerTest, TestIGetPut) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700283 CompileDirectMethod(NULL, "java.lang.Object", "<init>", "()V");
284 const ClassLoader* class_loader = LoadDex("IntMath");
285 CompileDirectMethod(class_loader, "IntMath", "<init>", "(I)V");
286 CompileDirectMethod(class_loader, "IntMath", "<init>", "()V");
287 CompileVirtualMethod(class_loader, "IntMath", "getFoo", "()I");
288 CompileVirtualMethod(class_loader, "IntMath", "setFoo", "(I)V");
289 AssertStaticIntMethod(class_loader, "IntMath", "testIGetPut", "(I)I", 333,
buzbeedd3efae2011-08-28 14:39:07 -0700290 111);
291}
292
buzbeec143c552011-08-20 17:38:58 -0700293} // namespace art