Home | History | Annotate | Download | only in verifier
      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 
     30 namespace art {
     31 namespace mirror {
     32   class Class;
     33   class ClassLoader;
     34 }  // namespace mirror
     35 class StringPiece;
     36 
     37 namespace verifier {
     38 
     39 class RegType;
     40 
     41 class 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(RootVisitor* visitor, const RootInfo& root_info)
    141       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    142   static void VisitStaticRoots(RootVisitor* visitor)
    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