Home | History | Annotate | Download | only in mirror
      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_MIRROR_DEX_CACHE_H_
     18 #define ART_RUNTIME_MIRROR_DEX_CACHE_H_
     19 
     20 #include "array.h"
     21 #include "art_field.h"
     22 #include "art_method.h"
     23 #include "class.h"
     24 #include "object.h"
     25 #include "object_array.h"
     26 
     27 namespace art {
     28 
     29 struct DexCacheOffsets;
     30 class DexFile;
     31 class ImageWriter;
     32 union JValue;
     33 
     34 namespace mirror {
     35 
     36 class String;
     37 
     38 // C++ mirror of java.lang.DexCache.
     39 class MANAGED DexCache FINAL : public Object {
     40  public:
     41   // Size of java.lang.DexCache.class.
     42   static uint32_t ClassSize(size_t pointer_size);
     43 
     44   // Size of an instance of java.lang.DexCache not including referenced values.
     45   static constexpr uint32_t InstanceSize() {
     46     return sizeof(DexCache);
     47   }
     48 
     49   void Init(const DexFile* dex_file,
     50             String* location,
     51             GcRoot<String>* strings,
     52             uint32_t num_strings,
     53             GcRoot<Class>* resolved_types,
     54             uint32_t num_resolved_types,
     55             ArtMethod** resolved_methods,
     56             uint32_t num_resolved_methods,
     57             ArtField** resolved_fields,
     58             uint32_t num_resolved_fields,
     59             size_t pointer_size) SHARED_REQUIRES(Locks::mutator_lock_);
     60 
     61   void Fixup(ArtMethod* trampoline, size_t pointer_size)
     62       SHARED_REQUIRES(Locks::mutator_lock_);
     63 
     64   template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier, typename Visitor>
     65   void FixupStrings(GcRoot<mirror::String>* dest, const Visitor& visitor)
     66       SHARED_REQUIRES(Locks::mutator_lock_);
     67 
     68   template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier, typename Visitor>
     69   void FixupResolvedTypes(GcRoot<mirror::Class>* dest, const Visitor& visitor)
     70       SHARED_REQUIRES(Locks::mutator_lock_);
     71 
     72   String* GetLocation() SHARED_REQUIRES(Locks::mutator_lock_) {
     73     return GetFieldObject<String>(OFFSET_OF_OBJECT_MEMBER(DexCache, location_));
     74   }
     75 
     76   static MemberOffset DexOffset() {
     77     return OFFSET_OF_OBJECT_MEMBER(DexCache, dex_);
     78   }
     79 
     80   static MemberOffset StringsOffset() {
     81     return OFFSET_OF_OBJECT_MEMBER(DexCache, strings_);
     82   }
     83 
     84   static MemberOffset ResolvedTypesOffset() {
     85     return OFFSET_OF_OBJECT_MEMBER(DexCache, resolved_types_);
     86   }
     87 
     88   static MemberOffset ResolvedFieldsOffset() {
     89     return OFFSET_OF_OBJECT_MEMBER(DexCache, resolved_fields_);
     90   }
     91 
     92   static MemberOffset ResolvedMethodsOffset() {
     93     return OFFSET_OF_OBJECT_MEMBER(DexCache, resolved_methods_);
     94   }
     95 
     96   static MemberOffset NumStringsOffset() {
     97     return OFFSET_OF_OBJECT_MEMBER(DexCache, num_strings_);
     98   }
     99 
    100   static MemberOffset NumResolvedTypesOffset() {
    101     return OFFSET_OF_OBJECT_MEMBER(DexCache, num_resolved_types_);
    102   }
    103 
    104   static MemberOffset NumResolvedFieldsOffset() {
    105     return OFFSET_OF_OBJECT_MEMBER(DexCache, num_resolved_fields_);
    106   }
    107 
    108   static MemberOffset NumResolvedMethodsOffset() {
    109     return OFFSET_OF_OBJECT_MEMBER(DexCache, num_resolved_methods_);
    110   }
    111 
    112   String* GetResolvedString(uint32_t string_idx) ALWAYS_INLINE
    113       SHARED_REQUIRES(Locks::mutator_lock_);
    114 
    115   void SetResolvedString(uint32_t string_idx, String* resolved) ALWAYS_INLINE
    116       SHARED_REQUIRES(Locks::mutator_lock_);
    117 
    118   Class* GetResolvedType(uint32_t type_idx) SHARED_REQUIRES(Locks::mutator_lock_);
    119 
    120   void SetResolvedType(uint32_t type_idx, Class* resolved) SHARED_REQUIRES(Locks::mutator_lock_);
    121 
    122   ALWAYS_INLINE ArtMethod* GetResolvedMethod(uint32_t method_idx, size_t ptr_size)
    123       SHARED_REQUIRES(Locks::mutator_lock_);
    124 
    125   ALWAYS_INLINE void SetResolvedMethod(uint32_t method_idx, ArtMethod* resolved, size_t ptr_size)
    126       SHARED_REQUIRES(Locks::mutator_lock_);
    127 
    128   // Pointer sized variant, used for patching.
    129   ALWAYS_INLINE ArtField* GetResolvedField(uint32_t idx, size_t ptr_size)
    130       SHARED_REQUIRES(Locks::mutator_lock_);
    131 
    132   // Pointer sized variant, used for patching.
    133   ALWAYS_INLINE void SetResolvedField(uint32_t idx, ArtField* field, size_t ptr_size)
    134       SHARED_REQUIRES(Locks::mutator_lock_);
    135 
    136   GcRoot<String>* GetStrings() ALWAYS_INLINE SHARED_REQUIRES(Locks::mutator_lock_) {
    137     return GetFieldPtr<GcRoot<String>*>(StringsOffset());
    138   }
    139 
    140   void SetStrings(GcRoot<String>* strings) ALWAYS_INLINE SHARED_REQUIRES(Locks::mutator_lock_) {
    141     SetFieldPtr<false>(StringsOffset(), strings);
    142   }
    143 
    144   GcRoot<Class>* GetResolvedTypes() ALWAYS_INLINE SHARED_REQUIRES(Locks::mutator_lock_) {
    145     return GetFieldPtr<GcRoot<Class>*>(ResolvedTypesOffset());
    146   }
    147 
    148   void SetResolvedTypes(GcRoot<Class>* resolved_types)
    149       ALWAYS_INLINE
    150       SHARED_REQUIRES(Locks::mutator_lock_) {
    151     SetFieldPtr<false>(ResolvedTypesOffset(), resolved_types);
    152   }
    153 
    154   ArtMethod** GetResolvedMethods() ALWAYS_INLINE SHARED_REQUIRES(Locks::mutator_lock_) {
    155     return GetFieldPtr<ArtMethod**>(ResolvedMethodsOffset());
    156   }
    157 
    158   void SetResolvedMethods(ArtMethod** resolved_methods)
    159       ALWAYS_INLINE
    160       SHARED_REQUIRES(Locks::mutator_lock_) {
    161     SetFieldPtr<false>(ResolvedMethodsOffset(), resolved_methods);
    162   }
    163 
    164   ArtField** GetResolvedFields() ALWAYS_INLINE SHARED_REQUIRES(Locks::mutator_lock_) {
    165     return GetFieldPtr<ArtField**>(ResolvedFieldsOffset());
    166   }
    167 
    168   void SetResolvedFields(ArtField** resolved_fields)
    169       ALWAYS_INLINE
    170       SHARED_REQUIRES(Locks::mutator_lock_) {
    171     SetFieldPtr<false>(ResolvedFieldsOffset(), resolved_fields);
    172   }
    173 
    174   size_t NumStrings() SHARED_REQUIRES(Locks::mutator_lock_) {
    175     return GetField32(NumStringsOffset());
    176   }
    177 
    178   size_t NumResolvedTypes() SHARED_REQUIRES(Locks::mutator_lock_) {
    179     return GetField32(NumResolvedTypesOffset());
    180   }
    181 
    182   size_t NumResolvedMethods() SHARED_REQUIRES(Locks::mutator_lock_) {
    183     return GetField32(NumResolvedMethodsOffset());
    184   }
    185 
    186   size_t NumResolvedFields() SHARED_REQUIRES(Locks::mutator_lock_) {
    187     return GetField32(NumResolvedFieldsOffset());
    188   }
    189 
    190   const DexFile* GetDexFile() ALWAYS_INLINE SHARED_REQUIRES(Locks::mutator_lock_) {
    191     return GetFieldPtr<const DexFile*>(OFFSET_OF_OBJECT_MEMBER(DexCache, dex_file_));
    192   }
    193 
    194   void SetDexFile(const DexFile* dex_file) SHARED_REQUIRES(Locks::mutator_lock_) {
    195     SetFieldPtr<false>(OFFSET_OF_OBJECT_MEMBER(DexCache, dex_file_), dex_file);
    196   }
    197 
    198   void SetLocation(mirror::String* location) SHARED_REQUIRES(Locks::mutator_lock_);
    199 
    200   // NOTE: Get/SetElementPtrSize() are intended for working with ArtMethod** and ArtField**
    201   // provided by GetResolvedMethods/Fields() and ArtMethod::GetDexCacheResolvedMethods(),
    202   // so they need to be public.
    203 
    204   template <typename PtrType>
    205   static PtrType GetElementPtrSize(PtrType* ptr_array, size_t idx, size_t ptr_size);
    206 
    207   template <typename PtrType>
    208   static void SetElementPtrSize(PtrType* ptr_array, size_t idx, PtrType ptr, size_t ptr_size);
    209 
    210  private:
    211   // Visit instance fields of the dex cache as well as its associated arrays.
    212   template <bool kVisitNativeRoots,
    213             VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
    214             ReadBarrierOption kReadBarrierOption = kWithReadBarrier,
    215             typename Visitor>
    216   void VisitReferences(mirror::Class* klass, const Visitor& visitor)
    217       SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(Locks::heap_bitmap_lock_);
    218 
    219   HeapReference<Object> dex_;
    220   HeapReference<String> location_;
    221   uint64_t dex_file_;           // const DexFile*
    222   uint64_t resolved_fields_;    // ArtField*, array with num_resolved_fields_ elements.
    223   uint64_t resolved_methods_;   // ArtMethod*, array with num_resolved_methods_ elements.
    224   uint64_t resolved_types_;     // GcRoot<Class>*, array with num_resolved_types_ elements.
    225   uint64_t strings_;            // GcRoot<String>*, array with num_strings_ elements.
    226   uint32_t num_resolved_fields_;    // Number of elements in the resolved_fields_ array.
    227   uint32_t num_resolved_methods_;   // Number of elements in the resolved_methods_ array.
    228   uint32_t num_resolved_types_;     // Number of elements in the resolved_types_ array.
    229   uint32_t num_strings_;            // Number of elements in the strings_ array.
    230 
    231   friend struct art::DexCacheOffsets;  // for verifying offset information
    232   friend class Object;  // For VisitReferences
    233   DISALLOW_IMPLICIT_CONSTRUCTORS(DexCache);
    234 };
    235 
    236 }  // namespace mirror
    237 }  // namespace art
    238 
    239 #endif  // ART_RUNTIME_MIRROR_DEX_CACHE_H_
    240