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