blob: 76a39a43f37669a24a2e77da5906ce7291748d48 [file] [log] [blame]
Elliott Hughes2faa5f12012-01-30 14:42:07 -08001/*
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 */
buzbeec143c552011-08-20 17:38:58 -070016
Elliott Hughes90a33692011-08-30 13:27:07 -070017#include "compiler.h"
18
19#include <stdint.h>
20#include <stdio.h>
21
22#include "UniquePtr.h"
buzbeec143c552011-08-20 17:38:58 -070023#include "class_linker.h"
24#include "common_test.h"
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -070025#include "dex_cache.h"
buzbeec143c552011-08-20 17:38:58 -070026#include "dex_file.h"
27#include "heap.h"
28#include "object.h"
buzbeec143c552011-08-20 17:38:58 -070029
30namespace art {
31
32class CompilerTest : public CommonTest {
Brian Carlstrombffb1552011-08-25 12:23:53 -070033 protected:
Brian Carlstrom8a487412011-08-29 20:08:52 -070034
Elliott Hughes1240dad2011-09-09 16:24:50 -070035 void CompileAll(const ClassLoader* class_loader) {
Jesse Wilson254db0f2011-11-16 16:44:11 -050036 compiler_->CompileAll(class_loader, ClassLoader::GetCompileTimeClassPath(class_loader));
Elliott Hughes1240dad2011-09-09 16:24:50 -070037 MakeAllExecutable(class_loader);
38 }
39
40 void EnsureCompiled(const ClassLoader* class_loader,
Shih-wei Liao303b01e2011-09-14 00:46:13 -070041 const char* class_name, const char* method, const char* signature, bool is_virtual) {
Elliott Hughes1240dad2011-09-09 16:24:50 -070042 CompileAll(class_loader);
Ian Rogersa0841a82011-09-22 14:16:31 -070043 runtime_->Start();
Elliott Hughes1240dad2011-09-09 16:24:50 -070044 env_ = Thread::Current()->GetJniEnv();
45 class_ = env_->FindClass(class_name);
46 CHECK(class_ != NULL) << "Class not found: " << class_name;
Shih-wei Liao303b01e2011-09-14 00:46:13 -070047 if (is_virtual) {
48 mid_ = env_->GetMethodID(class_, method, signature);
49 } else {
50 mid_ = env_->GetStaticMethodID(class_, method, signature);
51 }
Elliott Hughes1240dad2011-09-09 16:24:50 -070052 CHECK(mid_ != NULL) << "Method not found: " << class_name << "." << method << signature;
53 }
54
55 void MakeAllExecutable(const ClassLoader* class_loader) {
Brian Carlstromaded5f72011-10-07 17:15:04 -070056 const std::vector<const DexFile*>& class_path
57 = ClassLoader::GetCompileTimeClassPath(class_loader);
Elliott Hughes1240dad2011-09-09 16:24:50 -070058 for (size_t i = 0; i != class_path.size(); ++i) {
59 const DexFile* dex_file = class_path[i];
60 CHECK(dex_file != NULL);
61 MakeDexFileExecutable(class_loader, *dex_file);
62 }
63 }
64
65 void MakeDexFileExecutable(const ClassLoader* class_loader, const DexFile& dex_file) {
66 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
67 for (size_t i = 0; i < dex_file.NumClassDefs(); i++) {
68 const DexFile::ClassDef& class_def = dex_file.GetClassDef(i);
69 const char* descriptor = dex_file.GetClassDescriptor(class_def);
70 Class* c = class_linker->FindClass(descriptor, class_loader);
71 CHECK(c != NULL);
72 for (size_t i = 0; i < c->NumDirectMethods(); i++) {
Brian Carlstrom3320cf42011-10-04 14:58:28 -070073 MakeExecutable(c->GetDirectMethod(i));
Elliott Hughes1240dad2011-09-09 16:24:50 -070074 }
75 for (size_t i = 0; i < c->NumVirtualMethods(); i++) {
Brian Carlstrom3320cf42011-10-04 14:58:28 -070076 MakeExecutable(c->GetVirtualMethod(i));
Elliott Hughes1240dad2011-09-09 16:24:50 -070077 }
78 }
79 }
80
Elliott Hughes1240dad2011-09-09 16:24:50 -070081 JNIEnv* env_;
82 jclass class_;
83 jmethodID mid_;
buzbeec143c552011-08-20 17:38:58 -070084};
85
Brian Carlstrom7540ff42011-09-04 16:38:46 -070086// Disabled due to 10 second runtime on host
Elliott Hughes1240dad2011-09-09 16:24:50 -070087TEST_F(CompilerTest, DISABLED_LARGE_CompileDexLibCore) {
88 CompileAll(NULL);
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -070089
90 // All libcore references should resolve
91 const DexFile* dex = java_lang_dex_file_.get();
92 DexCache* dex_cache = class_linker_->FindDexCache(*dex);
93 EXPECT_EQ(dex->NumStringIds(), dex_cache->NumStrings());
94 for (size_t i = 0; i < dex_cache->NumStrings(); i++) {
Elliott Hughescf4c6c42011-09-01 15:16:42 -070095 const String* string = dex_cache->GetResolvedString(i);
Brian Carlstrom7540ff42011-09-04 16:38:46 -070096 EXPECT_TRUE(string != NULL) << "string_idx=" << i;
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -070097 }
Brian Carlstrom1caa2c22011-08-28 13:02:33 -070098 EXPECT_EQ(dex->NumTypeIds(), dex_cache->NumResolvedTypes());
99 for (size_t i = 0; i < dex_cache->NumResolvedTypes(); i++) {
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700100 Class* type = dex_cache->GetResolvedType(i);
Brian Carlstrom7540ff42011-09-04 16:38:46 -0700101 EXPECT_TRUE(type != NULL) << "type_idx=" << i
102 << " " << dex->GetTypeDescriptor(dex->GetTypeId(i));
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700103 }
Brian Carlstrom1caa2c22011-08-28 13:02:33 -0700104 EXPECT_EQ(dex->NumMethodIds(), dex_cache->NumResolvedMethods());
105 for (size_t i = 0; i < dex_cache->NumResolvedMethods(); i++) {
Brian Carlstrom20cfffa2011-08-26 02:31:27 -0700106 Method* method = dex_cache->GetResolvedMethod(i);
Brian Carlstrom7540ff42011-09-04 16:38:46 -0700107 EXPECT_TRUE(method != NULL) << "method_idx=" << i
Brian Carlstrom6b4ef022011-10-23 14:59:04 -0700108 << " " << dex->GetMethodDeclaringClassDescriptor(dex->GetMethodId(i))
Brian Carlstrom7540ff42011-09-04 16:38:46 -0700109 << " " << dex->GetMethodName(dex->GetMethodId(i));
Shih-wei Liaoc486c112011-09-13 16:43:52 -0700110 EXPECT_TRUE(method->GetCode() != NULL) << "method_idx=" << i
111 << " "
Brian Carlstrom6b4ef022011-10-23 14:59:04 -0700112 << dex->GetMethodDeclaringClassDescriptor(dex->GetMethodId(i))
Shih-wei Liaoc486c112011-09-13 16:43:52 -0700113 << " " << dex->GetMethodName(dex->GetMethodId(i));
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700114 }
Brian Carlstrom1caa2c22011-08-28 13:02:33 -0700115 EXPECT_EQ(dex->NumFieldIds(), dex_cache->NumResolvedFields());
116 for (size_t i = 0; i < dex_cache->NumResolvedFields(); i++) {
Brian Carlstrom20cfffa2011-08-26 02:31:27 -0700117 Field* field = dex_cache->GetResolvedField(i);
Brian Carlstrom7540ff42011-09-04 16:38:46 -0700118 EXPECT_TRUE(field != NULL) << "field_idx=" << i
Brian Carlstrom6b4ef022011-10-23 14:59:04 -0700119 << " " << dex->GetFieldDeclaringClassDescriptor(dex->GetFieldId(i))
Brian Carlstrom7540ff42011-09-04 16:38:46 -0700120 << " " << dex->GetFieldName(dex->GetFieldId(i));
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700121 }
122
Brian Carlstrom83db7722011-08-26 17:32:56 -0700123 // TODO check Class::IsVerified for all classes
124
125 // TODO: check that all Method::GetCode() values are non-null
126
Brian Carlstrom9cc262e2011-08-28 12:45:30 -0700127 EXPECT_EQ(dex->NumMethodIds(), dex_cache->NumCodeAndDirectMethods());
128 CodeAndDirectMethods* code_and_direct_methods = dex_cache->GetCodeAndDirectMethods();
129 for (size_t i = 0; i < dex_cache->NumCodeAndDirectMethods(); i++) {
Brian Carlstrom83db7722011-08-26 17:32:56 -0700130 Method* method = dex_cache->GetResolvedMethod(i);
Brian Carlstrom7540ff42011-09-04 16:38:46 -0700131 if (method->IsDirect()) {
132 EXPECT_EQ(method->GetCode(), code_and_direct_methods->GetResolvedCode(i));
133 EXPECT_EQ(method, code_and_direct_methods->GetResolvedMethod(i));
134 } else {
135 EXPECT_EQ(0U, code_and_direct_methods->GetResolvedCode(i));
136 EXPECT_TRUE(code_and_direct_methods->GetResolvedMethod(i) == NULL);
137 }
Brian Carlstrom83db7722011-08-26 17:32:56 -0700138 }
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700139}
140
Ian Rogersa0841a82011-09-22 14:16:31 -0700141TEST_F(CompilerTest, AbstractMethodErrorStub) {
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700142 CompileDirectMethod(NULL, "java.lang.Object", "<init>", "()V");
143
Brian Carlstrom40381fb2011-10-19 14:13:40 -0700144 SirtRef<ClassLoader> class_loader(LoadDex("AbstractMethod"));
145 ASSERT_TRUE(class_loader.get() != NULL);
146 EnsureCompiled(class_loader.get(), "AbstractClass", "foo", "()V", true);
Shih-wei Liao303b01e2011-09-14 00:46:13 -0700147
Ian Rogersa0841a82011-09-22 14:16:31 -0700148 // Create a jobj_ of ConcreteClass, NOT AbstractClass.
149 jclass c_class = env_->FindClass("ConcreteClass");
150 jmethodID constructor = env_->GetMethodID(c_class, "<init>", "()V");
151 jobject jobj_ = env_->NewObject(c_class, constructor);
Shih-wei Liao303b01e2011-09-14 00:46:13 -0700152 ASSERT_TRUE(jobj_ != NULL);
153
154#if defined(__arm__)
Brian Carlstrom40381fb2011-10-19 14:13:40 -0700155 Class* jlame = class_linker_->FindClass("Ljava/lang/AbstractMethodError;", class_loader.get());
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700156 // Force non-virtual call to AbstractClass foo, will throw AbstractMethodError exception.
Shih-wei Liao303b01e2011-09-14 00:46:13 -0700157 env_->CallNonvirtualVoidMethod(jobj_, class_, mid_);
Ian Rogersa0841a82011-09-22 14:16:31 -0700158 EXPECT_TRUE(Thread::Current()->IsExceptionPending());
159 EXPECT_TRUE(Thread::Current()->GetException()->InstanceOf(jlame));
160 Thread::Current()->ClearException();
Shih-wei Liao303b01e2011-09-14 00:46:13 -0700161#endif // __arm__
162}
163
buzbee2a475e72011-09-07 17:19:17 -0700164// TODO: need check-cast test (when stub complete & we can throw/catch
165
buzbeec143c552011-08-20 17:38:58 -0700166} // namespace art