blob: 656c7d4780ea18b9c98a6699ca3b03932d1fc149 [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
Brian Carlstrom8a487412011-08-29 20:08:52 -070021 void AssertStaticIntMethod(const ClassLoader* class_loader,
22 const char* klass, const char* method, const char* signature,
Brian Carlstrombffb1552011-08-25 12:23:53 -070023 jint expected, ...) {
Brian Carlstrom8a487412011-08-29 20:08:52 -070024 CompileDirectMethod(class_loader, klass, method, signature);
Brian Carlstrombffb1552011-08-25 12:23:53 -070025 JNIEnv* env = Thread::Current()->GetJniEnv();
26 jclass c = env->FindClass(klass);
Brian Carlstrom8a487412011-08-29 20:08:52 -070027 CHECK(c != NULL) << "Class not found " << klass;
Brian Carlstrombffb1552011-08-25 12:23:53 -070028 jmethodID m = env->GetStaticMethodID(c, method, signature);
Brian Carlstrom8a487412011-08-29 20:08:52 -070029 CHECK(m != NULL) << "Method not found " << method;
Brian Carlstrombffb1552011-08-25 12:23:53 -070030#if defined(__arm__)
31 va_list args;
32 va_start(args, expected);
33 jint result = env->CallStaticIntMethodV(c, m, args);
34 va_end(args);
35 LOG(INFO) << klass << "." << method << "(...) result is " << result;
36 EXPECT_EQ(expected, result);
37#endif // __arm__
38 }
Brian Carlstrom8a487412011-08-29 20:08:52 -070039 void AssertStaticLongMethod(const ClassLoader* class_loader,
40 const char* klass, const char* method, const char* signature,
41 jlong expected, ...) {
42 CompileDirectMethod(class_loader, klass, method, signature);
buzbeebafc3422011-08-25 15:22:55 -070043 JNIEnv* env = Thread::Current()->GetJniEnv();
44 jclass c = env->FindClass(klass);
Brian Carlstrom8a487412011-08-29 20:08:52 -070045 CHECK(c != NULL) << "Class not found " << klass;
buzbeebafc3422011-08-25 15:22:55 -070046 jmethodID m = env->GetStaticMethodID(c, method, signature);
Brian Carlstrom8a487412011-08-29 20:08:52 -070047 CHECK(m != NULL) << "Method not found " << method;
buzbeebafc3422011-08-25 15:22:55 -070048#if defined(__arm__)
49 va_list args;
50 va_start(args, expected);
buzbeec5ef0462011-08-25 18:44:49 -070051 jlong result = env->CallStaticLongMethodV(c, m, args);
buzbeebafc3422011-08-25 15:22:55 -070052 va_end(args);
53 LOG(INFO) << klass << "." << method << "(...) result is " << result;
54 EXPECT_EQ(expected, result);
55#endif // __arm__
56 }
buzbeec143c552011-08-20 17:38:58 -070057};
58
Brian Carlstrom8a487412011-08-29 20:08:52 -070059// TODO renenable when compiler can handle libcore
60TEST_F(CompilerTest, DISABLED_CompileDexLibCore) {
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -070061 Compiler compiler;
Brian Carlstrom8a487412011-08-29 20:08:52 -070062 compiler.CompileAll(NULL);
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -070063
64 // All libcore references should resolve
65 const DexFile* dex = java_lang_dex_file_.get();
66 DexCache* dex_cache = class_linker_->FindDexCache(*dex);
67 EXPECT_EQ(dex->NumStringIds(), dex_cache->NumStrings());
68 for (size_t i = 0; i < dex_cache->NumStrings(); i++) {
Elliott Hughescf4c6c42011-09-01 15:16:42 -070069 const String* string = dex_cache->GetResolvedString(i);
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -070070 EXPECT_TRUE(string != NULL);
71 }
Brian Carlstrom1caa2c22011-08-28 13:02:33 -070072 EXPECT_EQ(dex->NumTypeIds(), dex_cache->NumResolvedTypes());
73 for (size_t i = 0; i < dex_cache->NumResolvedTypes(); i++) {
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -070074 Class* type = dex_cache->GetResolvedType(i);
75 EXPECT_TRUE(type != NULL);
76 }
Brian Carlstrom1caa2c22011-08-28 13:02:33 -070077 EXPECT_EQ(dex->NumMethodIds(), dex_cache->NumResolvedMethods());
78 for (size_t i = 0; i < dex_cache->NumResolvedMethods(); i++) {
Brian Carlstrom20cfffa2011-08-26 02:31:27 -070079 Method* method = dex_cache->GetResolvedMethod(i);
80 EXPECT_TRUE(method != NULL);
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -070081 }
Brian Carlstrom1caa2c22011-08-28 13:02:33 -070082 EXPECT_EQ(dex->NumFieldIds(), dex_cache->NumResolvedFields());
83 for (size_t i = 0; i < dex_cache->NumResolvedFields(); i++) {
Brian Carlstrom20cfffa2011-08-26 02:31:27 -070084 Field* field = dex_cache->GetResolvedField(i);
85 EXPECT_TRUE(field != NULL);
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -070086 }
87
Brian Carlstrom83db7722011-08-26 17:32:56 -070088 // TODO check Class::IsVerified for all classes
89
90 // TODO: check that all Method::GetCode() values are non-null
91
Brian Carlstrom9cc262e2011-08-28 12:45:30 -070092 EXPECT_EQ(dex->NumMethodIds(), dex_cache->NumCodeAndDirectMethods());
93 CodeAndDirectMethods* code_and_direct_methods = dex_cache->GetCodeAndDirectMethods();
94 for (size_t i = 0; i < dex_cache->NumCodeAndDirectMethods(); i++) {
Brian Carlstrom83db7722011-08-26 17:32:56 -070095 Method* method = dex_cache->GetResolvedMethod(i);
Brian Carlstrom9cc262e2011-08-28 12:45:30 -070096 EXPECT_EQ(method->GetCode(), code_and_direct_methods->GetResolvedCode(i));
97 EXPECT_EQ(method, code_and_direct_methods->GetResolvedMethod(i));
Brian Carlstrom83db7722011-08-26 17:32:56 -070098 }
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -070099}
100
buzbeec143c552011-08-20 17:38:58 -0700101TEST_F(CompilerTest, BasicCodegen) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700102 AssertStaticIntMethod(LoadDex("Fibonacci"), "Fibonacci", "fibonacci", "(I)I", 55,
Brian Carlstrombffb1552011-08-25 12:23:53 -0700103 10);
buzbeec143c552011-08-20 17:38:58 -0700104}
buzbee3ea4ec52011-08-22 17:37:19 -0700105
buzbee4a3164f2011-09-03 11:25:10 -0700106// TODO: Need invoke-interface test
107
108TEST_F(CompilerTest, SuperTest) {
109 CompileDirectMethod(NULL, "java.lang.Object", "<init>", "()V");
110 const ClassLoader* class_loader = LoadDex("IntMath");
111 CompileDirectMethod(class_loader, "IntMathBase", "<init>", "()V");
112 CompileVirtualMethod(class_loader, "IntMathBase", "tryThing", "()I");
113 CompileDirectMethod(class_loader, "IntMath", "<init>", "()V");
114 CompileVirtualMethod(class_loader, "IntMath", "tryThing", "()I");
115 AssertStaticIntMethod(class_loader, "IntMath", "superTest", "(I)I", 4175,
116 4141);
117}
118
buzbee1b4c8592011-08-31 10:43:51 -0700119TEST_F(CompilerTest, ConstStringTest) {
120 AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "constStringTest",
121 "(I)I", 2468, 1234);
122}
123
buzbee561227c2011-09-02 15:28:19 -0700124TEST_F(CompilerTest, ConstClassTest) {
125 AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "constClassTest",
126 "(I)I", 2222, 1111);
127}
128
buzbee1b4c8592011-08-31 10:43:51 -0700129TEST_F(CompilerTest, DISABLED_CatchTest) {
130 CompileDirectMethod(NULL, "java.lang.Object", "<init>", "()V");
131 CompileDirectMethod(NULL, "java.lang.NullPointerException", "<init>", "()V");
132 const ClassLoader* class_loader = LoadDex("IntMath");
133 CompileDirectMethod(class_loader, "IntMath", "throwNullPointerException", "()V");
134 AssertStaticIntMethod(class_loader, "IntMath", "catchBlock", "(I)I", 1579,
135 1000);
136}
137
buzbeee1931742011-08-28 21:15:53 -0700138TEST_F(CompilerTest, StaticFieldTest) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700139 AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "staticFieldTest", "(I)I", 1404,
buzbeee1931742011-08-28 21:15:53 -0700140 404);
141}
142
buzbee3ea4ec52011-08-22 17:37:19 -0700143TEST_F(CompilerTest, UnopTest) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700144 AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "unopTest", "(I)I", 37,
Brian Carlstrombffb1552011-08-25 12:23:53 -0700145 38);
buzbee3ea4ec52011-08-22 17:37:19 -0700146}
147
buzbee3ea4ec52011-08-22 17:37:19 -0700148TEST_F(CompilerTest, ShiftTest1) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700149 AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "shiftTest1", "()I", 0);
buzbee3ea4ec52011-08-22 17:37:19 -0700150}
buzbeec143c552011-08-20 17:38:58 -0700151
buzbee3ea4ec52011-08-22 17:37:19 -0700152TEST_F(CompilerTest, ShiftTest2) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700153 AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "shiftTest2", "()I", 0);
buzbee3ea4ec52011-08-22 17:37:19 -0700154}
buzbee3ea4ec52011-08-22 17:37:19 -0700155
156TEST_F(CompilerTest, UnsignedShiftTest) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700157 AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "unsignedShiftTest", "()I", 0);
buzbee3ea4ec52011-08-22 17:37:19 -0700158}
159
buzbee3ea4ec52011-08-22 17:37:19 -0700160TEST_F(CompilerTest, ConvTest) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700161 AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "convTest", "()I", 0);
buzbee3ea4ec52011-08-22 17:37:19 -0700162}
buzbee3ea4ec52011-08-22 17:37:19 -0700163
164TEST_F(CompilerTest, CharSubTest) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700165 AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "charSubTest", "()I", 0);
buzbee3ea4ec52011-08-22 17:37:19 -0700166}
167
buzbee3ea4ec52011-08-22 17:37:19 -0700168TEST_F(CompilerTest, IntOperTest) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700169 AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "intOperTest", "(II)I", 0,
Brian Carlstrombffb1552011-08-25 12:23:53 -0700170 70000, -3);
buzbee3ea4ec52011-08-22 17:37:19 -0700171}
buzbee3ea4ec52011-08-22 17:37:19 -0700172
buzbee3ea4ec52011-08-22 17:37:19 -0700173TEST_F(CompilerTest, Lit16Test) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700174 AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "lit16Test", "(I)I", 0,
Brian Carlstrombffb1552011-08-25 12:23:53 -0700175 77777);
buzbee3ea4ec52011-08-22 17:37:19 -0700176}
buzbee3ea4ec52011-08-22 17:37:19 -0700177
buzbee3ea4ec52011-08-22 17:37:19 -0700178TEST_F(CompilerTest, Lit8Test) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700179 AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "lit8Test", "(I)I", 0,
Brian Carlstrombffb1552011-08-25 12:23:53 -0700180 -55555);
buzbee3ea4ec52011-08-22 17:37:19 -0700181}
buzbee3ea4ec52011-08-22 17:37:19 -0700182
buzbee3ea4ec52011-08-22 17:37:19 -0700183TEST_F(CompilerTest, IntShiftTest) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700184 AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "intShiftTest", "(II)I", 0,
Brian Carlstrombffb1552011-08-25 12:23:53 -0700185 0xff00aa01, 8);
buzbee3ea4ec52011-08-22 17:37:19 -0700186}
buzbee3ea4ec52011-08-22 17:37:19 -0700187
buzbee3ea4ec52011-08-22 17:37:19 -0700188TEST_F(CompilerTest, LongOperTest) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700189 AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "longOperTest", "(JJ)I", 0,
buzbee439c4fa2011-08-27 15:59:07 -0700190 70000000000LL, -3LL);
buzbee3ea4ec52011-08-22 17:37:19 -0700191}
buzbee3ea4ec52011-08-22 17:37:19 -0700192
buzbee3ea4ec52011-08-22 17:37:19 -0700193TEST_F(CompilerTest, LongShiftTest) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700194 AssertStaticLongMethod(LoadDex("IntMath"), "IntMath", "longShiftTest", "(JI)J",
buzbee7b1b86d2011-08-26 18:59:10 -0700195 0x96deff00aa010000LL, 0xd5aa96deff00aa01LL, 16);
buzbee3ea4ec52011-08-22 17:37:19 -0700196}
buzbee3ea4ec52011-08-22 17:37:19 -0700197
buzbee9e0f9b02011-08-24 15:32:46 -0700198TEST_F(CompilerTest, SwitchTest1) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700199 AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "switchTest", "(I)I", 1234,
Brian Carlstrombffb1552011-08-25 12:23:53 -0700200 1);
buzbee9e0f9b02011-08-24 15:32:46 -0700201}
202
203TEST_F(CompilerTest, IntCompare) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700204 AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "testIntCompare", "(IIII)I", 1111,
Brian Carlstrombffb1552011-08-25 12:23:53 -0700205 -5, 4, 4, 0);
buzbee9e0f9b02011-08-24 15:32:46 -0700206}
207
208TEST_F(CompilerTest, LongCompare) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700209 AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "testLongCompare", "(JJJJ)I", 2222,
Brian Carlstrombffb1552011-08-25 12:23:53 -0700210 -5LL, -4294967287LL, 4LL, 8LL);
buzbee9e0f9b02011-08-24 15:32:46 -0700211}
212
213TEST_F(CompilerTest, FloatCompare) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700214 AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "testFloatCompare", "(FFFF)I", 3333,
Brian Carlstrombffb1552011-08-25 12:23:53 -0700215 -5.0f, 4.0f, 4.0f,
216 (1.0f/0.0f) / (1.0f/0.0f));
buzbee9e0f9b02011-08-24 15:32:46 -0700217}
218
219TEST_F(CompilerTest, DoubleCompare) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700220 AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "testDoubleCompare", "(DDDD)I", 4444,
Brian Carlstrombffb1552011-08-25 12:23:53 -0700221 -5.0, 4.0, 4.0,
222 (1.0/0.0) / (1.0/0.0));
buzbee9e0f9b02011-08-24 15:32:46 -0700223}
224
buzbeec5ef0462011-08-25 18:44:49 -0700225TEST_F(CompilerTest, RecursiveFibonacci) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700226 AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "fibonacci", "(I)I", 55,
buzbeec5ef0462011-08-25 18:44:49 -0700227 10);
228}
buzbeec5ef0462011-08-25 18:44:49 -0700229
buzbee7b1b86d2011-08-26 18:59:10 -0700230#if 0 // Need to complete try/catch block handling
231TEST_F(CompilerTest, ThrowAndCatch) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700232 AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "throwAndCatch", "()I", 4);
buzbee7b1b86d2011-08-26 18:59:10 -0700233}
234#endif
235
236TEST_F(CompilerTest, ManyArgs) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700237 AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "manyArgs",
buzbee7b1b86d2011-08-26 18:59:10 -0700238 "(IJIJIJIIDFDSICIIBZIIJJIIIII)I", -1,
239 0, 1LL, 2, 3LL, 4, 5LL, 6, 7, 8.0, 9.0f, 10.0,
240 (short)11, 12, (char)13, 14, 15, (int8_t)-16, true, 18,
241 19, 20LL, 21LL, 22, 23, 24, 25, 26);
242}
243
buzbee7b1b86d2011-08-26 18:59:10 -0700244TEST_F(CompilerTest, VirtualCall) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700245 CompileDirectMethod(NULL, "java.lang.Object", "<init>", "()V");
246 const ClassLoader* class_loader = LoadDex("IntMath");
buzbee4a3164f2011-09-03 11:25:10 -0700247 CompileDirectMethod(class_loader, "IntMathBase", "<init>", "()V");
Brian Carlstrom8a487412011-08-29 20:08:52 -0700248 CompileDirectMethod(class_loader, "IntMath", "<init>", "()V");
249 CompileVirtualMethod(class_loader, "IntMath", "virtualCall", "(I)I");
250 AssertStaticIntMethod(class_loader, "IntMath", "staticCall", "(I)I", 6,
buzbee7b1b86d2011-08-26 18:59:10 -0700251 3);
252}
buzbee7b1b86d2011-08-26 18:59:10 -0700253
buzbeedd3efae2011-08-28 14:39:07 -0700254TEST_F(CompilerTest, TestIGetPut) {
Brian Carlstrom8a487412011-08-29 20:08:52 -0700255 CompileDirectMethod(NULL, "java.lang.Object", "<init>", "()V");
256 const ClassLoader* class_loader = LoadDex("IntMath");
buzbee4a3164f2011-09-03 11:25:10 -0700257 CompileDirectMethod(class_loader, "IntMathBase", "<init>", "()V");
Brian Carlstrom8a487412011-08-29 20:08:52 -0700258 CompileDirectMethod(class_loader, "IntMath", "<init>", "(I)V");
259 CompileDirectMethod(class_loader, "IntMath", "<init>", "()V");
260 CompileVirtualMethod(class_loader, "IntMath", "getFoo", "()I");
261 CompileVirtualMethod(class_loader, "IntMath", "setFoo", "(I)V");
262 AssertStaticIntMethod(class_loader, "IntMath", "testIGetPut", "(I)I", 333,
buzbeedd3efae2011-08-28 14:39:07 -0700263 111);
264}
265
buzbee4a3164f2011-09-03 11:25:10 -0700266
buzbeec143c552011-08-20 17:38:58 -0700267} // namespace art