compiler_driver-inl.h revision 8d6768d47b66a688d35399d524ad5a5450e9d9d4
13a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald/* 219690593273a5b210a9b9ea72bd59840d02759b0Antoine Pitrou * Copyright (C) 2012 The Android Open Source Project 386821b2563915e4f11cde045da8ebe01beffa634Tim Peters * 419690593273a5b210a9b9ea72bd59840d02759b0Antoine Pitrou * Licensed under the Apache License, Version 2.0 (the "License"); 519690593273a5b210a9b9ea72bd59840d02759b0Antoine Pitrou * you may not use this file except in compliance with the License. 686821b2563915e4f11cde045da8ebe01beffa634Tim Peters * You may obtain a copy of the License at 719690593273a5b210a9b9ea72bd59840d02759b0Antoine Pitrou * 819690593273a5b210a9b9ea72bd59840d02759b0Antoine Pitrou * http://www.apache.org/licenses/LICENSE-2.0 919690593273a5b210a9b9ea72bd59840d02759b0Antoine Pitrou * 1019690593273a5b210a9b9ea72bd59840d02759b0Antoine Pitrou * Unless required by applicable law or agreed to in writing, software 1119690593273a5b210a9b9ea72bd59840d02759b0Antoine Pitrou * distributed under the License is distributed on an "AS IS" BASIS, 1219690593273a5b210a9b9ea72bd59840d02759b0Antoine Pitrou * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald * See the License for the specific language governing permissions and 143a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald * limitations under the License. 153a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald */ 163a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald 173a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald#ifndef ART_COMPILER_DRIVER_COMPILER_DRIVER_INL_H_ 183a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald#define ART_COMPILER_DRIVER_COMPILER_DRIVER_INL_H_ 1992abad24d68823dc3c334d05b7bc5375db049b7bNeal Norwitz 2019690593273a5b210a9b9ea72bd59840d02759b0Antoine Pitrou#include "compiler_driver.h" 2192abad24d68823dc3c334d05b7bc5375db049b7bNeal Norwitz 223a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald#include "art_field-inl.h" 233a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald#include "art_method-inl.h" 2419690593273a5b210a9b9ea72bd59840d02759b0Antoine Pitrou#include "base/enums.h" 253a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald#include "class_linker-inl.h" 263a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald#include "dex_compilation_unit.h" 273a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald#include "mirror/class_loader.h" 2819690593273a5b210a9b9ea72bd59840d02759b0Antoine Pitrou#include "mirror/dex_cache-inl.h" 293a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald#include "scoped_thread_state_change-inl.h" 303a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald#include "handle_scope-inl.h" 3119690593273a5b210a9b9ea72bd59840d02759b0Antoine Pitrou 323a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwaldnamespace art { 3319690593273a5b210a9b9ea72bd59840d02759b0Antoine Pitrou 343a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwaldinline mirror::Class* CompilerDriver::ResolveClass( 353a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald const ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache, 363a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald Handle<mirror::ClassLoader> class_loader, dex::TypeIndex cls_index, 37ea4d2875ac5dc83864a8313d6252e56295598070Serhiy Storchaka const DexCompilationUnit* mUnit) { 383a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald DCHECK_EQ(dex_cache->GetDexFile(), mUnit->GetDexFile()); 393a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald DCHECK_EQ(class_loader.Get(), mUnit->GetClassLoader().Get()); 4019690593273a5b210a9b9ea72bd59840d02759b0Antoine Pitrou mirror::Class* cls = mUnit->GetClassLinker()->ResolveType( 41abd8a336a3ab390a2ea4b15a0ecd187e482001afTim Peters *mUnit->GetDexFile(), cls_index, dex_cache, class_loader); 423a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald DCHECK_EQ(cls == nullptr, soa.Self()->IsExceptionPending()); 433a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald if (UNLIKELY(cls == nullptr)) { 443a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald // Clean up any exception left by type resolution. 453a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald soa.Self()->ClearException(); 463a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald } 473a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald return cls; 483a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald} 493a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald 503a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwaldinline mirror::Class* CompilerDriver::ResolveCompilingMethodsClass( 513a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald const ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache, 523a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald Handle<mirror::ClassLoader> class_loader, const DexCompilationUnit* mUnit) { 5319690593273a5b210a9b9ea72bd59840d02759b0Antoine Pitrou DCHECK_EQ(dex_cache->GetDexFile(), mUnit->GetDexFile()); 543a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald DCHECK_EQ(class_loader.Get(), mUnit->GetClassLoader().Get()); 553a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald const DexFile::MethodId& referrer_method_id = 563a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald mUnit->GetDexFile()->GetMethodId(mUnit->GetDexMethodIndex()); 573a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald return ResolveClass(soa, dex_cache, class_loader, referrer_method_id.class_idx_, mUnit); 583a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald} 5919690593273a5b210a9b9ea72bd59840d02759b0Antoine Pitrou 603a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwaldinline ArtField* CompilerDriver::ResolveFieldWithDexFile( 613a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald const ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache, 6219690593273a5b210a9b9ea72bd59840d02759b0Antoine Pitrou Handle<mirror::ClassLoader> class_loader, const DexFile* dex_file, 6319690593273a5b210a9b9ea72bd59840d02759b0Antoine Pitrou uint32_t field_idx, bool is_static) { 6419690593273a5b210a9b9ea72bd59840d02759b0Antoine Pitrou DCHECK_EQ(dex_cache->GetDexFile(), dex_file); 6519690593273a5b210a9b9ea72bd59840d02759b0Antoine Pitrou ArtField* resolved_field = Runtime::Current()->GetClassLinker()->ResolveField( 6619690593273a5b210a9b9ea72bd59840d02759b0Antoine Pitrou *dex_file, field_idx, dex_cache, class_loader, is_static); 6719690593273a5b210a9b9ea72bd59840d02759b0Antoine Pitrou DCHECK_EQ(resolved_field == nullptr, soa.Self()->IsExceptionPending()); 6819690593273a5b210a9b9ea72bd59840d02759b0Antoine Pitrou if (UNLIKELY(resolved_field == nullptr)) { 6919690593273a5b210a9b9ea72bd59840d02759b0Antoine Pitrou // Clean up any exception left by type resolution. 7019690593273a5b210a9b9ea72bd59840d02759b0Antoine Pitrou soa.Self()->ClearException(); 71c5ae86b9d3b6e348b6d0ee77c050134749a18cccAntoine Pitrou return nullptr; 72c5ae86b9d3b6e348b6d0ee77c050134749a18cccAntoine Pitrou } 73c5ae86b9d3b6e348b6d0ee77c050134749a18cccAntoine Pitrou if (UNLIKELY(resolved_field->IsStatic() != is_static)) { 743a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald // ClassLinker can return a field of the wrong kind directly from the DexCache. 753a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald // Silently return null on such incompatible class change. 76c5ae86b9d3b6e348b6d0ee77c050134749a18cccAntoine Pitrou return nullptr; 773a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald } 783a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald return resolved_field; 793a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald} 80 81inline ArtField* CompilerDriver::ResolveField( 82 const ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache, 83 Handle<mirror::ClassLoader> class_loader, const DexCompilationUnit* mUnit, 84 uint32_t field_idx, bool is_static) { 85 DCHECK_EQ(class_loader.Get(), mUnit->GetClassLoader().Get()); 86 return ResolveFieldWithDexFile(soa, dex_cache, class_loader, mUnit->GetDexFile(), field_idx, 87 is_static); 88} 89 90inline std::pair<bool, bool> CompilerDriver::IsFastInstanceField( 91 mirror::DexCache* dex_cache, mirror::Class* referrer_class, 92 ArtField* resolved_field, uint16_t field_idx) { 93 DCHECK(!resolved_field->IsStatic()); 94 ObjPtr<mirror::Class> fields_class = resolved_field->GetDeclaringClass(); 95 bool fast_get = referrer_class != nullptr && 96 referrer_class->CanAccessResolvedField(fields_class, 97 resolved_field, 98 dex_cache, 99 field_idx); 100 bool fast_put = fast_get && (!resolved_field->IsFinal() || fields_class == referrer_class); 101 return std::make_pair(fast_get, fast_put); 102} 103 104template <typename ArtMember> 105inline bool CompilerDriver::CanAccessResolvedMember(mirror::Class* referrer_class ATTRIBUTE_UNUSED, 106 mirror::Class* access_to ATTRIBUTE_UNUSED, 107 ArtMember* member ATTRIBUTE_UNUSED, 108 mirror::DexCache* dex_cache ATTRIBUTE_UNUSED, 109 uint32_t field_idx ATTRIBUTE_UNUSED) { 110 // Not defined for ArtMember values other than ArtField or ArtMethod. 111 UNREACHABLE(); 112} 113 114template <> 115inline bool CompilerDriver::CanAccessResolvedMember<ArtField>(mirror::Class* referrer_class, 116 mirror::Class* access_to, 117 ArtField* field, 118 mirror::DexCache* dex_cache, 119 uint32_t field_idx) { 120 return referrer_class->CanAccessResolvedField(access_to, field, dex_cache, field_idx); 121} 122 123template <> 124inline bool CompilerDriver::CanAccessResolvedMember<ArtMethod>( 125 mirror::Class* referrer_class, 126 mirror::Class* access_to, 127 ArtMethod* method, 128 mirror::DexCache* dex_cache, 129 uint32_t field_idx) { 130 return referrer_class->CanAccessResolvedMethod(access_to, method, dex_cache, field_idx); 131} 132 133inline ArtMethod* CompilerDriver::ResolveMethod( 134 ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache, 135 Handle<mirror::ClassLoader> class_loader, const DexCompilationUnit* mUnit, 136 uint32_t method_idx, InvokeType invoke_type, bool check_incompatible_class_change) { 137 DCHECK_EQ(class_loader.Get(), mUnit->GetClassLoader().Get()); 138 ArtMethod* resolved_method = 139 check_incompatible_class_change 140 ? mUnit->GetClassLinker()->ResolveMethod<ClassLinker::kForceICCECheck>( 141 *dex_cache->GetDexFile(), method_idx, dex_cache, class_loader, nullptr, invoke_type) 142 : mUnit->GetClassLinker()->ResolveMethod<ClassLinker::kNoICCECheckForCache>( 143 *dex_cache->GetDexFile(), method_idx, dex_cache, class_loader, nullptr, invoke_type); 144 if (UNLIKELY(resolved_method == nullptr)) { 145 DCHECK(soa.Self()->IsExceptionPending()); 146 // Clean up any exception left by type resolution. 147 soa.Self()->ClearException(); 148 } 149 return resolved_method; 150} 151 152} // namespace art 153 154#endif // ART_COMPILER_DRIVER_COMPILER_DRIVER_INL_H_ 155