Home | History | Annotate | Download | only in mirror
      1 /*
      2  * Copyright (C) 2013 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_MIRROR_DEX_CACHE_INL_H_
     18 #define ART_RUNTIME_MIRROR_DEX_CACHE_INL_H_
     19 
     20 #include "dex_cache.h"
     21 
     22 #include "art_field-inl.h"
     23 #include "art_method-inl.h"
     24 #include "base/casts.h"
     25 #include "base/logging.h"
     26 #include "mirror/class.h"
     27 #include "runtime.h"
     28 
     29 namespace art {
     30 namespace mirror {
     31 
     32 inline uint32_t DexCache::ClassSize(size_t pointer_size) {
     33   uint32_t vtable_entries = Object::kVTableLength + 5;
     34   return Class::ComputeClassSize(true, vtable_entries, 0, 0, 0, 0, 0, pointer_size);
     35 }
     36 
     37 inline String* DexCache::GetResolvedString(uint32_t string_idx) {
     38   DCHECK_LT(string_idx, NumStrings());
     39   return GetStrings()[string_idx].Read();
     40 }
     41 
     42 inline void DexCache::SetResolvedString(uint32_t string_idx, String* resolved) {
     43   DCHECK_LT(string_idx, NumStrings());
     44   // TODO default transaction support.
     45   GetStrings()[string_idx] = GcRoot<String>(resolved);
     46   // TODO: Fine-grained marking, so that we don't need to go through all arrays in full.
     47   Runtime::Current()->GetHeap()->WriteBarrierEveryFieldOf(this);
     48 }
     49 
     50 inline Class* DexCache::GetResolvedType(uint32_t type_idx) {
     51   DCHECK_LT(type_idx, NumResolvedTypes());
     52   return GetResolvedTypes()[type_idx].Read();
     53 }
     54 
     55 inline void DexCache::SetResolvedType(uint32_t type_idx, Class* resolved) {
     56   DCHECK_LT(type_idx, NumResolvedTypes());  // NOTE: Unchecked, i.e. not throwing AIOOB.
     57   // TODO default transaction support.
     58   GetResolvedTypes()[type_idx] = GcRoot<Class>(resolved);
     59   // TODO: Fine-grained marking, so that we don't need to go through all arrays in full.
     60   Runtime::Current()->GetHeap()->WriteBarrierEveryFieldOf(this);
     61 }
     62 
     63 inline ArtField* DexCache::GetResolvedField(uint32_t field_idx, size_t ptr_size) {
     64   DCHECK_EQ(Runtime::Current()->GetClassLinker()->GetImagePointerSize(), ptr_size);
     65   DCHECK_LT(field_idx, NumResolvedFields());  // NOTE: Unchecked, i.e. not throwing AIOOB.
     66   ArtField* field = GetElementPtrSize(GetResolvedFields(), field_idx, ptr_size);
     67   if (field == nullptr || field->GetDeclaringClass()->IsErroneous()) {
     68     return nullptr;
     69   }
     70   return field;
     71 }
     72 
     73 inline void DexCache::SetResolvedField(uint32_t field_idx, ArtField* field, size_t ptr_size) {
     74   DCHECK_EQ(Runtime::Current()->GetClassLinker()->GetImagePointerSize(), ptr_size);
     75   DCHECK_LT(field_idx, NumResolvedFields());  // NOTE: Unchecked, i.e. not throwing AIOOB.
     76   SetElementPtrSize(GetResolvedFields(), field_idx, field, ptr_size);
     77 }
     78 
     79 inline ArtMethod* DexCache::GetResolvedMethod(uint32_t method_idx, size_t ptr_size) {
     80   DCHECK_EQ(Runtime::Current()->GetClassLinker()->GetImagePointerSize(), ptr_size);
     81   DCHECK_LT(method_idx, NumResolvedMethods());  // NOTE: Unchecked, i.e. not throwing AIOOB.
     82   ArtMethod* method = GetElementPtrSize<ArtMethod*>(GetResolvedMethods(), method_idx, ptr_size);
     83   // Hide resolution trampoline methods from the caller
     84   if (method != nullptr && method->IsRuntimeMethod()) {
     85     DCHECK_EQ(method, Runtime::Current()->GetResolutionMethod());
     86     return nullptr;
     87   }
     88   return method;
     89 }
     90 
     91 inline void DexCache::SetResolvedMethod(uint32_t method_idx, ArtMethod* method, size_t ptr_size) {
     92   DCHECK_EQ(Runtime::Current()->GetClassLinker()->GetImagePointerSize(), ptr_size);
     93   DCHECK_LT(method_idx, NumResolvedMethods());  // NOTE: Unchecked, i.e. not throwing AIOOB.
     94   SetElementPtrSize(GetResolvedMethods(), method_idx, method, ptr_size);
     95 }
     96 
     97 template <typename PtrType>
     98 inline PtrType DexCache::GetElementPtrSize(PtrType* ptr_array, size_t idx, size_t ptr_size) {
     99   if (ptr_size == 8u) {
    100     uint64_t element = reinterpret_cast<const uint64_t*>(ptr_array)[idx];
    101     return reinterpret_cast<PtrType>(dchecked_integral_cast<uintptr_t>(element));
    102   } else {
    103     DCHECK_EQ(ptr_size, 4u);
    104     uint32_t element = reinterpret_cast<const uint32_t*>(ptr_array)[idx];
    105     return reinterpret_cast<PtrType>(dchecked_integral_cast<uintptr_t>(element));
    106   }
    107 }
    108 
    109 template <typename PtrType>
    110 inline void DexCache::SetElementPtrSize(PtrType* ptr_array,
    111                                         size_t idx,
    112                                         PtrType ptr,
    113                                         size_t ptr_size) {
    114   if (ptr_size == 8u) {
    115     reinterpret_cast<uint64_t*>(ptr_array)[idx] =
    116         dchecked_integral_cast<uint64_t>(reinterpret_cast<uintptr_t>(ptr));
    117   } else {
    118     DCHECK_EQ(ptr_size, 4u);
    119     reinterpret_cast<uint32_t*>(ptr_array)[idx] =
    120         dchecked_integral_cast<uint32_t>(reinterpret_cast<uintptr_t>(ptr));
    121   }
    122 }
    123 
    124 template <bool kVisitNativeRoots,
    125           VerifyObjectFlags kVerifyFlags,
    126           ReadBarrierOption kReadBarrierOption,
    127           typename Visitor>
    128 inline void DexCache::VisitReferences(mirror::Class* klass, const Visitor& visitor) {
    129   // Visit instance fields first.
    130   VisitInstanceFieldsReferences<kVerifyFlags, kReadBarrierOption>(klass, visitor);
    131   // Visit arrays after.
    132   if (kVisitNativeRoots) {
    133     GcRoot<mirror::String>* strings = GetStrings();
    134     for (size_t i = 0, num_strings = NumStrings(); i != num_strings; ++i) {
    135       visitor.VisitRootIfNonNull(strings[i].AddressWithoutBarrier());
    136     }
    137     GcRoot<mirror::Class>* resolved_types = GetResolvedTypes();
    138     for (size_t i = 0, num_types = NumResolvedTypes(); i != num_types; ++i) {
    139       visitor.VisitRootIfNonNull(resolved_types[i].AddressWithoutBarrier());
    140     }
    141   }
    142 }
    143 
    144 template <ReadBarrierOption kReadBarrierOption, typename Visitor>
    145 inline void DexCache::FixupStrings(GcRoot<mirror::String>* dest, const Visitor& visitor) {
    146   GcRoot<mirror::String>* src = GetStrings();
    147   for (size_t i = 0, count = NumStrings(); i < count; ++i) {
    148     mirror::String* source = src[i].Read<kReadBarrierOption>();
    149     mirror::String* new_source = visitor(source);
    150     dest[i] = GcRoot<mirror::String>(new_source);
    151   }
    152 }
    153 
    154 template <ReadBarrierOption kReadBarrierOption, typename Visitor>
    155 inline void DexCache::FixupResolvedTypes(GcRoot<mirror::Class>* dest, const Visitor& visitor) {
    156   GcRoot<mirror::Class>* src = GetResolvedTypes();
    157   for (size_t i = 0, count = NumResolvedTypes(); i < count; ++i) {
    158     mirror::Class* source = src[i].Read<kReadBarrierOption>();
    159     mirror::Class* new_source = visitor(source);
    160     dest[i] = GcRoot<mirror::Class>(new_source);
    161   }
    162 }
    163 
    164 }  // namespace mirror
    165 }  // namespace art
    166 
    167 #endif  // ART_RUNTIME_MIRROR_DEX_CACHE_INL_H_
    168