• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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