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 "base/casts.h" 21 #include "base/macros.h" 22 #include "base/stl_util.h" 23 #include "object_callbacks.h" 24 #include "reg_type.h" 25 #include "runtime.h" 26 27 #include <stdint.h> 28 #include <vector> 29 30 namespace art { 31 namespace mirror { 32 class Class; 33 class ClassLoader; 34 } // namespace mirror 35 class StringPiece; 36 37 namespace verifier { 38 39 class RegType; 40 41 class RegTypeCache { 42 public: 43 explicit RegTypeCache(bool can_load_classes); 44 ~RegTypeCache(); Init()45 static void Init() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 46 if (!RegTypeCache::primitive_initialized_) { 47 CHECK_EQ(RegTypeCache::primitive_count_, 0); 48 CreatePrimitiveAndSmallConstantTypes(); 49 CHECK_EQ(RegTypeCache::primitive_count_, kNumPrimitivesAndSmallConstants); 50 RegTypeCache::primitive_initialized_ = true; 51 } 52 } 53 static void ShutDown(); 54 const art::verifier::RegType& GetFromId(uint16_t id) const; 55 const RegType& From(mirror::ClassLoader* loader, const char* descriptor, bool precise) 56 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 57 const RegType& FromClass(const char* descriptor, mirror::Class* klass, bool precise) 58 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 59 const ConstantType& FromCat1Const(int32_t value, bool precise) 60 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 61 const ConstantType& FromCat2ConstLo(int32_t value, bool precise) 62 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 63 const ConstantType& FromCat2ConstHi(int32_t value, bool precise) 64 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 65 const RegType& FromDescriptor(mirror::ClassLoader* loader, const char* descriptor, bool precise) 66 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 67 const RegType& FromUnresolvedMerge(const RegType& left, const RegType& right) 68 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 69 const RegType& FromUnresolvedSuperClass(const RegType& child) 70 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); Zero()71 const ConstantType& Zero() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 72 return FromCat1Const(0, true); 73 } One()74 const ConstantType& One() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 75 return FromCat1Const(1, true); 76 } GetCacheSize()77 size_t GetCacheSize() { 78 return entries_.size(); 79 } Boolean()80 const BooleanType& Boolean() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 81 return *BooleanType::GetInstance(); 82 } Byte()83 const ByteType& Byte() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 84 return *ByteType::GetInstance(); 85 } Char()86 const CharType& Char() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 87 return *CharType::GetInstance(); 88 } Short()89 const ShortType& Short() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 90 return *ShortType::GetInstance(); 91 } Integer()92 const IntegerType& Integer() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 93 return *IntegerType::GetInstance(); 94 } Float()95 const FloatType& Float() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 96 return *FloatType::GetInstance(); 97 } LongLo()98 const LongLoType& LongLo() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 99 return *LongLoType::GetInstance(); 100 } LongHi()101 const LongHiType& LongHi() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 102 return *LongHiType::GetInstance(); 103 } DoubleLo()104 const DoubleLoType& DoubleLo() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 105 return *DoubleLoType::GetInstance(); 106 } DoubleHi()107 const DoubleHiType& DoubleHi() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 108 return *DoubleHiType::GetInstance(); 109 } Undefined()110 const UndefinedType& Undefined() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 111 return *UndefinedType::GetInstance(); 112 } Conflict()113 const ConflictType& Conflict() { 114 return *ConflictType::GetInstance(); 115 } 116 117 const PreciseReferenceType& JavaLangClass() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 118 const PreciseReferenceType& JavaLangString() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 119 const RegType& JavaLangThrowable(bool precise) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 120 const RegType& JavaLangObject(bool precise) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 121 122 const UninitializedType& Uninitialized(const RegType& type, uint32_t allocation_pc) 123 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 124 // Create an uninitialized 'this' argument for the given type. 125 const UninitializedType& UninitializedThisArgument(const RegType& type) 126 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 127 const RegType& FromUninitialized(const RegType& uninit_type) 128 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 129 const ImpreciseConstType& ByteConstant() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 130 const ImpreciseConstType& CharConstant() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 131 const ImpreciseConstType& ShortConstant() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 132 const ImpreciseConstType& IntConstant() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 133 const ImpreciseConstType& PosByteConstant() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 134 const ImpreciseConstType& PosShortConstant() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 135 const RegType& GetComponentType(const RegType& array, mirror::ClassLoader* loader) 136 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 137 void Dump(std::ostream& os) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 138 const RegType& RegTypeFromPrimitiveType(Primitive::Type) const; 139 140 void VisitRoots(RootVisitor* visitor, const RootInfo& root_info) 141 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 142 static void VisitStaticRoots(RootVisitor* visitor) 143 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 144 145 private: 146 void FillPrimitiveAndSmallConstantTypes() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 147 mirror::Class* ResolveClass(const char* descriptor, mirror::ClassLoader* loader) 148 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 149 bool MatchDescriptor(size_t idx, const StringPiece& descriptor, bool precise) 150 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 151 const ConstantType& FromCat1NonSmallConstant(int32_t value, bool precise) 152 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 153 154 void AddEntry(RegType* new_entry); 155 156 template <class Type> 157 static const Type* CreatePrimitiveTypeInstance(const std::string& descriptor) 158 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 159 static void CreatePrimitiveAndSmallConstantTypes() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 160 161 // A quick look up for popular small constants. 162 static constexpr int32_t kMinSmallConstant = -1; 163 static constexpr int32_t kMaxSmallConstant = 4; 164 static const PreciseConstType* small_precise_constants_[kMaxSmallConstant - kMinSmallConstant + 1]; 165 166 static constexpr size_t kNumPrimitivesAndSmallConstants = 167 12 + (kMaxSmallConstant - kMinSmallConstant + 1); 168 169 // Have the well known global primitives been created? 170 static bool primitive_initialized_; 171 172 // Number of well known primitives that will be copied into a RegTypeCache upon construction. 173 static uint16_t primitive_count_; 174 175 // The actual storage for the RegTypes. 176 std::vector<const RegType*> entries_; 177 178 // Whether or not we're allowed to load classes. 179 const bool can_load_classes_; 180 181 DISALLOW_COPY_AND_ASSIGN(RegTypeCache); 182 }; 183 184 } // namespace verifier 185 } // namespace art 186 187 #endif // ART_RUNTIME_VERIFIER_REG_TYPE_CACHE_H_ 188