1 /* 2 * Copyright (C) 2012 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_VERIFIER_REG_TYPE_CACHE_H_ 18 #define ART_RUNTIME_VERIFIER_REG_TYPE_CACHE_H_ 19 20 #include <stdint.h> 21 #include <string_view> 22 #include <vector> 23 24 #include "base/arena_containers.h" 25 #include "base/casts.h" 26 #include "base/macros.h" 27 #include "dex/primitive.h" 28 #include "gc_root.h" 29 #include "handle_scope.h" 30 #include "reg_type.h" 31 32 namespace art HIDDEN { 33 34 namespace mirror { 35 class Class; 36 class ClassLoader; 37 } // namespace mirror 38 39 class ClassLinker; 40 class DexFile; 41 42 namespace verifier { 43 44 class MethodVerifier; 45 46 // Use 8 bytes since that is the default arena allocator alignment. 47 static constexpr size_t kDefaultArenaBitVectorBytes = 8; 48 49 class RegTypeCache { 50 public: 51 EXPORT RegTypeCache(Thread* self, 52 ClassLinker* class_linker, 53 ArenaPool* arena_pool, 54 Handle<mirror::ClassLoader> class_loader, 55 const DexFile* dex_file, 56 bool can_load_classes = true, 57 bool can_suspend = true); 58 GetClassLoader()59 Handle<mirror::ClassLoader> GetClassLoader() const { 60 return class_loader_; 61 } 62 GetDexFile()63 const DexFile* GetDexFile() const { 64 return dex_file_; 65 } 66 CanLoadClasses()67 bool CanLoadClasses() const { 68 return can_load_classes_; 69 } 70 CanSuspend()71 bool CanSuspend() const { 72 return can_suspend_; 73 } 74 NumberOfRegKindCacheIds()75 static constexpr uint32_t NumberOfRegKindCacheIds() { return kNumberOfRegKindCacheIds; } 76 77 // Translate `RegType::Kind` to id for a pre-initialized register type. 78 // Cannot be used for non-zero reference kinds other than `JavaLangObject()`; all other 79 // kinds (undefined, conflict, primitive and constant kinds) have pre-initialized types. 80 static constexpr uint16_t IdForRegKind(RegType::Kind kind); 81 82 // Translate `id` to `RegType::Kind`. 83 // The `id` must be lower than `NumberOfRegKindCacheIds()`. 84 static constexpr RegType::Kind RegKindForId(uint16_t id); 85 86 // Get register type for a `RegType::Kind` with the same restrictions as `IdForRegKind()`. 87 const RegType& GetFromRegKind(RegType::Kind kind) const; 88 89 const RegType& GetFromId(uint16_t id) const; 90 // Get or insert a reg type for a klass. 91 const RegType& FromClass(ObjPtr<mirror::Class> klass) 92 REQUIRES_SHARED(Locks::mutator_lock_); 93 const RegType& FromDescriptor(const char* descriptor) 94 REQUIRES_SHARED(Locks::mutator_lock_); 95 const RegType& FromUnresolvedMerge(const RegType& left, 96 const RegType& right, 97 MethodVerifier* verifier) 98 REQUIRES_SHARED(Locks::mutator_lock_); 99 100 const RegType& FromTypeIndex(dex::TypeIndex type_index) REQUIRES_SHARED(Locks::mutator_lock_); 101 102 // Note: this should not be used outside of RegType::ClassJoin! 103 const RegType& MakeUnresolvedReference() REQUIRES_SHARED(Locks::mutator_lock_); 104 GetCacheSize()105 size_t GetCacheSize() { 106 return entries_.size(); 107 } 108 109 const UndefinedType& Undefined() const REQUIRES_SHARED(Locks::mutator_lock_); 110 const ConflictType& Conflict() const; 111 const NullType& Null() const; 112 113 const BooleanType& Boolean() const REQUIRES_SHARED(Locks::mutator_lock_); 114 const ByteType& Byte() const REQUIRES_SHARED(Locks::mutator_lock_); 115 const CharType& Char() const REQUIRES_SHARED(Locks::mutator_lock_); 116 const ShortType& Short() const REQUIRES_SHARED(Locks::mutator_lock_); 117 const IntegerType& Integer() const REQUIRES_SHARED(Locks::mutator_lock_); 118 const FloatType& Float() const REQUIRES_SHARED(Locks::mutator_lock_); 119 const LongLoType& LongLo() const REQUIRES_SHARED(Locks::mutator_lock_); 120 const LongHiType& LongHi() const REQUIRES_SHARED(Locks::mutator_lock_); 121 const DoubleLoType& DoubleLo() const REQUIRES_SHARED(Locks::mutator_lock_); 122 const DoubleHiType& DoubleHi() const REQUIRES_SHARED(Locks::mutator_lock_); 123 124 const ZeroType& Zero() const REQUIRES_SHARED(Locks::mutator_lock_); 125 const BooleanConstantType& BooleanConstant() const REQUIRES_SHARED(Locks::mutator_lock_); 126 const ByteConstantType& ByteConstant() const REQUIRES_SHARED(Locks::mutator_lock_); 127 const CharConstantType& CharConstant() const REQUIRES_SHARED(Locks::mutator_lock_); 128 const ShortConstantType& ShortConstant() const REQUIRES_SHARED(Locks::mutator_lock_); 129 const IntegerConstantType& IntegerConstant() const REQUIRES_SHARED(Locks::mutator_lock_); 130 const PositiveByteConstantType& PositiveByteConstant() const 131 REQUIRES_SHARED(Locks::mutator_lock_); 132 const PositiveShortConstantType& PositiveShortConstant() const 133 REQUIRES_SHARED(Locks::mutator_lock_); 134 const ConstantLoType& ConstantLo() const REQUIRES_SHARED(Locks::mutator_lock_); 135 const ConstantHiType& ConstantHi() const REQUIRES_SHARED(Locks::mutator_lock_); 136 137 const ReferenceType& JavaLangClass() REQUIRES_SHARED(Locks::mutator_lock_); 138 const ReferenceType& JavaLangString() REQUIRES_SHARED(Locks::mutator_lock_); 139 const ReferenceType& JavaLangInvokeMethodHandle() REQUIRES_SHARED(Locks::mutator_lock_); 140 const ReferenceType& JavaLangInvokeMethodType() REQUIRES_SHARED(Locks::mutator_lock_); 141 const ReferenceType& JavaLangThrowable() REQUIRES_SHARED(Locks::mutator_lock_); 142 const JavaLangObjectType& JavaLangObject() REQUIRES_SHARED(Locks::mutator_lock_); 143 144 const UninitializedType& Uninitialized(const RegType& type) 145 REQUIRES_SHARED(Locks::mutator_lock_); 146 // Create an uninitialized 'this' argument for the given type. 147 const UninitializedType& UninitializedThisArgument(const RegType& type) 148 REQUIRES_SHARED(Locks::mutator_lock_); 149 const RegType& FromUninitialized(const RegType& uninit_type) 150 REQUIRES_SHARED(Locks::mutator_lock_); 151 152 const RegType& GetComponentType(const RegType& array) REQUIRES_SHARED(Locks::mutator_lock_); 153 void Dump(std::ostream& os) REQUIRES_SHARED(Locks::mutator_lock_); 154 const RegType& RegTypeFromPrimitiveType(Primitive::Type) const 155 REQUIRES_SHARED(Locks::mutator_lock_); 156 GetClassLinker()157 ClassLinker* GetClassLinker() const { 158 return class_linker_; 159 } 160 161 static constexpr uint32_t kUndefinedCacheId = 0; 162 static constexpr uint32_t kConflictCacheId = kUndefinedCacheId + 1u; 163 static constexpr uint32_t kBooleanCacheId = kConflictCacheId + 1u; 164 static constexpr uint32_t kByteCacheId = kBooleanCacheId + 1u; 165 static constexpr uint32_t kCharCacheId = kByteCacheId + 1u; 166 static constexpr uint32_t kShortCacheId = kCharCacheId + 1u; 167 static constexpr uint32_t kIntegerCacheId = kShortCacheId + 1u; 168 static constexpr uint32_t kLongLoCacheId = kIntegerCacheId + 1u; 169 static constexpr uint32_t kLongHiCacheId = kLongLoCacheId + 1u; 170 static constexpr uint32_t kFloatCacheId = kLongHiCacheId + 1u; 171 static constexpr uint32_t kDoubleLoCacheId = kFloatCacheId + 1u; 172 static constexpr uint32_t kDoubleHiCacheId = kDoubleLoCacheId + 1u; 173 static constexpr uint32_t kZeroCacheId = kDoubleHiCacheId + 1u; 174 static constexpr uint32_t kBooleanConstantCacheId = kZeroCacheId + 1u; 175 static constexpr uint32_t kPositiveByteConstantCacheId = kBooleanConstantCacheId + 1u; 176 static constexpr uint32_t kPositiveShortConstantCacheId = kPositiveByteConstantCacheId + 1u; 177 static constexpr uint32_t kCharConstantCacheId = kPositiveShortConstantCacheId + 1u; 178 static constexpr uint32_t kByteConstantCacheId = kCharConstantCacheId + 1u; 179 static constexpr uint32_t kShortConstantCacheId = kByteConstantCacheId + 1u; 180 static constexpr uint32_t kIntegerConstantCacheId = kShortConstantCacheId + 1u; 181 static constexpr uint32_t kConstantLoCacheId = kIntegerConstantCacheId + 1u; 182 static constexpr uint32_t kConstantHiCacheId = kConstantLoCacheId + 1u; 183 static constexpr uint32_t kNullCacheId = kConstantHiCacheId + 1u; 184 static constexpr uint32_t kJavaLangObjectCacheId = kNullCacheId + 1u; 185 static constexpr uint32_t kNumberOfRegKindCacheIds = kJavaLangObjectCacheId + 1u; 186 187 static constexpr uint32_t kUninitializedJavaLangObjectCacheId = kNumberOfRegKindCacheIds; 188 static constexpr uint32_t kNumberOfFixedCacheIds = kUninitializedJavaLangObjectCacheId + 1u; 189 190 private: 191 // We want 0 to mean an empty slot in `ids_for_type_index_`, so that we do not need to fill 192 // the array after allocaing zero-initialized storage. This needs to correspond to a fixed 193 // cache id that cannot be returned for a type index, such as `kUndefinedCacheId`. 194 static constexpr uint32_t kNoIdForTypeIndex = 0u; 195 static_assert(kNoIdForTypeIndex == kUndefinedCacheId); 196 197 void FillPrimitiveAndConstantTypes() REQUIRES_SHARED(Locks::mutator_lock_); 198 ObjPtr<mirror::Class> ResolveClass(const char* descriptor, size_t descriptor_length) 199 REQUIRES_SHARED(Locks::mutator_lock_); 200 bool MatchDescriptor(size_t idx, const std::string_view& descriptor) 201 REQUIRES_SHARED(Locks::mutator_lock_); 202 203 const RegType& From(const char* descriptor) 204 REQUIRES_SHARED(Locks::mutator_lock_); 205 206 const RegType& FromTypeIndexUncached(dex::TypeIndex type_index) 207 REQUIRES_SHARED(Locks::mutator_lock_); 208 209 // Returns the pass in RegType. 210 template <class RegTypeType> 211 RegTypeType& AddEntry(RegTypeType* new_entry) REQUIRES_SHARED(Locks::mutator_lock_); 212 213 // Add a string to the arena allocator so that it stays live for the lifetime of the 214 // verifier and return a string view. 215 std::string_view AddString(const std::string_view& str); 216 217 // Arena allocator. 218 ArenaAllocator allocator_; 219 220 // The actual storage for the RegTypes. 221 ArenaVector<const RegType*> entries_; 222 223 // Fast lookup for quickly finding entries that have a matching class. 224 ArenaVector<std::pair<Handle<mirror::Class>, const RegType*>> klass_entries_; 225 226 // Handle scope containing classes. 227 VariableSizedHandleScope handles_; 228 229 ClassLinker* class_linker_; 230 Handle<mirror::ClassLoader> class_loader_; 231 const DexFile* const dex_file_; 232 233 // Fast lookup by type index. 234 uint16_t* const ids_for_type_index_; 235 236 // Cache last uninitialized "this" type used for constructors. 237 const UninitializedType* last_uninitialized_this_type_; 238 239 // Whether or not we're allowed to load classes. 240 const bool can_load_classes_; 241 242 // Whether or not we're allowed to suspend. 243 const bool can_suspend_; 244 245 DISALLOW_COPY_AND_ASSIGN(RegTypeCache); 246 }; 247 248 } // namespace verifier 249 } // namespace art 250 251 #endif // ART_RUNTIME_VERIFIER_REG_TYPE_CACHE_H_ 252