reg_type_cache.h revision 12d625f87bcd6c4059a205bb39007a255f57f382
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 {
32  class Class;
33  class ClassLoader;
34}  // namespace mirror
35class StringPiece;
36
37namespace verifier {
38
39class RegType;
40
41class RegTypeCache {
42 public:
43  explicit RegTypeCache(bool can_load_classes);
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 ConstantType& Zero() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
72    return FromCat1Const(0, true);
73  }
74  const ConstantType& One() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
75    return FromCat1Const(1, true);
76  }
77  size_t GetCacheSize() {
78    return entries_.size();
79  }
80  const BooleanType& Boolean() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
81    return *BooleanType::GetInstance();
82  }
83  const ByteType& Byte() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
84    return *ByteType::GetInstance();
85  }
86  const CharType& Char() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
87    return *CharType::GetInstance();
88  }
89  const ShortType& Short() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
90    return *ShortType::GetInstance();
91  }
92  const IntegerType& Integer() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
93    return *IntegerType::GetInstance();
94  }
95  const FloatType& Float() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
96    return *FloatType::GetInstance();
97  }
98  const LongLoType& LongLo() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
99    return *LongLoType::GetInstance();
100  }
101  const LongHiType& LongHi() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
102    return *LongHiType::GetInstance();
103  }
104  const DoubleLoType& DoubleLo() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
105    return *DoubleLoType::GetInstance();
106  }
107  const DoubleHiType& DoubleHi() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
108    return *DoubleHiType::GetInstance();
109  }
110  const UndefinedType& Undefined() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
111    return *UndefinedType::GetInstance();
112  }
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(RootCallback* callback, void* arg, const RootInfo& root_info)
141      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
142  static void VisitStaticRoots(RootCallback* callback, void* arg)
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