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 "reg_type.h" 24 #include "runtime.h" 25 26 #include <stdint.h> 27 #include <vector> 28 29 namespace art { 30 namespace mirror { 31 class Class; 32 class ClassLoader; 33 } // namespace mirror 34 namespace verifier { 35 36 class RegType; 37 38 const size_t kNumPrimitives = 12; 39 class RegTypeCache { 40 public: RegTypeCache(bool can_load_classes)41 explicit RegTypeCache(bool can_load_classes) : can_load_classes_(can_load_classes) { 42 entries_.reserve(64); 43 FillPrimitiveTypes(); 44 } 45 ~RegTypeCache(); Init()46 static void Init() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 47 if (!RegTypeCache::primitive_initialized_) { 48 CHECK_EQ(RegTypeCache::primitive_count_, 0); 49 CreatePrimitiveTypes(); 50 CHECK_EQ(RegTypeCache::primitive_count_, kNumPrimitives); 51 RegTypeCache::primitive_initialized_ = true; 52 } 53 } 54 static void ShutDown(); 55 const art::verifier::RegType& GetFromId(uint16_t id) const; 56 const RegType& From(mirror::ClassLoader* loader, const char* descriptor, bool precise) 57 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 58 template <class Type> 59 static Type* CreatePrimitiveTypeInstance(const std::string& descriptor) 60 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 61 void FillPrimitiveTypes() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 62 const RegType& FromClass(const char* descriptor, mirror::Class* klass, bool precise) 63 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 64 const RegType& FromCat1Const(int32_t value, bool precise) 65 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 66 const RegType& FromCat2ConstLo(int32_t value, bool precise) 67 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 68 const RegType& FromCat2ConstHi(int32_t value, bool precise) 69 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 70 const RegType& FromDescriptor(mirror::ClassLoader* loader, const char* descriptor, bool precise) 71 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 72 const RegType& FromUnresolvedMerge(const RegType& left, const RegType& right) 73 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 74 const RegType& FromUnresolvedSuperClass(const RegType& child) 75 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); JavaLangString()76 const RegType& JavaLangString() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 77 // String is final and therefore always precise. 78 return From(NULL, "Ljava/lang/String;", true); 79 } JavaLangThrowable(bool precise)80 const RegType& JavaLangThrowable(bool precise) 81 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 82 return From(NULL, "Ljava/lang/Throwable;", precise); 83 } Zero()84 const RegType& Zero() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 85 return FromCat1Const(0, true); 86 } GetCacheSize()87 size_t GetCacheSize() { 88 return entries_.size(); 89 } Boolean()90 const RegType& Boolean() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 91 return *BooleanType::GetInstance(); 92 } Byte()93 const RegType& Byte() { 94 return *ByteType::GetInstance(); 95 } Char()96 const RegType& Char() { 97 return *CharType::GetInstance(); 98 } Short()99 const RegType& Short() { 100 return *ShortType::GetInstance(); 101 } Integer()102 const RegType& Integer() { 103 return *IntegerType::GetInstance(); 104 } Float()105 const RegType& Float() { 106 return *FloatType::GetInstance(); 107 } LongLo()108 const RegType& LongLo() { 109 return *LongLoType::GetInstance(); 110 } LongHi()111 const RegType& LongHi() { 112 return *LongHiType::GetInstance(); 113 } DoubleLo()114 const RegType& DoubleLo() { 115 return *DoubleLoType::GetInstance(); 116 } DoubleHi()117 const RegType& DoubleHi() { 118 return *DoubleHiType::GetInstance(); 119 } Undefined()120 const RegType& Undefined() { 121 return *UndefinedType::GetInstance(); 122 } Conflict()123 const RegType& Conflict() { 124 return *ConflictType::GetInstance(); 125 } JavaLangClass(bool precise)126 const RegType& JavaLangClass(bool precise) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 127 return From(NULL, "Ljava/lang/Class;", precise); 128 } JavaLangObject(bool precise)129 const RegType& JavaLangObject(bool precise) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 130 return From(NULL, "Ljava/lang/Object;", precise); 131 } 132 const RegType& Uninitialized(const RegType& type, uint32_t allocation_pc) 133 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 134 // Create an uninitialized 'this' argument for the given type. 135 const RegType& UninitializedThisArgument(const RegType& type) 136 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 137 const RegType& FromUninitialized(const RegType& uninit_type) 138 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 139 const RegType& ByteConstant() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 140 const RegType& ShortConstant() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 141 const RegType& IntConstant() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 142 const RegType& GetComponentType(const RegType& array, mirror::ClassLoader* loader) 143 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 144 void Dump(std::ostream& os) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 145 const RegType& RegTypeFromPrimitiveType(Primitive::Type) const; 146 147 private: 148 std::vector<RegType*> entries_; 149 static bool primitive_initialized_; 150 static uint16_t primitive_start_; 151 static uint16_t primitive_count_; 152 static void CreatePrimitiveTypes() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 153 // Whether or not we're allowed to load classes. 154 const bool can_load_classes_; 155 mirror::Class* ResolveClass(const char* descriptor, mirror::ClassLoader* loader) 156 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 157 void ClearException(); 158 bool MatchDescriptor(size_t idx, const char* descriptor, bool precise) 159 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 160 DISALLOW_COPY_AND_ASSIGN(RegTypeCache); 161 }; 162 163 } // namespace verifier 164 } // namespace art 165 166 #endif // ART_RUNTIME_VERIFIER_REG_TYPE_CACHE_H_ 167