Home | History | Annotate | Download | only in runtime
      1 /*
      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  */
     16 
     17 #ifndef ART_RUNTIME_CLASS_LINKER_INL_H_
     18 #define ART_RUNTIME_CLASS_LINKER_INL_H_
     19 
     20 #include <atomic>
     21 
     22 #include "art_field-inl.h"
     23 #include "art_method-inl.h"
     24 #include "base/mutex.h"
     25 #include "class_linker.h"
     26 #include "dex/dex_file.h"
     27 #include "dex/dex_file_structs.h"
     28 #include "gc_root-inl.h"
     29 #include "handle_scope-inl.h"
     30 #include "mirror/class_loader.h"
     31 #include "mirror/dex_cache-inl.h"
     32 #include "mirror/iftable.h"
     33 #include "mirror/object_array-inl.h"
     34 #include "obj_ptr-inl.h"
     35 #include "scoped_thread_state_change-inl.h"
     36 
     37 namespace art {
     38 
     39 inline ObjPtr<mirror::Class> ClassLinker::FindArrayClass(Thread* self,
     40                                                          ObjPtr<mirror::Class> element_class) {
     41   for (size_t i = 0; i < kFindArrayCacheSize; ++i) {
     42     // Read the cached array class once to avoid races with other threads setting it.
     43     ObjPtr<mirror::Class> array_class = find_array_class_cache_[i].Read();
     44     if (array_class != nullptr && array_class->GetComponentType() == element_class) {
     45       return array_class;
     46     }
     47   }
     48   std::string descriptor = "[";
     49   std::string temp;
     50   descriptor += element_class->GetDescriptor(&temp);
     51   StackHandleScope<1> hs(Thread::Current());
     52   Handle<mirror::ClassLoader> class_loader(hs.NewHandle(element_class->GetClassLoader()));
     53   ObjPtr<mirror::Class> array_class = FindClass(self, descriptor.c_str(), class_loader);
     54   if (array_class != nullptr) {
     55     // Benign races in storing array class and incrementing index.
     56     size_t victim_index = find_array_class_cache_next_victim_;
     57     find_array_class_cache_[victim_index] = GcRoot<mirror::Class>(array_class);
     58     find_array_class_cache_next_victim_ = (victim_index + 1) % kFindArrayCacheSize;
     59   } else {
     60     // We should have a NoClassDefFoundError.
     61     self->AssertPendingException();
     62   }
     63   return array_class;
     64 }
     65 
     66 inline ObjPtr<mirror::String> ClassLinker::ResolveString(dex::StringIndex string_idx,
     67                                                          ArtField* referrer) {
     68   Thread::PoisonObjectPointersIfDebug();
     69   DCHECK(!Thread::Current()->IsExceptionPending());
     70   // We do not need the read barrier for getting the DexCache for the initial resolved type
     71   // lookup as both from-space and to-space copies point to the same native resolved types array.
     72   ObjPtr<mirror::String> resolved =
     73       referrer->GetDexCache<kWithoutReadBarrier>()->GetResolvedString(string_idx);
     74   if (resolved == nullptr) {
     75     resolved = DoResolveString(string_idx, referrer->GetDexCache());
     76   }
     77   return resolved;
     78 }
     79 
     80 inline ObjPtr<mirror::String> ClassLinker::ResolveString(dex::StringIndex string_idx,
     81                                                          ArtMethod* referrer) {
     82   Thread::PoisonObjectPointersIfDebug();
     83   DCHECK(!Thread::Current()->IsExceptionPending());
     84   // We do not need the read barrier for getting the DexCache for the initial resolved type
     85   // lookup as both from-space and to-space copies point to the same native resolved types array.
     86   ObjPtr<mirror::String> resolved =
     87       referrer->GetDexCache<kWithoutReadBarrier>()->GetResolvedString(string_idx);
     88   if (resolved == nullptr) {
     89     resolved = DoResolveString(string_idx, referrer->GetDexCache());
     90   }
     91   return resolved;
     92 }
     93 
     94 inline ObjPtr<mirror::String> ClassLinker::ResolveString(dex::StringIndex string_idx,
     95                                                          Handle<mirror::DexCache> dex_cache) {
     96   Thread::PoisonObjectPointersIfDebug();
     97   DCHECK(!Thread::Current()->IsExceptionPending());
     98   ObjPtr<mirror::String> resolved = dex_cache->GetResolvedString(string_idx);
     99   if (resolved == nullptr) {
    100     resolved = DoResolveString(string_idx, dex_cache);
    101   }
    102   return resolved;
    103 }
    104 
    105 inline ObjPtr<mirror::String> ClassLinker::LookupString(dex::StringIndex string_idx,
    106                                                         ObjPtr<mirror::DexCache> dex_cache) {
    107   ObjPtr<mirror::String> resolved = dex_cache->GetResolvedString(string_idx);
    108   if (resolved == nullptr) {
    109     resolved = DoLookupString(string_idx, dex_cache);
    110   }
    111   return resolved;
    112 }
    113 
    114 inline ObjPtr<mirror::Class> ClassLinker::ResolveType(dex::TypeIndex type_idx,
    115                                                       ObjPtr<mirror::Class> referrer) {
    116   if (kObjPtrPoisoning) {
    117     StackHandleScope<1> hs(Thread::Current());
    118     HandleWrapperObjPtr<mirror::Class> referrer_wrapper = hs.NewHandleWrapper(&referrer);
    119     Thread::Current()->PoisonObjectPointers();
    120   }
    121   DCHECK(!Thread::Current()->IsExceptionPending());
    122   // We do not need the read barrier for getting the DexCache for the initial resolved type
    123   // lookup as both from-space and to-space copies point to the same native resolved types array.
    124   ObjPtr<mirror::Class> resolved_type =
    125       referrer->GetDexCache<kDefaultVerifyFlags, kWithoutReadBarrier>()->GetResolvedType(type_idx);
    126   if (resolved_type == nullptr) {
    127     resolved_type = DoResolveType(type_idx, referrer);
    128   }
    129   return resolved_type;
    130 }
    131 
    132 inline ObjPtr<mirror::Class> ClassLinker::ResolveType(dex::TypeIndex type_idx,
    133                                                       ArtField* referrer) {
    134   Thread::PoisonObjectPointersIfDebug();
    135   DCHECK(!Thread::Current()->IsExceptionPending());
    136   // We do not need the read barrier for getting the DexCache for the initial resolved type
    137   // lookup as both from-space and to-space copies point to the same native resolved types array.
    138   ObjPtr<mirror::Class> resolved_type =
    139       referrer->GetDexCache<kWithoutReadBarrier>()->GetResolvedType(type_idx);
    140   if (UNLIKELY(resolved_type == nullptr)) {
    141     resolved_type = DoResolveType(type_idx, referrer);
    142   }
    143   return resolved_type;
    144 }
    145 
    146 inline ObjPtr<mirror::Class> ClassLinker::ResolveType(dex::TypeIndex type_idx,
    147                                                       ArtMethod* referrer) {
    148   Thread::PoisonObjectPointersIfDebug();
    149   DCHECK(!Thread::Current()->IsExceptionPending());
    150   // We do not need the read barrier for getting the DexCache for the initial resolved type
    151   // lookup as both from-space and to-space copies point to the same native resolved types array.
    152   ObjPtr<mirror::Class> resolved_type =
    153       referrer->GetDexCache<kWithoutReadBarrier>()->GetResolvedType(type_idx);
    154   if (UNLIKELY(resolved_type == nullptr)) {
    155     resolved_type = DoResolveType(type_idx, referrer);
    156   }
    157   return resolved_type;
    158 }
    159 
    160 inline ObjPtr<mirror::Class> ClassLinker::ResolveType(dex::TypeIndex type_idx,
    161                                                       Handle<mirror::DexCache> dex_cache,
    162                                                       Handle<mirror::ClassLoader> class_loader) {
    163   DCHECK(dex_cache != nullptr);
    164   Thread::PoisonObjectPointersIfDebug();
    165   ObjPtr<mirror::Class> resolved = dex_cache->GetResolvedType(type_idx);
    166   if (resolved == nullptr) {
    167     resolved = DoResolveType(type_idx, dex_cache, class_loader);
    168   }
    169   return resolved;
    170 }
    171 
    172 inline ObjPtr<mirror::Class> ClassLinker::LookupResolvedType(dex::TypeIndex type_idx,
    173                                                              ObjPtr<mirror::Class> referrer) {
    174   // We do not need the read barrier for getting the DexCache for the initial resolved type
    175   // lookup as both from-space and to-space copies point to the same native resolved types array.
    176   ObjPtr<mirror::Class> type =
    177       referrer->GetDexCache<kDefaultVerifyFlags, kWithoutReadBarrier>()->GetResolvedType(type_idx);
    178   if (type == nullptr) {
    179     type = DoLookupResolvedType(type_idx, referrer);
    180   }
    181   return type;
    182 }
    183 
    184 inline ObjPtr<mirror::Class> ClassLinker::LookupResolvedType(dex::TypeIndex type_idx,
    185                                                              ArtField* referrer) {
    186   // We do not need the read barrier for getting the DexCache for the initial resolved type
    187   // lookup as both from-space and to-space copies point to the same native resolved types array.
    188   ObjPtr<mirror::Class> type =
    189       referrer->GetDexCache<kWithoutReadBarrier>()->GetResolvedType(type_idx);
    190   if (type == nullptr) {
    191     type = DoLookupResolvedType(type_idx, referrer->GetDeclaringClass());
    192   }
    193   return type;
    194 }
    195 
    196 inline ObjPtr<mirror::Class> ClassLinker::LookupResolvedType(dex::TypeIndex type_idx,
    197                                                              ArtMethod* referrer) {
    198   // We do not need the read barrier for getting the DexCache for the initial resolved type
    199   // lookup as both from-space and to-space copies point to the same native resolved types array.
    200   ObjPtr<mirror::Class> type =
    201       referrer->GetDexCache<kWithoutReadBarrier>()->GetResolvedType(type_idx);
    202   if (type == nullptr) {
    203     type = DoLookupResolvedType(type_idx, referrer->GetDeclaringClass());
    204   }
    205   return type;
    206 }
    207 
    208 inline ObjPtr<mirror::Class> ClassLinker::LookupResolvedType(
    209     dex::TypeIndex type_idx,
    210     ObjPtr<mirror::DexCache> dex_cache,
    211     ObjPtr<mirror::ClassLoader> class_loader) {
    212   ObjPtr<mirror::Class> type = dex_cache->GetResolvedType(type_idx);
    213   if (type == nullptr) {
    214     type = DoLookupResolvedType(type_idx, dex_cache, class_loader);
    215   }
    216   return type;
    217 }
    218 
    219 template <bool kThrowOnError, typename ClassGetter>
    220 inline bool ClassLinker::CheckInvokeClassMismatch(ObjPtr<mirror::DexCache> dex_cache,
    221                                                   InvokeType type,
    222                                                   ClassGetter class_getter) {
    223   switch (type) {
    224     case kStatic:
    225     case kSuper:
    226       break;
    227     case kInterface: {
    228       // We have to check whether the method id really belongs to an interface (dex static bytecode
    229       // constraints A15, A16). Otherwise you must not invoke-interface on it.
    230       ObjPtr<mirror::Class> klass = class_getter();
    231       if (UNLIKELY(!klass->IsInterface())) {
    232         if (kThrowOnError) {
    233           ThrowIncompatibleClassChangeError(klass,
    234                                             "Found class %s, but interface was expected",
    235                                             klass->PrettyDescriptor().c_str());
    236         }
    237         return true;
    238       }
    239       break;
    240     }
    241     case kDirect:
    242       if (dex_cache->GetDexFile()->SupportsDefaultMethods()) {
    243         break;
    244       }
    245       FALLTHROUGH_INTENDED;
    246     case kVirtual: {
    247       // Similarly, invoke-virtual (and invoke-direct without default methods) must reference
    248       // a non-interface class (dex static bytecode constraint A24, A25).
    249       ObjPtr<mirror::Class> klass = class_getter();
    250       if (UNLIKELY(klass->IsInterface())) {
    251         if (kThrowOnError) {
    252           ThrowIncompatibleClassChangeError(klass,
    253                                             "Found interface %s, but class was expected",
    254                                             klass->PrettyDescriptor().c_str());
    255         }
    256         return true;
    257       }
    258       break;
    259     }
    260     default:
    261       LOG(FATAL) << "Unreachable - invocation type: " << type;
    262       UNREACHABLE();
    263   }
    264   return false;
    265 }
    266 
    267 template <bool kThrow>
    268 inline bool ClassLinker::CheckInvokeClassMismatch(ObjPtr<mirror::DexCache> dex_cache,
    269                                                   InvokeType type,
    270                                                   uint32_t method_idx,
    271                                                   ObjPtr<mirror::ClassLoader> class_loader) {
    272   return CheckInvokeClassMismatch<kThrow>(
    273       dex_cache,
    274       type,
    275       [this, dex_cache, method_idx, class_loader]() REQUIRES_SHARED(Locks::mutator_lock_) {
    276         const dex::MethodId& method_id = dex_cache->GetDexFile()->GetMethodId(method_idx);
    277         ObjPtr<mirror::Class> klass =
    278             LookupResolvedType(method_id.class_idx_, dex_cache, class_loader);
    279         DCHECK(klass != nullptr);
    280         return klass;
    281       });
    282 }
    283 
    284 inline ArtMethod* ClassLinker::LookupResolvedMethod(uint32_t method_idx,
    285                                                     ObjPtr<mirror::DexCache> dex_cache,
    286                                                     ObjPtr<mirror::ClassLoader> class_loader) {
    287   PointerSize pointer_size = image_pointer_size_;
    288   ArtMethod* resolved = dex_cache->GetResolvedMethod(method_idx, pointer_size);
    289   if (resolved == nullptr) {
    290     const DexFile& dex_file = *dex_cache->GetDexFile();
    291     const dex::MethodId& method_id = dex_file.GetMethodId(method_idx);
    292     ObjPtr<mirror::Class> klass = LookupResolvedType(method_id.class_idx_, dex_cache, class_loader);
    293     if (klass != nullptr) {
    294       resolved = FindResolvedMethod(klass, dex_cache, class_loader, method_idx);
    295     }
    296   }
    297   return resolved;
    298 }
    299 
    300 template <InvokeType type, ClassLinker::ResolveMode kResolveMode>
    301 inline ArtMethod* ClassLinker::GetResolvedMethod(uint32_t method_idx, ArtMethod* referrer) {
    302   DCHECK(referrer != nullptr);
    303   // Note: The referrer can be a Proxy constructor. In that case, we need to do the
    304   // lookup in the context of the original method from where it steals the code.
    305   // However, we delay the GetInterfaceMethodIfProxy() until needed.
    306   DCHECK(!referrer->IsProxyMethod() || referrer->IsConstructor());
    307   // We do not need the read barrier for getting the DexCache for the initial resolved method
    308   // lookup as both from-space and to-space copies point to the same native resolved methods array.
    309   ArtMethod* resolved_method = referrer->GetDexCache<kWithoutReadBarrier>()->GetResolvedMethod(
    310       method_idx, image_pointer_size_);
    311   if (resolved_method == nullptr) {
    312     return nullptr;
    313   }
    314   DCHECK(!resolved_method->IsRuntimeMethod());
    315   if (kResolveMode == ResolveMode::kCheckICCEAndIAE) {
    316     referrer = referrer->GetInterfaceMethodIfProxy(image_pointer_size_);
    317     // Check if the invoke type matches the class type.
    318     ObjPtr<mirror::DexCache> dex_cache = referrer->GetDexCache();
    319     ObjPtr<mirror::ClassLoader> class_loader = referrer->GetClassLoader();
    320     if (CheckInvokeClassMismatch</* kThrow= */ false>(dex_cache, type, method_idx, class_loader)) {
    321       return nullptr;
    322     }
    323     // Check access.
    324     ObjPtr<mirror::Class> referring_class = referrer->GetDeclaringClass();
    325     if (!referring_class->CanAccessResolvedMethod(resolved_method->GetDeclaringClass(),
    326                                                   resolved_method,
    327                                                   dex_cache,
    328                                                   method_idx)) {
    329       return nullptr;
    330     }
    331     // Check if the invoke type matches the method type.
    332     if (UNLIKELY(resolved_method->CheckIncompatibleClassChange(type))) {
    333       return nullptr;
    334     }
    335   }
    336   return resolved_method;
    337 }
    338 
    339 template <ClassLinker::ResolveMode kResolveMode>
    340 inline ArtMethod* ClassLinker::ResolveMethod(Thread* self,
    341                                              uint32_t method_idx,
    342                                              ArtMethod* referrer,
    343                                              InvokeType type) {
    344   DCHECK(referrer != nullptr);
    345   // Note: The referrer can be a Proxy constructor. In that case, we need to do the
    346   // lookup in the context of the original method from where it steals the code.
    347   // However, we delay the GetInterfaceMethodIfProxy() until needed.
    348   DCHECK(!referrer->IsProxyMethod() || referrer->IsConstructor());
    349   Thread::PoisonObjectPointersIfDebug();
    350   // We do not need the read barrier for getting the DexCache for the initial resolved method
    351   // lookup as both from-space and to-space copies point to the same native resolved methods array.
    352   ArtMethod* resolved_method = referrer->GetDexCache<kWithoutReadBarrier>()->GetResolvedMethod(
    353       method_idx, image_pointer_size_);
    354   DCHECK(resolved_method == nullptr || !resolved_method->IsRuntimeMethod());
    355   if (UNLIKELY(resolved_method == nullptr)) {
    356     referrer = referrer->GetInterfaceMethodIfProxy(image_pointer_size_);
    357     ObjPtr<mirror::Class> declaring_class = referrer->GetDeclaringClass();
    358     StackHandleScope<2> hs(self);
    359     Handle<mirror::DexCache> h_dex_cache(hs.NewHandle(referrer->GetDexCache()));
    360     Handle<mirror::ClassLoader> h_class_loader(hs.NewHandle(declaring_class->GetClassLoader()));
    361     resolved_method = ResolveMethod<kResolveMode>(method_idx,
    362                                                   h_dex_cache,
    363                                                   h_class_loader,
    364                                                   referrer,
    365                                                   type);
    366   } else if (kResolveMode == ResolveMode::kCheckICCEAndIAE) {
    367     referrer = referrer->GetInterfaceMethodIfProxy(image_pointer_size_);
    368     // Check if the invoke type matches the class type.
    369     ObjPtr<mirror::DexCache> dex_cache = referrer->GetDexCache();
    370     ObjPtr<mirror::ClassLoader> class_loader = referrer->GetClassLoader();
    371     if (CheckInvokeClassMismatch</* kThrow= */ true>(dex_cache, type, method_idx, class_loader)) {
    372       DCHECK(Thread::Current()->IsExceptionPending());
    373       return nullptr;
    374     }
    375     // Check access.
    376     ObjPtr<mirror::Class> referring_class = referrer->GetDeclaringClass();
    377     if (!referring_class->CheckResolvedMethodAccess(resolved_method->GetDeclaringClass(),
    378                                                     resolved_method,
    379                                                     dex_cache,
    380                                                     method_idx,
    381                                                     type)) {
    382       DCHECK(Thread::Current()->IsExceptionPending());
    383       return nullptr;
    384     }
    385     // Check if the invoke type matches the method type.
    386     if (UNLIKELY(resolved_method->CheckIncompatibleClassChange(type))) {
    387       ThrowIncompatibleClassChangeError(type,
    388                                         resolved_method->GetInvokeType(),
    389                                         resolved_method,
    390                                         referrer);
    391       return nullptr;
    392     }
    393   }
    394   // Note: We cannot check here to see whether we added the method to the cache. It
    395   //       might be an erroneous class, which results in it being hidden from us.
    396   return resolved_method;
    397 }
    398 
    399 inline ArtField* ClassLinker::LookupResolvedField(uint32_t field_idx,
    400                                                   ArtMethod* referrer,
    401                                                   bool is_static) {
    402   // We do not need the read barrier for getting the DexCache for the initial resolved field
    403   // lookup as both from-space and to-space copies point to the same native resolved fields array.
    404   ArtField* field = referrer->GetDexCache<kWithoutReadBarrier>()->GetResolvedField(
    405       field_idx, image_pointer_size_);
    406   if (field == nullptr) {
    407     ObjPtr<mirror::ClassLoader> class_loader = referrer->GetDeclaringClass()->GetClassLoader();
    408     field = LookupResolvedField(field_idx, referrer->GetDexCache(), class_loader, is_static);
    409   }
    410   return field;
    411 }
    412 
    413 inline ArtField* ClassLinker::ResolveField(uint32_t field_idx,
    414                                            ArtMethod* referrer,
    415                                            bool is_static) {
    416   Thread::PoisonObjectPointersIfDebug();
    417   // We do not need the read barrier for getting the DexCache for the initial resolved field
    418   // lookup as both from-space and to-space copies point to the same native resolved fields array.
    419   ArtField* resolved_field = referrer->GetDexCache<kWithoutReadBarrier>()->GetResolvedField(
    420       field_idx, image_pointer_size_);
    421   if (UNLIKELY(resolved_field == nullptr)) {
    422     StackHandleScope<2> hs(Thread::Current());
    423     ObjPtr<mirror::Class> referring_class = referrer->GetDeclaringClass();
    424     Handle<mirror::DexCache> dex_cache(hs.NewHandle(referrer->GetDexCache()));
    425     Handle<mirror::ClassLoader> class_loader(hs.NewHandle(referring_class->GetClassLoader()));
    426     resolved_field = ResolveField(field_idx, dex_cache, class_loader, is_static);
    427     // Note: We cannot check here to see whether we added the field to the cache. The type
    428     //       might be an erroneous class, which results in it being hidden from us.
    429   }
    430   return resolved_field;
    431 }
    432 
    433 template <class Visitor>
    434 inline void ClassLinker::VisitClassTables(const Visitor& visitor) {
    435   Thread* const self = Thread::Current();
    436   WriterMutexLock mu(self, *Locks::classlinker_classes_lock_);
    437   for (const ClassLoaderData& data : class_loaders_) {
    438     if (data.class_table != nullptr) {
    439       visitor(data.class_table);
    440     }
    441   }
    442 }
    443 
    444 template <ReadBarrierOption kReadBarrierOption>
    445 inline ObjPtr<mirror::ObjectArray<mirror::Class>> ClassLinker::GetClassRoots() {
    446   ObjPtr<mirror::ObjectArray<mirror::Class>> class_roots =
    447       class_roots_.Read<kReadBarrierOption>();
    448   DCHECK(class_roots != nullptr);
    449   return class_roots;
    450 }
    451 
    452 }  // namespace art
    453 
    454 #endif  // ART_RUNTIME_CLASS_LINKER_INL_H_
    455