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