compiler_driver-inl.h revision 8d6768d47b66a688d35399d524ad5a5450e9d9d4
1be0e546730e532ef0987cd4bde2c6f5a1b14dd2aVladimir Marko/* 2be0e546730e532ef0987cd4bde2c6f5a1b14dd2aVladimir Marko * Copyright (C) 2012 The Android Open Source Project 3be0e546730e532ef0987cd4bde2c6f5a1b14dd2aVladimir Marko * 4be0e546730e532ef0987cd4bde2c6f5a1b14dd2aVladimir Marko * Licensed under the Apache License, Version 2.0 (the "License"); 5be0e546730e532ef0987cd4bde2c6f5a1b14dd2aVladimir Marko * you may not use this file except in compliance with the License. 6be0e546730e532ef0987cd4bde2c6f5a1b14dd2aVladimir Marko * You may obtain a copy of the License at 7be0e546730e532ef0987cd4bde2c6f5a1b14dd2aVladimir Marko * 8be0e546730e532ef0987cd4bde2c6f5a1b14dd2aVladimir Marko * http://www.apache.org/licenses/LICENSE-2.0 9be0e546730e532ef0987cd4bde2c6f5a1b14dd2aVladimir Marko * 10be0e546730e532ef0987cd4bde2c6f5a1b14dd2aVladimir Marko * Unless required by applicable law or agreed to in writing, software 11be0e546730e532ef0987cd4bde2c6f5a1b14dd2aVladimir Marko * distributed under the License is distributed on an "AS IS" BASIS, 12be0e546730e532ef0987cd4bde2c6f5a1b14dd2aVladimir Marko * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13be0e546730e532ef0987cd4bde2c6f5a1b14dd2aVladimir Marko * See the License for the specific language governing permissions and 14be0e546730e532ef0987cd4bde2c6f5a1b14dd2aVladimir Marko * limitations under the License. 15be0e546730e532ef0987cd4bde2c6f5a1b14dd2aVladimir Marko */ 16be0e546730e532ef0987cd4bde2c6f5a1b14dd2aVladimir Marko 17be0e546730e532ef0987cd4bde2c6f5a1b14dd2aVladimir Marko#ifndef ART_COMPILER_DRIVER_COMPILER_DRIVER_INL_H_ 18be0e546730e532ef0987cd4bde2c6f5a1b14dd2aVladimir Marko#define ART_COMPILER_DRIVER_COMPILER_DRIVER_INL_H_ 19be0e546730e532ef0987cd4bde2c6f5a1b14dd2aVladimir Marko 20be0e546730e532ef0987cd4bde2c6f5a1b14dd2aVladimir Marko#include "compiler_driver.h" 2198d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang 22c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier#include "art_field-inl.h" 23e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier#include "art_method-inl.h" 24542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampe#include "base/enums.h" 25e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier#include "class_linker-inl.h" 2653c913bb71b218714823c8c87a1f92830c336f61Andreas Gampe#include "dex_compilation_unit.h" 27be0e546730e532ef0987cd4bde2c6f5a1b14dd2aVladimir Marko#include "mirror/class_loader.h" 28f096aad9203d7c50b2f9cbe1c1215a50c265a059Vladimir Marko#include "mirror/dex_cache-inl.h" 290795f23920ee9aabf28e45c63cd592dcccf00216Mathieu Chartier#include "scoped_thread_state_change-inl.h" 30eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier#include "handle_scope-inl.h" 31be0e546730e532ef0987cd4bde2c6f5a1b14dd2aVladimir Marko 32be0e546730e532ef0987cd4bde2c6f5a1b14dd2aVladimir Markonamespace art { 33be0e546730e532ef0987cd4bde2c6f5a1b14dd2aVladimir Marko 349437b78780f9e6ffa5797ebe82de8e8d7f3a5ed6Nicolas Geoffrayinline mirror::Class* CompilerDriver::ResolveClass( 359437b78780f9e6ffa5797ebe82de8e8d7f3a5ed6Nicolas Geoffray const ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache, 36a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe Handle<mirror::ClassLoader> class_loader, dex::TypeIndex cls_index, 379437b78780f9e6ffa5797ebe82de8e8d7f3a5ed6Nicolas Geoffray const DexCompilationUnit* mUnit) { 389437b78780f9e6ffa5797ebe82de8e8d7f3a5ed6Nicolas Geoffray DCHECK_EQ(dex_cache->GetDexFile(), mUnit->GetDexFile()); 398d6768d47b66a688d35399d524ad5a5450e9d9d4Vladimir Marko DCHECK_EQ(class_loader.Get(), mUnit->GetClassLoader().Get()); 409437b78780f9e6ffa5797ebe82de8e8d7f3a5ed6Nicolas Geoffray mirror::Class* cls = mUnit->GetClassLinker()->ResolveType( 419437b78780f9e6ffa5797ebe82de8e8d7f3a5ed6Nicolas Geoffray *mUnit->GetDexFile(), cls_index, dex_cache, class_loader); 429437b78780f9e6ffa5797ebe82de8e8d7f3a5ed6Nicolas Geoffray DCHECK_EQ(cls == nullptr, soa.Self()->IsExceptionPending()); 439437b78780f9e6ffa5797ebe82de8e8d7f3a5ed6Nicolas Geoffray if (UNLIKELY(cls == nullptr)) { 449437b78780f9e6ffa5797ebe82de8e8d7f3a5ed6Nicolas Geoffray // Clean up any exception left by type resolution. 459437b78780f9e6ffa5797ebe82de8e8d7f3a5ed6Nicolas Geoffray soa.Self()->ClearException(); 469437b78780f9e6ffa5797ebe82de8e8d7f3a5ed6Nicolas Geoffray } 479437b78780f9e6ffa5797ebe82de8e8d7f3a5ed6Nicolas Geoffray return cls; 489437b78780f9e6ffa5797ebe82de8e8d7f3a5ed6Nicolas Geoffray} 499437b78780f9e6ffa5797ebe82de8e8d7f3a5ed6Nicolas Geoffray 50be0e546730e532ef0987cd4bde2c6f5a1b14dd2aVladimir Markoinline mirror::Class* CompilerDriver::ResolveCompilingMethodsClass( 51e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray const ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache, 520cd81352a7c06e381951cea1b104fd73516f4341Mathieu Chartier Handle<mirror::ClassLoader> class_loader, const DexCompilationUnit* mUnit) { 53eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier DCHECK_EQ(dex_cache->GetDexFile(), mUnit->GetDexFile()); 548d6768d47b66a688d35399d524ad5a5450e9d9d4Vladimir Marko DCHECK_EQ(class_loader.Get(), mUnit->GetClassLoader().Get()); 55be0e546730e532ef0987cd4bde2c6f5a1b14dd2aVladimir Marko const DexFile::MethodId& referrer_method_id = 56be0e546730e532ef0987cd4bde2c6f5a1b14dd2aVladimir Marko mUnit->GetDexFile()->GetMethodId(mUnit->GetDexMethodIndex()); 579437b78780f9e6ffa5797ebe82de8e8d7f3a5ed6Nicolas Geoffray return ResolveClass(soa, dex_cache, class_loader, referrer_method_id.class_idx_, mUnit); 58be0e546730e532ef0987cd4bde2c6f5a1b14dd2aVladimir Marko} 59be0e546730e532ef0987cd4bde2c6f5a1b14dd2aVladimir Marko 60c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartierinline ArtField* CompilerDriver::ResolveFieldWithDexFile( 61e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray const ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache, 62e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier Handle<mirror::ClassLoader> class_loader, const DexFile* dex_file, 63be0e546730e532ef0987cd4bde2c6f5a1b14dd2aVladimir Marko uint32_t field_idx, bool is_static) { 64e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier DCHECK_EQ(dex_cache->GetDexFile(), dex_file); 65c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier ArtField* resolved_field = Runtime::Current()->GetClassLinker()->ResolveField( 66e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier *dex_file, field_idx, dex_cache, class_loader, is_static); 67be0e546730e532ef0987cd4bde2c6f5a1b14dd2aVladimir Marko DCHECK_EQ(resolved_field == nullptr, soa.Self()->IsExceptionPending()); 68be0e546730e532ef0987cd4bde2c6f5a1b14dd2aVladimir Marko if (UNLIKELY(resolved_field == nullptr)) { 69be0e546730e532ef0987cd4bde2c6f5a1b14dd2aVladimir Marko // Clean up any exception left by type resolution. 70be0e546730e532ef0987cd4bde2c6f5a1b14dd2aVladimir Marko soa.Self()->ClearException(); 71be0e546730e532ef0987cd4bde2c6f5a1b14dd2aVladimir Marko return nullptr; 72be0e546730e532ef0987cd4bde2c6f5a1b14dd2aVladimir Marko } 73be0e546730e532ef0987cd4bde2c6f5a1b14dd2aVladimir Marko if (UNLIKELY(resolved_field->IsStatic() != is_static)) { 74be0e546730e532ef0987cd4bde2c6f5a1b14dd2aVladimir Marko // ClassLinker can return a field of the wrong kind directly from the DexCache. 752cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier // Silently return null on such incompatible class change. 76be0e546730e532ef0987cd4bde2c6f5a1b14dd2aVladimir Marko return nullptr; 77be0e546730e532ef0987cd4bde2c6f5a1b14dd2aVladimir Marko } 78be0e546730e532ef0987cd4bde2c6f5a1b14dd2aVladimir Marko return resolved_field; 79be0e546730e532ef0987cd4bde2c6f5a1b14dd2aVladimir Marko} 80be0e546730e532ef0987cd4bde2c6f5a1b14dd2aVladimir Marko 81c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartierinline ArtField* CompilerDriver::ResolveField( 82e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier const ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache, 83e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier Handle<mirror::ClassLoader> class_loader, const DexCompilationUnit* mUnit, 84e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier uint32_t field_idx, bool is_static) { 858d6768d47b66a688d35399d524ad5a5450e9d9d4Vladimir Marko DCHECK_EQ(class_loader.Get(), mUnit->GetClassLoader().Get()); 86e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier return ResolveFieldWithDexFile(soa, dex_cache, class_loader, mUnit->GetDexFile(), field_idx, 87e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier is_static); 88e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier} 89e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier 90be0e546730e532ef0987cd4bde2c6f5a1b14dd2aVladimir Markoinline std::pair<bool, bool> CompilerDriver::IsFastInstanceField( 91be0e546730e532ef0987cd4bde2c6f5a1b14dd2aVladimir Marko mirror::DexCache* dex_cache, mirror::Class* referrer_class, 92c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier ArtField* resolved_field, uint16_t field_idx) { 93be0e546730e532ef0987cd4bde2c6f5a1b14dd2aVladimir Marko DCHECK(!resolved_field->IsStatic()); 943398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier ObjPtr<mirror::Class> fields_class = resolved_field->GetDeclaringClass(); 95be0e546730e532ef0987cd4bde2c6f5a1b14dd2aVladimir Marko bool fast_get = referrer_class != nullptr && 961a5337fff2cc6cb9d563c8b32aca75f485d23373Mathieu Chartier referrer_class->CanAccessResolvedField(fields_class, 973398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier resolved_field, 983398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier dex_cache, 993398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier field_idx); 100be0e546730e532ef0987cd4bde2c6f5a1b14dd2aVladimir Marko bool fast_put = fast_get && (!resolved_field->IsFinal() || fields_class == referrer_class); 101be0e546730e532ef0987cd4bde2c6f5a1b14dd2aVladimir Marko return std::make_pair(fast_get, fast_put); 102be0e546730e532ef0987cd4bde2c6f5a1b14dd2aVladimir Marko} 103be0e546730e532ef0987cd4bde2c6f5a1b14dd2aVladimir Marko 1044c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillaintemplate <typename ArtMember> 1054c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillaininline bool CompilerDriver::CanAccessResolvedMember(mirror::Class* referrer_class ATTRIBUTE_UNUSED, 1064c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain mirror::Class* access_to ATTRIBUTE_UNUSED, 1074c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain ArtMember* member ATTRIBUTE_UNUSED, 1084c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain mirror::DexCache* dex_cache ATTRIBUTE_UNUSED, 1094c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain uint32_t field_idx ATTRIBUTE_UNUSED) { 110e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier // Not defined for ArtMember values other than ArtField or ArtMethod. 1114c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain UNREACHABLE(); 1124c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain} 1134c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain 1144c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillaintemplate <> 1154c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillaininline bool CompilerDriver::CanAccessResolvedMember<ArtField>(mirror::Class* referrer_class, 1164c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain mirror::Class* access_to, 1174c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain ArtField* field, 1184c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain mirror::DexCache* dex_cache, 1194c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain uint32_t field_idx) { 1204c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain return referrer_class->CanAccessResolvedField(access_to, field, dex_cache, field_idx); 1214c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain} 1224c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain 1234c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillaintemplate <> 124e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline bool CompilerDriver::CanAccessResolvedMember<ArtMethod>( 1254c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain mirror::Class* referrer_class, 1264c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain mirror::Class* access_to, 127e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier ArtMethod* method, 1284c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain mirror::DexCache* dex_cache, 1294c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain uint32_t field_idx) { 1304c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain return referrer_class->CanAccessResolvedMethod(access_to, method, dex_cache, field_idx); 1314c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain} 1324c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain 133e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline ArtMethod* CompilerDriver::ResolveMethod( 1340cd81352a7c06e381951cea1b104fd73516f4341Mathieu Chartier ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache, 1350cd81352a7c06e381951cea1b104fd73516f4341Mathieu Chartier Handle<mirror::ClassLoader> class_loader, const DexCompilationUnit* mUnit, 136e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier uint32_t method_idx, InvokeType invoke_type, bool check_incompatible_class_change) { 1378d6768d47b66a688d35399d524ad5a5450e9d9d4Vladimir Marko DCHECK_EQ(class_loader.Get(), mUnit->GetClassLoader().Get()); 13842ef8ab151a3d0cbb42cb43f6841c3708d65fca3Andreas Gampe ArtMethod* resolved_method = 13942ef8ab151a3d0cbb42cb43f6841c3708d65fca3Andreas Gampe check_incompatible_class_change 14042ef8ab151a3d0cbb42cb43f6841c3708d65fca3Andreas Gampe ? mUnit->GetClassLinker()->ResolveMethod<ClassLinker::kForceICCECheck>( 14142ef8ab151a3d0cbb42cb43f6841c3708d65fca3Andreas Gampe *dex_cache->GetDexFile(), method_idx, dex_cache, class_loader, nullptr, invoke_type) 14242ef8ab151a3d0cbb42cb43f6841c3708d65fca3Andreas Gampe : mUnit->GetClassLinker()->ResolveMethod<ClassLinker::kNoICCECheckForCache>( 14342ef8ab151a3d0cbb42cb43f6841c3708d65fca3Andreas Gampe *dex_cache->GetDexFile(), method_idx, dex_cache, class_loader, nullptr, invoke_type); 144f096aad9203d7c50b2f9cbe1c1215a50c265a059Vladimir Marko if (UNLIKELY(resolved_method == nullptr)) { 14542ef8ab151a3d0cbb42cb43f6841c3708d65fca3Andreas Gampe DCHECK(soa.Self()->IsExceptionPending()); 146f096aad9203d7c50b2f9cbe1c1215a50c265a059Vladimir Marko // Clean up any exception left by type resolution. 147f096aad9203d7c50b2f9cbe1c1215a50c265a059Vladimir Marko soa.Self()->ClearException(); 148f096aad9203d7c50b2f9cbe1c1215a50c265a059Vladimir Marko } 149f096aad9203d7c50b2f9cbe1c1215a50c265a059Vladimir Marko return resolved_method; 150f096aad9203d7c50b2f9cbe1c1215a50c265a059Vladimir Marko} 151f096aad9203d7c50b2f9cbe1c1215a50c265a059Vladimir Marko 152be0e546730e532ef0987cd4bde2c6f5a1b14dd2aVladimir Marko} // namespace art 153be0e546730e532ef0987cd4bde2c6f5a1b14dd2aVladimir Marko 154be0e546730e532ef0987cd4bde2c6f5a1b14dd2aVladimir Marko#endif // ART_COMPILER_DRIVER_COMPILER_DRIVER_INL_H_ 155