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