12faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes/* 22faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Copyright (C) 2011 The Android Open Source Project 32faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 42faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 52faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * you may not use this file except in compliance with the License. 62faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * You may obtain a copy of the License at 72faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 82faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 92faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 102faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Unless required by applicable law or agreed to in writing, software 112faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 122faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * See the License for the specific language governing permissions and 142faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * limitations under the License. 152faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes */ 16c143c55718342519db5398e41dda31422cf16c79buzbee 177940e44f4517de5e2634a7e07d58d0fb26160513Brian Carlstrom#include "driver/compiler_driver.h" 1890a3369d3b6238f1a4c9b19ca68978dab1c39bc4Elliott Hughes 192c64a837e62c2839521c89060b5bb0dcb237dddaVladimir Marko#include <limits> 2090a3369d3b6238f1a4c9b19ca68978dab1c39bc4Elliott Hughes#include <stdint.h> 2190a3369d3b6238f1a4c9b19ca68978dab1c39bc4Elliott Hughes#include <stdio.h> 22700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers#include <memory> 2390a3369d3b6238f1a4c9b19ca68978dab1c39bc4Elliott Hughes 24e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier#include "art_method-inl.h" 252c64a837e62c2839521c89060b5bb0dcb237dddaVladimir Marko#include "base/casts.h" 263481ba2c4e4f3aa80d8c6d50a9f85dacb56b508bVladimir Marko#include "class_linker-inl.h" 27a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom#include "common_compiler_test.h" 289e050df94df5c6736e1e24705194f62fbc119114Mathieu Chartier#include "compiler_callbacks.h" 299e734c7ab4599d7747a05db0dc73c7b668cb6683David Sehr#include "dex/dex_file.h" 309e734c7ab4599d7747a05db0dc73c7b668cb6683David Sehr#include "dex/dex_file_types.h" 311d54e73444e017d3a65234e0f193846f3e27472bIan Rogers#include "gc/heap.h" 328cf9cb386cd9286d67e879f1ee501ec00d72a4e1Andreas Gampe#include "handle_scope-inl.h" 338cf9cb386cd9286d67e879f1ee501ec00d72a4e1Andreas Gampe#include "jit/profile_compilation_info.h" 342dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/class-inl.h" 35e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers#include "mirror/class_loader.h" 3639ebcb800aabedd0ffa6aa4aeac8aa4194c66e61Ian Rogers#include "mirror/dex_cache-inl.h" 3704d7aa92bc5548bc4d272b9480614f06248194ccIan Rogers#include "mirror/object-inl.h" 388cf9cb386cd9286d67e879f1ee501ec00d72a4e1Andreas Gampe#include "mirror/object_array-inl.h" 390795f23920ee9aabf28e45c63cd592dcccf00216Mathieu Chartier#include "scoped_thread_state_change-inl.h" 40c143c55718342519db5398e41dda31422cf16c79buzbee 41c143c55718342519db5398e41dda31422cf16c79buzbeenamespace art { 42c143c55718342519db5398e41dda31422cf16c79buzbee 43a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstromclass CompilerDriverTest : public CommonCompilerTest { 44bffb15585b8fd43d3ca534ddbb85e7f591595951Brian Carlstrom protected: 4590443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier void CompileAll(jobject class_loader) REQUIRES(!Locks::mutator_lock_) { 465fe9af720048673e62ee29597a30bb9e54c903c5Ian Rogers TimingLogger timings("CompilerDriverTest::CompileAll", false, false); 47f5997b4d3f889569d5a2b724d83d764bfbb8d106Mathieu Chartier TimingLogger::ScopedTiming t(__FUNCTION__, &timings); 4872041a0dcb5b7c133b79a1d6783a23039f2136bdMathieu Chartier dex_files_ = GetDexFiles(class_loader); 4972041a0dcb5b7c133b79a1d6783a23039f2136bdMathieu Chartier compiler_driver_->SetDexFilesForOatFile(dex_files_);; 5072041a0dcb5b7c133b79a1d6783a23039f2136bdMathieu Chartier compiler_driver_->CompileAll(class_loader, dex_files_, &timings); 51f5997b4d3f889569d5a2b724d83d764bfbb8d106Mathieu Chartier t.NewTiming("MakeAllExecutable"); 521240dade91d6c4bbf4e367ca608fcdc15348da45Elliott Hughes MakeAllExecutable(class_loader); 531240dade91d6c4bbf4e367ca608fcdc15348da45Elliott Hughes } 541240dade91d6c4bbf4e367ca608fcdc15348da45Elliott Hughes 5500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers void EnsureCompiled(jobject class_loader, const char* class_name, const char* method, 5600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers const char* signature, bool is_virtual) 5790443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier REQUIRES(!Locks::mutator_lock_) { 581240dade91d6c4bbf4e367ca608fcdc15348da45Elliott Hughes CompileAll(class_loader); 5900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Thread::Current()->TransitionFromSuspendedToRunnable(); 60bd86bccf1b47f1151842152ee52cf5d46d6b34abBrian Carlstrom bool started = runtime_->Start(); 61bd86bccf1b47f1151842152ee52cf5d46d6b34abBrian Carlstrom CHECK(started); 621240dade91d6c4bbf4e367ca608fcdc15348da45Elliott Hughes env_ = Thread::Current()->GetJniEnv(); 631240dade91d6c4bbf4e367ca608fcdc15348da45Elliott Hughes class_ = env_->FindClass(class_name); 642cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier CHECK(class_ != nullptr) << "Class not found: " << class_name; 65303b01ed0d36017371e29b1f1e209dd19896ac9eShih-wei Liao if (is_virtual) { 66303b01ed0d36017371e29b1f1e209dd19896ac9eShih-wei Liao mid_ = env_->GetMethodID(class_, method, signature); 67303b01ed0d36017371e29b1f1e209dd19896ac9eShih-wei Liao } else { 68303b01ed0d36017371e29b1f1e209dd19896ac9eShih-wei Liao mid_ = env_->GetStaticMethodID(class_, method, signature); 69303b01ed0d36017371e29b1f1e209dd19896ac9eShih-wei Liao } 702cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier CHECK(mid_ != nullptr) << "Method not found: " << class_name << "." << method << signature; 711240dade91d6c4bbf4e367ca608fcdc15348da45Elliott Hughes } 721240dade91d6c4bbf4e367ca608fcdc15348da45Elliott Hughes 7300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers void MakeAllExecutable(jobject class_loader) { 7481c6f8db12b203878a7d72444ead2bc7cf5c47adAndreas Gampe const std::vector<const DexFile*> class_path = GetDexFiles(class_loader); 751240dade91d6c4bbf4e367ca608fcdc15348da45Elliott Hughes for (size_t i = 0; i != class_path.size(); ++i) { 761240dade91d6c4bbf4e367ca608fcdc15348da45Elliott Hughes const DexFile* dex_file = class_path[i]; 772cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier CHECK(dex_file != nullptr); 781240dade91d6c4bbf4e367ca608fcdc15348da45Elliott Hughes MakeDexFileExecutable(class_loader, *dex_file); 791240dade91d6c4bbf4e367ca608fcdc15348da45Elliott Hughes } 801240dade91d6c4bbf4e367ca608fcdc15348da45Elliott Hughes } 811240dade91d6c4bbf4e367ca608fcdc15348da45Elliott Hughes 8200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers void MakeDexFileExecutable(jobject class_loader, const DexFile& dex_file) { 831240dade91d6c4bbf4e367ca608fcdc15348da45Elliott Hughes ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 841240dade91d6c4bbf4e367ca608fcdc15348da45Elliott Hughes for (size_t i = 0; i < dex_file.NumClassDefs(); i++) { 851240dade91d6c4bbf4e367ca608fcdc15348da45Elliott Hughes const DexFile::ClassDef& class_def = dex_file.GetClassDef(i); 861240dade91d6c4bbf4e367ca608fcdc15348da45Elliott Hughes const char* descriptor = dex_file.GetClassDescriptor(class_def); 8700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(Thread::Current()); 88eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier StackHandleScope<1> hs(soa.Self()); 89eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier Handle<mirror::ClassLoader> loader( 900795f23920ee9aabf28e45c63cd592dcccf00216Mathieu Chartier hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader))); 919837939678bb5dcba178e5fb00ed59b5d14c8d9bIan Rogers mirror::Class* c = class_linker->FindClass(soa.Self(), descriptor, loader); 922cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier CHECK(c != nullptr); 93e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier const auto pointer_size = class_linker->GetImagePointerSize(); 94e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light for (auto& m : c->GetMethods(pointer_size)) { 95e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier MakeExecutable(&m); 961240dade91d6c4bbf4e367ca608fcdc15348da45Elliott Hughes } 971240dade91d6c4bbf4e367ca608fcdc15348da45Elliott Hughes } 981240dade91d6c4bbf4e367ca608fcdc15348da45Elliott Hughes } 991240dade91d6c4bbf4e367ca608fcdc15348da45Elliott Hughes 1001240dade91d6c4bbf4e367ca608fcdc15348da45Elliott Hughes JNIEnv* env_; 1011240dade91d6c4bbf4e367ca608fcdc15348da45Elliott Hughes jclass class_; 1021240dade91d6c4bbf4e367ca608fcdc15348da45Elliott Hughes jmethodID mid_; 10372041a0dcb5b7c133b79a1d6783a23039f2136bdMathieu Chartier std::vector<const DexFile*> dex_files_; 104c143c55718342519db5398e41dda31422cf16c79buzbee}; 105c143c55718342519db5398e41dda31422cf16c79buzbee 1067540ff4b6ad0ff5d8c5f60658b66155caf3a7cbcBrian Carlstrom// Disabled due to 10 second runtime on host 1078d6768d47b66a688d35399d524ad5a5450e9d9d4Vladimir Marko// TODO: Update the test for hash-based dex cache arrays. Bug: 30627598 1081212a022fa5f8ef9585d765b1809521812af882cIan RogersTEST_F(CompilerDriverTest, DISABLED_LARGE_CompileDexLibCore) { 1092cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier CompileAll(nullptr); 1109ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 1119ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom // All libcore references should resolve 11200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(Thread::Current()); 1132cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier ASSERT_TRUE(java_lang_dex_file_ != nullptr); 114fbef44de596d298dc6430f482dffc933a046dd28Richard Uhler const DexFile& dex = *java_lang_dex_file_; 11528357fab628bd9b91749988b554977398caf9963Mathieu Chartier ObjPtr<mirror::DexCache> dex_cache = class_linker_->FindDexCache(soa.Self(), dex); 116fbef44de596d298dc6430f482dffc933a046dd28Richard Uhler EXPECT_EQ(dex.NumStringIds(), dex_cache->NumStrings()); 1179ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom for (size_t i = 0; i < dex_cache->NumStrings(); i++) { 1188a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe const mirror::String* string = dex_cache->GetResolvedString(dex::StringIndex(i)); 1192cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier EXPECT_TRUE(string != nullptr) << "string_idx=" << i; 1209ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom } 121fbef44de596d298dc6430f482dffc933a046dd28Richard Uhler EXPECT_EQ(dex.NumTypeIds(), dex_cache->NumResolvedTypes()); 1221caa2c205e51dda670207828f25451fb7623cea6Brian Carlstrom for (size_t i = 0; i < dex_cache->NumResolvedTypes(); i++) { 123a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe mirror::Class* type = dex_cache->GetResolvedType(dex::TypeIndex(i)); 1242cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier EXPECT_TRUE(type != nullptr) << "type_idx=" << i 125a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe << " " << dex.GetTypeDescriptor(dex.GetTypeId(dex::TypeIndex(i))); 1269ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom } 12707bfbace6f835e6c748fd68ec7624992478b16c1Vladimir Marko EXPECT_TRUE(dex_cache->StaticMethodSize() == dex_cache->NumResolvedMethods() 12807bfbace6f835e6c748fd68ec7624992478b16c1Vladimir Marko || dex.NumMethodIds() == dex_cache->NumResolvedMethods()); 129e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier auto* cl = Runtime::Current()->GetClassLinker(); 130e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier auto pointer_size = cl->GetImagePointerSize(); 1311caa2c205e51dda670207828f25451fb7623cea6Brian Carlstrom for (size_t i = 0; i < dex_cache->NumResolvedMethods(); i++) { 13207bfbace6f835e6c748fd68ec7624992478b16c1Vladimir Marko // FIXME: This is outdated for hash-based method array. 133e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier ArtMethod* method = dex_cache->GetResolvedMethod(i, pointer_size); 1342cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier EXPECT_TRUE(method != nullptr) << "method_idx=" << i 135fbef44de596d298dc6430f482dffc933a046dd28Richard Uhler << " " << dex.GetMethodDeclaringClassDescriptor(dex.GetMethodId(i)) 136fbef44de596d298dc6430f482dffc933a046dd28Richard Uhler << " " << dex.GetMethodName(dex.GetMethodId(i)); 1372cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier EXPECT_TRUE(method->GetEntryPointFromQuickCompiledCode() != nullptr) << "method_idx=" << i 1382cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier << " " << dex.GetMethodDeclaringClassDescriptor(dex.GetMethodId(i)) << " " 1392cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier << dex.GetMethodName(dex.GetMethodId(i)); 1409ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom } 141f44d36c8423f81cbb5e9f55d8813e26ffa1a7f3bVladimir Marko EXPECT_TRUE(dex_cache->StaticArtFieldSize() == dex_cache->NumResolvedFields() 142f44d36c8423f81cbb5e9f55d8813e26ffa1a7f3bVladimir Marko || dex.NumFieldIds() == dex_cache->NumResolvedFields()); 1431caa2c205e51dda670207828f25451fb7623cea6Brian Carlstrom for (size_t i = 0; i < dex_cache->NumResolvedFields(); i++) { 14407bfbace6f835e6c748fd68ec7624992478b16c1Vladimir Marko // FIXME: This is outdated for hash-based field array. 145f44d36c8423f81cbb5e9f55d8813e26ffa1a7f3bVladimir Marko ArtField* field = dex_cache->GetResolvedField(i, cl->GetImagePointerSize()); 1462cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier EXPECT_TRUE(field != nullptr) << "field_idx=" << i 147fbef44de596d298dc6430f482dffc933a046dd28Richard Uhler << " " << dex.GetFieldDeclaringClassDescriptor(dex.GetFieldId(i)) 148fbef44de596d298dc6430f482dffc933a046dd28Richard Uhler << " " << dex.GetFieldName(dex.GetFieldId(i)); 1499ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom } 1509ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 15183db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom // TODO check Class::IsVerified for all classes 15283db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom 15383db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom // TODO: check that all Method::GetCode() values are non-null 1549ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom} 1559ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 1565dcf19d402b4ea7023ced2afa8d615576fe2784fYi KongTEST_F(CompilerDriverTest, AbstractMethodErrorStub) { 15700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers jobject class_loader; 15800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers { 15900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(Thread::Current()); 16000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers class_loader = LoadDex("AbstractMethod"); 16100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 1622cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier ASSERT_TRUE(class_loader != nullptr); 16300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers EnsureCompiled(class_loader, "AbstractClass", "foo", "()V", true); 164303b01ed0d36017371e29b1f1e209dd19896ac9eShih-wei Liao 165a0841a83323a82e3bed3d0b5f2e6ec3795f496beIan Rogers // Create a jobj_ of ConcreteClass, NOT AbstractClass. 166a0841a83323a82e3bed3d0b5f2e6ec3795f496beIan Rogers jclass c_class = env_->FindClass("ConcreteClass"); 167e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier 168a0841a83323a82e3bed3d0b5f2e6ec3795f496beIan Rogers jmethodID constructor = env_->GetMethodID(c_class, "<init>", "()V"); 169e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier 170a0841a83323a82e3bed3d0b5f2e6ec3795f496beIan Rogers jobject jobj_ = env_->NewObject(c_class, constructor); 1712cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier ASSERT_TRUE(jobj_ != nullptr); 172303b01ed0d36017371e29b1f1e209dd19896ac9eShih-wei Liao 1733320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom // Force non-virtual call to AbstractClass foo, will throw AbstractMethodError exception. 174303b01ed0d36017371e29b1f1e209dd19896ac9eShih-wei Liao env_->CallNonvirtualVoidMethod(jobj_, class_, mid_); 175e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier 17600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers EXPECT_EQ(env_->ExceptionCheck(), JNI_TRUE); 17700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers jthrowable exception = env_->ExceptionOccurred(); 17800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers env_->ExceptionClear(); 17900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers jclass jlame = env_->FindClass("java/lang/AbstractMethodError"); 18000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers EXPECT_TRUE(env_->IsInstanceOf(exception, jlame)); 181a309d76d4c9f4e5564b09708004bf4b2e3401bb3Serguei Katkov { 182a309d76d4c9f4e5564b09708004bf4b2e3401bb3Serguei Katkov ScopedObjectAccess soa(Thread::Current()); 183a309d76d4c9f4e5564b09708004bf4b2e3401bb3Serguei Katkov Thread::Current()->ClearException(); 184a309d76d4c9f4e5564b09708004bf4b2e3401bb3Serguei Katkov } 185303b01ed0d36017371e29b1f1e209dd19896ac9eShih-wei Liao} 186303b01ed0d36017371e29b1f1e209dd19896ac9eShih-wei Liao 18770bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampeclass CompilerDriverMethodsTest : public CompilerDriverTest { 18870bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe protected: 18970bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe std::unordered_set<std::string>* GetCompiledMethods() OVERRIDE { 19070bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe return new std::unordered_set<std::string>({ 19170bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe "byte StaticLeafMethods.identity(byte)", 19270bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe "int StaticLeafMethods.sum(int, int, int)", 19370bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe "double StaticLeafMethods.sum(double, double, double, double)" 19470bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe }); 19570bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe } 19670bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe}; 19770bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe 19870bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas GampeTEST_F(CompilerDriverMethodsTest, Selection) { 19970bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe Thread* self = Thread::Current(); 20070bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe jobject class_loader; 20170bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe { 20270bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe ScopedObjectAccess soa(self); 20370bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe class_loader = LoadDex("StaticLeafMethods"); 20470bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe } 20570bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe ASSERT_NE(class_loader, nullptr); 20670bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe 20770bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe // Need to enable dex-file writability. Methods rejected to be compiled will run through the 20870bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe // dex-to-dex compiler. 20970bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe for (const DexFile* dex_file : GetDexFiles(class_loader)) { 21070bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe ASSERT_TRUE(dex_file->EnableWrite()); 21170bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe } 21270bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe 21370bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe CompileAll(class_loader); 21470bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe 21570bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 21670bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe ScopedObjectAccess soa(self); 217ed15000a5099f5e230c8ded5ac75692bae272650Mathieu Chartier StackHandleScope<1> hs(self); 218c4f3925490a73da8dc74884a1deb965d4ecaf14eMathieu Chartier Handle<mirror::ClassLoader> h_loader( 219c4f3925490a73da8dc74884a1deb965d4ecaf14eMathieu Chartier hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader))); 22070bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe mirror::Class* klass = class_linker->FindClass(self, "LStaticLeafMethods;", h_loader); 22170bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe ASSERT_NE(klass, nullptr); 22270bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe 22370bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe std::unique_ptr<std::unordered_set<std::string>> expected(GetCompiledMethods()); 22470bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe 225e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier const auto pointer_size = class_linker->GetImagePointerSize(); 226e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier for (auto& m : klass->GetDirectMethods(pointer_size)) { 227709b070044354d9f47641f273edacaeeb0240ab7David Sehr std::string name = m.PrettyMethod(true); 228e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier const void* code = m.GetEntryPointFromQuickCompiledCodePtrSize(pointer_size); 22970bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe ASSERT_NE(code, nullptr); 23070bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe if (expected->find(name) != expected->end()) { 23170bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe expected->erase(name); 23270bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe EXPECT_FALSE(class_linker->IsQuickToInterpreterBridge(code)); 23370bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe } else { 23470bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe EXPECT_TRUE(class_linker->IsQuickToInterpreterBridge(code)); 23570bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe } 23670bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe } 23770bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe EXPECT_TRUE(expected->empty()); 23870bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe} 23970bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe 240877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravleclass CompilerDriverProfileTest : public CompilerDriverTest { 241877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle protected: 242877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle ProfileCompilationInfo* GetProfileCompilationInfo() OVERRIDE { 243877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle ScopedObjectAccess soa(Thread::Current()); 244877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle std::vector<std::unique_ptr<const DexFile>> dex_files = OpenTestDexFiles("ProfileTestMultiDex"); 245877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle 246877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle ProfileCompilationInfo info; 247877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle for (const std::unique_ptr<const DexFile>& dex_file : dex_files) { 248bbe3a5efcdfb2fb15a4e5f724cc323ae0ada5111Mathieu Chartier profile_info_.AddMethodIndex(ProfileCompilationInfo::MethodHotness::kFlagHot, 249bbe3a5efcdfb2fb15a4e5f724cc323ae0ada5111Mathieu Chartier MethodReference(dex_file.get(), 1)); 250bbe3a5efcdfb2fb15a4e5f724cc323ae0ada5111Mathieu Chartier profile_info_.AddMethodIndex(ProfileCompilationInfo::MethodHotness::kFlagHot, 251bbe3a5efcdfb2fb15a4e5f724cc323ae0ada5111Mathieu Chartier MethodReference(dex_file.get(), 2)); 252877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle } 253877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle return &profile_info_; 254877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle } 255877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle 256d0af56cdb1eaebea403e382257bdc14d7b7fdaa4Mathieu Chartier CompilerFilter::Filter GetCompilerFilter() const OVERRIDE { 257d0af56cdb1eaebea403e382257bdc14d7b7fdaa4Mathieu Chartier // Use a profile based filter. 258d0af56cdb1eaebea403e382257bdc14d7b7fdaa4Mathieu Chartier return CompilerFilter::kSpeedProfile; 259d0af56cdb1eaebea403e382257bdc14d7b7fdaa4Mathieu Chartier } 260d0af56cdb1eaebea403e382257bdc14d7b7fdaa4Mathieu Chartier 261877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle std::unordered_set<std::string> GetExpectedMethodsForClass(const std::string& clazz) { 262877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle if (clazz == "Main") { 263877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle return std::unordered_set<std::string>({ 264877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle "java.lang.String Main.getA()", 265877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle "java.lang.String Main.getB()"}); 266877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle } else if (clazz == "Second") { 267877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle return std::unordered_set<std::string>({ 268877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle "java.lang.String Second.getX()", 269877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle "java.lang.String Second.getY()"}); 270877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle } else { 271877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle return std::unordered_set<std::string>(); 272877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle } 273877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle } 274877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle 275877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle void CheckCompiledMethods(jobject class_loader, 276877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle const std::string& clazz, 277877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle const std::unordered_set<std::string>& expected_methods) { 278877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 279877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle Thread* self = Thread::Current(); 280877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle ScopedObjectAccess soa(self); 281877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle StackHandleScope<1> hs(self); 282c4f3925490a73da8dc74884a1deb965d4ecaf14eMathieu Chartier Handle<mirror::ClassLoader> h_loader( 283c4f3925490a73da8dc74884a1deb965d4ecaf14eMathieu Chartier hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader))); 284877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle mirror::Class* klass = class_linker->FindClass(self, clazz.c_str(), h_loader); 285877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle ASSERT_NE(klass, nullptr); 286877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle 287877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle const auto pointer_size = class_linker->GetImagePointerSize(); 288877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle size_t number_of_compiled_methods = 0; 289877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle for (auto& m : klass->GetVirtualMethods(pointer_size)) { 290709b070044354d9f47641f273edacaeeb0240ab7David Sehr std::string name = m.PrettyMethod(true); 291877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle const void* code = m.GetEntryPointFromQuickCompiledCodePtrSize(pointer_size); 292877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle ASSERT_NE(code, nullptr); 293877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle if (expected_methods.find(name) != expected_methods.end()) { 294877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle number_of_compiled_methods++; 295877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle EXPECT_FALSE(class_linker->IsQuickToInterpreterBridge(code)); 296877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle } else { 297877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle EXPECT_TRUE(class_linker->IsQuickToInterpreterBridge(code)); 298877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle } 299877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle } 300877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle EXPECT_EQ(expected_methods.size(), number_of_compiled_methods); 301877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle } 302877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle 303877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle private: 304877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle ProfileCompilationInfo profile_info_; 305877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle}; 306877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle 307877fd963548a3175665bfef25b0d24bc0e5a0135Calin JuravleTEST_F(CompilerDriverProfileTest, ProfileGuidedCompilation) { 308877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle Thread* self = Thread::Current(); 309877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle jobject class_loader; 310877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle { 311877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle ScopedObjectAccess soa(self); 312877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle class_loader = LoadDex("ProfileTestMultiDex"); 313877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle } 314877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle ASSERT_NE(class_loader, nullptr); 315877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle 316877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle // Need to enable dex-file writability. Methods rejected to be compiled will run through the 317877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle // dex-to-dex compiler. 318877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle for (const DexFile* dex_file : GetDexFiles(class_loader)) { 319877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle ASSERT_TRUE(dex_file->EnableWrite()); 320877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle } 321877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle 322877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle CompileAll(class_loader); 323877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle 324877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle std::unordered_set<std::string> m = GetExpectedMethodsForClass("Main"); 325877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle std::unordered_set<std::string> s = GetExpectedMethodsForClass("Second"); 326877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle CheckCompiledMethods(class_loader, "LMain;", m); 327877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle CheckCompiledMethods(class_loader, "LSecond;", s); 328877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle} 329877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle 330c7da1d61ba0fc38950f303813d4ba8c2d6d05c7fNicolas Geoffray// Test that a verify only compiler filter updates the CompiledClass map, 331c7da1d61ba0fc38950f303813d4ba8c2d6d05c7fNicolas Geoffray// which will be used for OatClass. 332c7da1d61ba0fc38950f303813d4ba8c2d6d05c7fNicolas Geoffrayclass CompilerDriverVerifyTest : public CompilerDriverTest { 333c7da1d61ba0fc38950f303813d4ba8c2d6d05c7fNicolas Geoffray protected: 334c7da1d61ba0fc38950f303813d4ba8c2d6d05c7fNicolas Geoffray CompilerFilter::Filter GetCompilerFilter() const OVERRIDE { 33549cda06d5bf003f588ba7839bbf89d606237dfa7Nicolas Geoffray return CompilerFilter::kVerify; 336c7da1d61ba0fc38950f303813d4ba8c2d6d05c7fNicolas Geoffray } 337c7da1d61ba0fc38950f303813d4ba8c2d6d05c7fNicolas Geoffray 338c7da1d61ba0fc38950f303813d4ba8c2d6d05c7fNicolas Geoffray void CheckVerifiedClass(jobject class_loader, const std::string& clazz) const { 339c7da1d61ba0fc38950f303813d4ba8c2d6d05c7fNicolas Geoffray ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 340c7da1d61ba0fc38950f303813d4ba8c2d6d05c7fNicolas Geoffray Thread* self = Thread::Current(); 341c7da1d61ba0fc38950f303813d4ba8c2d6d05c7fNicolas Geoffray ScopedObjectAccess soa(self); 342c7da1d61ba0fc38950f303813d4ba8c2d6d05c7fNicolas Geoffray StackHandleScope<1> hs(self); 343c7da1d61ba0fc38950f303813d4ba8c2d6d05c7fNicolas Geoffray Handle<mirror::ClassLoader> h_loader( 344c7da1d61ba0fc38950f303813d4ba8c2d6d05c7fNicolas Geoffray hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader))); 345c7da1d61ba0fc38950f303813d4ba8c2d6d05c7fNicolas Geoffray mirror::Class* klass = class_linker->FindClass(self, clazz.c_str(), h_loader); 346c7da1d61ba0fc38950f303813d4ba8c2d6d05c7fNicolas Geoffray ASSERT_NE(klass, nullptr); 347c7da1d61ba0fc38950f303813d4ba8c2d6d05c7fNicolas Geoffray EXPECT_TRUE(klass->IsVerified()); 348c7da1d61ba0fc38950f303813d4ba8c2d6d05c7fNicolas Geoffray 3492c64a837e62c2839521c89060b5bb0dcb237dddaVladimir Marko ClassStatus status; 350bb84610d2de3c12b0e0cdc724df29479b9501461Andreas Gampe bool found = compiler_driver_->GetCompiledClass( 351bb84610d2de3c12b0e0cdc724df29479b9501461Andreas Gampe ClassReference(&klass->GetDexFile(), klass->GetDexTypeIndex().index_), &status); 352bb84610d2de3c12b0e0cdc724df29479b9501461Andreas Gampe ASSERT_TRUE(found); 3532c64a837e62c2839521c89060b5bb0dcb237dddaVladimir Marko EXPECT_EQ(status, ClassStatus::kVerified); 354c7da1d61ba0fc38950f303813d4ba8c2d6d05c7fNicolas Geoffray } 355c7da1d61ba0fc38950f303813d4ba8c2d6d05c7fNicolas Geoffray}; 356c7da1d61ba0fc38950f303813d4ba8c2d6d05c7fNicolas Geoffray 357c7da1d61ba0fc38950f303813d4ba8c2d6d05c7fNicolas GeoffrayTEST_F(CompilerDriverVerifyTest, VerifyCompilation) { 358c7da1d61ba0fc38950f303813d4ba8c2d6d05c7fNicolas Geoffray Thread* self = Thread::Current(); 359c7da1d61ba0fc38950f303813d4ba8c2d6d05c7fNicolas Geoffray jobject class_loader; 360c7da1d61ba0fc38950f303813d4ba8c2d6d05c7fNicolas Geoffray { 361c7da1d61ba0fc38950f303813d4ba8c2d6d05c7fNicolas Geoffray ScopedObjectAccess soa(self); 362c7da1d61ba0fc38950f303813d4ba8c2d6d05c7fNicolas Geoffray class_loader = LoadDex("ProfileTestMultiDex"); 363c7da1d61ba0fc38950f303813d4ba8c2d6d05c7fNicolas Geoffray } 364c7da1d61ba0fc38950f303813d4ba8c2d6d05c7fNicolas Geoffray ASSERT_NE(class_loader, nullptr); 365c7da1d61ba0fc38950f303813d4ba8c2d6d05c7fNicolas Geoffray 366c7da1d61ba0fc38950f303813d4ba8c2d6d05c7fNicolas Geoffray CompileAll(class_loader); 367c7da1d61ba0fc38950f303813d4ba8c2d6d05c7fNicolas Geoffray 368c7da1d61ba0fc38950f303813d4ba8c2d6d05c7fNicolas Geoffray CheckVerifiedClass(class_loader, "LMain;"); 369c7da1d61ba0fc38950f303813d4ba8c2d6d05c7fNicolas Geoffray CheckVerifiedClass(class_loader, "LSecond;"); 370c7da1d61ba0fc38950f303813d4ba8c2d6d05c7fNicolas Geoffray} 371c7da1d61ba0fc38950f303813d4ba8c2d6d05c7fNicolas Geoffray 3722c64a837e62c2839521c89060b5bb0dcb237dddaVladimir Marko// Test that a class of status ClassStatus::kRetryVerificationAtRuntime is indeed 3732c64a837e62c2839521c89060b5bb0dcb237dddaVladimir Marko// recorded that way in the driver. 3749e050df94df5c6736e1e24705194f62fbc119114Mathieu ChartierTEST_F(CompilerDriverVerifyTest, RetryVerifcationStatusCheckVerified) { 375f1aa26599d866abe3c31ac959b042fc32d7fb581Jeff Hao Thread* const self = Thread::Current(); 376f1aa26599d866abe3c31ac959b042fc32d7fb581Jeff Hao jobject class_loader; 377f1aa26599d866abe3c31ac959b042fc32d7fb581Jeff Hao std::vector<const DexFile*> dex_files; 378f1aa26599d866abe3c31ac959b042fc32d7fb581Jeff Hao const DexFile* dex_file = nullptr; 379f1aa26599d866abe3c31ac959b042fc32d7fb581Jeff Hao { 380f1aa26599d866abe3c31ac959b042fc32d7fb581Jeff Hao ScopedObjectAccess soa(self); 381f1aa26599d866abe3c31ac959b042fc32d7fb581Jeff Hao class_loader = LoadDex("ProfileTestMultiDex"); 382f1aa26599d866abe3c31ac959b042fc32d7fb581Jeff Hao ASSERT_NE(class_loader, nullptr); 383f1aa26599d866abe3c31ac959b042fc32d7fb581Jeff Hao dex_files = GetDexFiles(class_loader); 384f1aa26599d866abe3c31ac959b042fc32d7fb581Jeff Hao ASSERT_GT(dex_files.size(), 0u); 385f1aa26599d866abe3c31ac959b042fc32d7fb581Jeff Hao dex_file = dex_files.front(); 386f1aa26599d866abe3c31ac959b042fc32d7fb581Jeff Hao } 387f1aa26599d866abe3c31ac959b042fc32d7fb581Jeff Hao compiler_driver_->SetDexFilesForOatFile(dex_files); 3889e050df94df5c6736e1e24705194f62fbc119114Mathieu Chartier callbacks_->SetDoesClassUnloading(true, compiler_driver_.get()); 389f1aa26599d866abe3c31ac959b042fc32d7fb581Jeff Hao ClassReference ref(dex_file, 0u); 390f1aa26599d866abe3c31ac959b042fc32d7fb581Jeff Hao // Test that the status is read from the compiler driver as expected. 3912c64a837e62c2839521c89060b5bb0dcb237dddaVladimir Marko static_assert(enum_cast<size_t>(ClassStatus::kLast) < std::numeric_limits<size_t>::max(), 3922c64a837e62c2839521c89060b5bb0dcb237dddaVladimir Marko "Make sure incrementing the class status does not overflow."); 3932c64a837e62c2839521c89060b5bb0dcb237dddaVladimir Marko for (size_t i = enum_cast<size_t>(ClassStatus::kRetryVerificationAtRuntime); 3942c64a837e62c2839521c89060b5bb0dcb237dddaVladimir Marko i <= enum_cast<size_t>(ClassStatus::kLast); 3952c64a837e62c2839521c89060b5bb0dcb237dddaVladimir Marko ++i) { 3962c64a837e62c2839521c89060b5bb0dcb237dddaVladimir Marko const ClassStatus expected_status = enum_cast<ClassStatus>(i); 397f1aa26599d866abe3c31ac959b042fc32d7fb581Jeff Hao // Skip unsupported status that are not supposed to be ever recorded. 3982c64a837e62c2839521c89060b5bb0dcb237dddaVladimir Marko if (expected_status == ClassStatus::kVerifyingAtRuntime || 3992c64a837e62c2839521c89060b5bb0dcb237dddaVladimir Marko expected_status == ClassStatus::kInitializing) { 400f1aa26599d866abe3c31ac959b042fc32d7fb581Jeff Hao continue; 401f1aa26599d866abe3c31ac959b042fc32d7fb581Jeff Hao } 402f1aa26599d866abe3c31ac959b042fc32d7fb581Jeff Hao compiler_driver_->RecordClassStatus(ref, expected_status); 4032c64a837e62c2839521c89060b5bb0dcb237dddaVladimir Marko ClassStatus status = {}; 404f1aa26599d866abe3c31ac959b042fc32d7fb581Jeff Hao ASSERT_TRUE(compiler_driver_->GetCompiledClass(ref, &status)); 405f1aa26599d866abe3c31ac959b042fc32d7fb581Jeff Hao EXPECT_EQ(status, expected_status); 406f1aa26599d866abe3c31ac959b042fc32d7fb581Jeff Hao } 407f1aa26599d866abe3c31ac959b042fc32d7fb581Jeff Hao} 408f1aa26599d866abe3c31ac959b042fc32d7fb581Jeff Hao 4092a475e7b93d754e0a7525bb5c7059386307ea63abuzbee// TODO: need check-cast test (when stub complete & we can throw/catch 4102a475e7b93d754e0a7525bb5c7059386307ea63abuzbee 411c143c55718342519db5398e41dda31422cf16c79buzbee} // namespace art 412