compiler_driver_test.cc revision 700a402244a1a423da4f3ba8032459f4b65fa18f
113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi/* 213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi * Copyright (C) 2011 The Android Open Source Project 313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi * 413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi * Licensed under the Apache License, Version 2.0 (the "License"); 513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi * you may not use this file except in compliance with the License. 613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi * You may obtain a copy of the License at 713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi * 813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi * http://www.apache.org/licenses/LICENSE-2.0 913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi * 1013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi * Unless required by applicable law or agreed to in writing, software 1113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi * distributed under the License is distributed on an "AS IS" BASIS, 1213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi * See the License for the specific language governing permissions and 1413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi * limitations under the License. 1513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi */ 1613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi 17bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi#include "driver/compiler_driver.h" 18bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi 19bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi#include <stdint.h> 206b1182bd1c2354ae8d8579b5a2941a21b42540a9Dongwon Kang#include <stdio.h> 216b1182bd1c2354ae8d8579b5a2941a21b42540a9Dongwon Kang#include <memory> 226b1182bd1c2354ae8d8579b5a2941a21b42540a9Dongwon Kang 234ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi#include "class_linker.h" 244ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi#include "common_compiler_test.h" 254ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi#include "dex_file.h" 264ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi#include "gc/heap.h" 274ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi#include "mirror/art_method-inl.h" 284ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi#include "mirror/class.h" 294ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi#include "mirror/class-inl.h" 3013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi#include "mirror/dex_cache-inl.h" 3113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi#include "mirror/object_array-inl.h" 3213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi#include "mirror/object-inl.h" 3313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi#include "handle_scope-inl.h" 34bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi 35bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivinamespace art { 360f92f48017588949daf7d24a339423e149bb2555Glenn Kasten 37bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Triviclass CompilerDriverTest : public CommonCompilerTest { 38bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi protected: 39bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi void CompileAll(jobject class_loader) LOCKS_EXCLUDED(Locks::mutator_lock_) { 40bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi TimingLogger timings("CompilerDriverTest::CompileAll", false, false); 41bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi timings.StartSplit("CompileAll"); 427f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi compiler_driver_->CompileAll(class_loader, 437f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi Runtime::Current()->GetCompileTimeClassPath(class_loader), 440f92f48017588949daf7d24a339423e149bb2555Glenn Kasten &timings); 457f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi MakeAllExecutable(class_loader); 467f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi timings.EndSplit(); 477f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi } 487f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi 497349b2e742b2cedc6d149fac62ed661ad7d47decGlenn Kasten void EnsureCompiled(jobject class_loader, const char* class_name, const char* method, 5013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi const char* signature, bool is_virtual) 5113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi LOCKS_EXCLUDED(Locks::mutator_lock_) { 5213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi CompileAll(class_loader); 5313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi Thread::Current()->TransitionFromSuspendedToRunnable(); 549bf773df2b8a0cf788f394c326960bc3a5af7c60Chih-Hung Hsieh bool started = runtime_->Start(); 5513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi CHECK(started); 5613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi env_ = Thread::Current()->GetJniEnv(); 57e6ded5c61944a87fa9e472dec3a6929855d42aebJean-Michel Trivi class_ = env_->FindClass(class_name); 58e6ded5c61944a87fa9e472dec3a6929855d42aebJean-Michel Trivi CHECK(class_ != NULL) << "Class not found: " << class_name; 5913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi if (is_virtual) { 6013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi mid_ = env_->GetMethodID(class_, method, signature); 615050a75e342ce45794d56666cddde3d46472acc7Jean-Michel Trivi } else { 6213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi mid_ = env_->GetStaticMethodID(class_, method, signature); 6391540f92d7f1bcda423859af6bd82df083c2afabGlenn Kasten } 647f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi CHECK(mid_ != NULL) << "Method not found: " << class_name << "." << method << signature; 657f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi } 667f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi 677f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi void MakeAllExecutable(jobject class_loader) { 687f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi const std::vector<const DexFile*>& class_path 6913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi = Runtime::Current()->GetCompileTimeClassPath(class_loader); 7013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi for (size_t i = 0; i != class_path.size(); ++i) { 7113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi const DexFile* dex_file = class_path[i]; 727f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi CHECK(dex_file != NULL); 737f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi MakeDexFileExecutable(class_loader, *dex_file); 7454cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi } 7513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi } 7613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi 7713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi void MakeDexFileExecutable(jobject class_loader, const DexFile& dex_file) { 7813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 7913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi for (size_t i = 0; i < dex_file.NumClassDefs(); i++) { 807349b2e742b2cedc6d149fac62ed661ad7d47decGlenn Kasten const DexFile::ClassDef& class_def = dex_file.GetClassDef(i); 8113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi const char* descriptor = dex_file.GetClassDescriptor(class_def); 8213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi ScopedObjectAccess soa(Thread::Current()); 8313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi StackHandleScope<1> hs(soa.Self()); 8413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi Handle<mirror::ClassLoader> loader( 8513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi hs.NewHandle(soa.Decode<mirror::ClassLoader*>(class_loader))); 8613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi mirror::Class* c = class_linker->FindClass(soa.Self(), descriptor, loader); 8713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi CHECK(c != NULL); 8813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi for (size_t i = 0; i < c->NumDirectMethods(); i++) { 8913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi MakeExecutable(c->GetDirectMethod(i)); 9013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi } 9113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi for (size_t i = 0; i < c->NumVirtualMethods(); i++) { 9213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi MakeExecutable(c->GetVirtualMethod(i)); 9313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi } 9454cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi } 9513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi } 9654cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi 9713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi JNIEnv* env_; 9813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi jclass class_; 9913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi jmethodID mid_; 100e6ded5c61944a87fa9e472dec3a6929855d42aebJean-Michel Trivi}; 1019fc34129185026cefe3760a714990879435b9449Dongwon Kang 102e6ded5c61944a87fa9e472dec3a6929855d42aebJean-Michel Trivi// Disabled due to 10 second runtime on host 103e6ded5c61944a87fa9e472dec3a6929855d42aebJean-Michel TriviTEST_F(CompilerDriverTest, DISABLED_LARGE_CompileDexLibCore) { 10413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi CompileAll(NULL); 10513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi 10613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi // All libcore references should resolve 1075050a75e342ce45794d56666cddde3d46472acc7Jean-Michel Trivi ScopedObjectAccess soa(Thread::Current()); 10813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi const DexFile* dex = java_lang_dex_file_; 10913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi mirror::DexCache* dex_cache = class_linker_->FindDexCache(*dex); 11013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi EXPECT_EQ(dex->NumStringIds(), dex_cache->NumStrings()); 111e6ded5c61944a87fa9e472dec3a6929855d42aebJean-Michel Trivi for (size_t i = 0; i < dex_cache->NumStrings(); i++) { 112e6ded5c61944a87fa9e472dec3a6929855d42aebJean-Michel Trivi const mirror::String* string = dex_cache->GetResolvedString(i); 113e6ded5c61944a87fa9e472dec3a6929855d42aebJean-Michel Trivi EXPECT_TRUE(string != NULL) << "string_idx=" << i; 11413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi } 11513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi EXPECT_EQ(dex->NumTypeIds(), dex_cache->NumResolvedTypes()); 11613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi for (size_t i = 0; i < dex_cache->NumResolvedTypes(); i++) { 11713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi mirror::Class* type = dex_cache->GetResolvedType(i); 1185050a75e342ce45794d56666cddde3d46472acc7Jean-Michel Trivi EXPECT_TRUE(type != NULL) << "type_idx=" << i 1195050a75e342ce45794d56666cddde3d46472acc7Jean-Michel Trivi << " " << dex->GetTypeDescriptor(dex->GetTypeId(i)); 1205050a75e342ce45794d56666cddde3d46472acc7Jean-Michel Trivi } 1215050a75e342ce45794d56666cddde3d46472acc7Jean-Michel Trivi EXPECT_EQ(dex->NumMethodIds(), dex_cache->NumResolvedMethods()); 12213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi for (size_t i = 0; i < dex_cache->NumResolvedMethods(); i++) { 1237f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi mirror::ArtMethod* method = dex_cache->GetResolvedMethod(i); 1247f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi EXPECT_TRUE(method != NULL) << "method_idx=" << i 1257f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi << " " << dex->GetMethodDeclaringClassDescriptor(dex->GetMethodId(i)) 12691540f92d7f1bcda423859af6bd82df083c2afabGlenn Kasten << " " << dex->GetMethodName(dex->GetMethodId(i)); 12754cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi EXPECT_TRUE(method->GetEntryPointFromQuickCompiledCode() != NULL) << "method_idx=" << i 1287f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi << " " 1297349b2e742b2cedc6d149fac62ed661ad7d47decGlenn Kasten << dex->GetMethodDeclaringClassDescriptor(dex->GetMethodId(i)) 1307349b2e742b2cedc6d149fac62ed661ad7d47decGlenn Kasten << " " << dex->GetMethodName(dex->GetMethodId(i)); 131bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi EXPECT_TRUE(method->GetEntryPointFromPortableCompiledCode() != NULL) << "method_idx=" << i 13213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi << " " 1334ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi << dex->GetMethodDeclaringClassDescriptor(dex->GetMethodId(i)) 1345050a75e342ce45794d56666cddde3d46472acc7Jean-Michel Trivi << " " << dex->GetMethodName(dex->GetMethodId(i)); 13513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi } 13654cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi EXPECT_EQ(dex->NumFieldIds(), dex_cache->NumResolvedFields()); 13754cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi for (size_t i = 0; i < dex_cache->NumResolvedFields(); i++) { 13854cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi mirror::ArtField* field = dex_cache->GetResolvedField(i); 13954cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi EXPECT_TRUE(field != NULL) << "field_idx=" << i 1403597268c2bf4ff71521e3cbe522d7ee02c41f175Jean-Michel Trivi << " " << dex->GetFieldDeclaringClassDescriptor(dex->GetFieldId(i)) 1413597268c2bf4ff71521e3cbe522d7ee02c41f175Jean-Michel Trivi << " " << dex->GetFieldName(dex->GetFieldId(i)); 14213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi } 14313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi 14413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi // TODO check Class::IsVerified for all classes 14513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi 14613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi // TODO: check that all Method::GetCode() values are non-null 14713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi} 148bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi 149bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel TriviTEST_F(CompilerDriverTest, AbstractMethodErrorStub) { 150 TEST_DISABLED_FOR_PORTABLE(); 151 TEST_DISABLED_FOR_HEAP_REFERENCE_POISONING(); 152 jobject class_loader; 153 { 154 ScopedObjectAccess soa(Thread::Current()); 155 StackHandleScope<1> hs(soa.Self()); 156 auto null_loader(hs.NewHandle<mirror::ClassLoader>(nullptr)); 157 CompileVirtualMethod(null_loader, "java.lang.Class", "isFinalizable", "()Z"); 158 CompileDirectMethod(null_loader, "java.lang.Object", "<init>", "()V"); 159 class_loader = LoadDex("AbstractMethod"); 160 } 161 ASSERT_TRUE(class_loader != NULL); 162 EnsureCompiled(class_loader, "AbstractClass", "foo", "()V", true); 163 164 // Create a jobj_ of ConcreteClass, NOT AbstractClass. 165 jclass c_class = env_->FindClass("ConcreteClass"); 166 jmethodID constructor = env_->GetMethodID(c_class, "<init>", "()V"); 167 jobject jobj_ = env_->NewObject(c_class, constructor); 168 ASSERT_TRUE(jobj_ != NULL); 169 170 // Force non-virtual call to AbstractClass foo, will throw AbstractMethodError exception. 171 env_->CallNonvirtualVoidMethod(jobj_, class_, mid_); 172 EXPECT_EQ(env_->ExceptionCheck(), JNI_TRUE); 173 jthrowable exception = env_->ExceptionOccurred(); 174 env_->ExceptionClear(); 175 jclass jlame = env_->FindClass("java/lang/AbstractMethodError"); 176 EXPECT_TRUE(env_->IsInstanceOf(exception, jlame)); 177 Thread::Current()->ClearException(); 178} 179 180// TODO: need check-cast test (when stub complete & we can throw/catch 181 182} // namespace art 183