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/scoped_arena_containers.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 ScopedArenaAllocator;
     36 class StringPiece;
     37 
     38 namespace verifier {
     39 
     40 class RegType;
     41 
     42 // Use 8 bytes since that is the default arena allocator alignment.
     43 static constexpr size_t kDefaultArenaBitVectorBytes = 8;
     44 
     45 class RegTypeCache {
     46  public:
     47   explicit RegTypeCache(bool can_load_classes, ScopedArenaAllocator& arena);
     48   ~RegTypeCache();
     49   static void Init() SHARED_REQUIRES(Locks::mutator_lock_) {
     50     if (!RegTypeCache::primitive_initialized_) {
     51       CHECK_EQ(RegTypeCache::primitive_count_, 0);
     52       CreatePrimitiveAndSmallConstantTypes();
     53       CHECK_EQ(RegTypeCache::primitive_count_, kNumPrimitivesAndSmallConstants);
     54       RegTypeCache::primitive_initialized_ = true;
     55     }
     56   }
     57   static void ShutDown();
     58   const art::verifier::RegType& GetFromId(uint16_t id) const;
     59   const RegType& From(mirror::ClassLoader* loader, const char* descriptor, bool precise)
     60       SHARED_REQUIRES(Locks::mutator_lock_);
     61   // Find a RegType, returns null if not found.
     62   const RegType* FindClass(mirror::Class* klass, bool precise) const
     63       SHARED_REQUIRES(Locks::mutator_lock_);
     64   // Insert a new class with a specified descriptor, must not already be in the cache.
     65   const RegType* InsertClass(const StringPiece& descriptor, mirror::Class* klass, bool precise)
     66       SHARED_REQUIRES(Locks::mutator_lock_);
     67   // Get or insert a reg type for a description, klass, and precision.
     68   const RegType& FromClass(const char* descriptor, mirror::Class* klass, bool precise)
     69       SHARED_REQUIRES(Locks::mutator_lock_);
     70   const ConstantType& FromCat1Const(int32_t value, bool precise)
     71       SHARED_REQUIRES(Locks::mutator_lock_);
     72   const ConstantType& FromCat2ConstLo(int32_t value, bool precise)
     73       SHARED_REQUIRES(Locks::mutator_lock_);
     74   const ConstantType& FromCat2ConstHi(int32_t value, bool precise)
     75       SHARED_REQUIRES(Locks::mutator_lock_);
     76   const RegType& FromDescriptor(mirror::ClassLoader* loader, const char* descriptor, bool precise)
     77       SHARED_REQUIRES(Locks::mutator_lock_);
     78   const RegType& FromUnresolvedMerge(const RegType& left, const RegType& right)
     79       SHARED_REQUIRES(Locks::mutator_lock_);
     80   const RegType& FromUnresolvedSuperClass(const RegType& child)
     81       SHARED_REQUIRES(Locks::mutator_lock_);
     82   const ConstantType& Zero() SHARED_REQUIRES(Locks::mutator_lock_) {
     83     return FromCat1Const(0, true);
     84   }
     85   const ConstantType& One() SHARED_REQUIRES(Locks::mutator_lock_) {
     86     return FromCat1Const(1, true);
     87   }
     88   size_t GetCacheSize() {
     89     return entries_.size();
     90   }
     91   const BooleanType& Boolean() SHARED_REQUIRES(Locks::mutator_lock_) {
     92     return *BooleanType::GetInstance();
     93   }
     94   const ByteType& Byte() SHARED_REQUIRES(Locks::mutator_lock_) {
     95     return *ByteType::GetInstance();
     96   }
     97   const CharType& Char() SHARED_REQUIRES(Locks::mutator_lock_) {
     98     return *CharType::GetInstance();
     99   }
    100   const ShortType& Short() SHARED_REQUIRES(Locks::mutator_lock_) {
    101     return *ShortType::GetInstance();
    102   }
    103   const IntegerType& Integer() SHARED_REQUIRES(Locks::mutator_lock_) {
    104     return *IntegerType::GetInstance();
    105   }
    106   const FloatType& Float() SHARED_REQUIRES(Locks::mutator_lock_) {
    107     return *FloatType::GetInstance();
    108   }
    109   const LongLoType& LongLo() SHARED_REQUIRES(Locks::mutator_lock_) {
    110     return *LongLoType::GetInstance();
    111   }
    112   const LongHiType& LongHi() SHARED_REQUIRES(Locks::mutator_lock_) {
    113     return *LongHiType::GetInstance();
    114   }
    115   const DoubleLoType& DoubleLo() SHARED_REQUIRES(Locks::mutator_lock_) {
    116     return *DoubleLoType::GetInstance();
    117   }
    118   const DoubleHiType& DoubleHi() SHARED_REQUIRES(Locks::mutator_lock_) {
    119     return *DoubleHiType::GetInstance();
    120   }
    121   const UndefinedType& Undefined() SHARED_REQUIRES(Locks::mutator_lock_) {
    122     return *UndefinedType::GetInstance();
    123   }
    124   const ConflictType& Conflict() {
    125     return *ConflictType::GetInstance();
    126   }
    127 
    128   const PreciseReferenceType& JavaLangClass() SHARED_REQUIRES(Locks::mutator_lock_);
    129   const PreciseReferenceType& JavaLangString() SHARED_REQUIRES(Locks::mutator_lock_);
    130   const RegType& JavaLangThrowable(bool precise) SHARED_REQUIRES(Locks::mutator_lock_);
    131   const RegType& JavaLangObject(bool precise) SHARED_REQUIRES(Locks::mutator_lock_);
    132 
    133   const UninitializedType& Uninitialized(const RegType& type, uint32_t allocation_pc)
    134       SHARED_REQUIRES(Locks::mutator_lock_);
    135   // Create an uninitialized 'this' argument for the given type.
    136   const UninitializedType& UninitializedThisArgument(const RegType& type)
    137       SHARED_REQUIRES(Locks::mutator_lock_);
    138   const RegType& FromUninitialized(const RegType& uninit_type)
    139       SHARED_REQUIRES(Locks::mutator_lock_);
    140   const ImpreciseConstType& ByteConstant() SHARED_REQUIRES(Locks::mutator_lock_);
    141   const ImpreciseConstType& CharConstant() SHARED_REQUIRES(Locks::mutator_lock_);
    142   const ImpreciseConstType& ShortConstant() SHARED_REQUIRES(Locks::mutator_lock_);
    143   const ImpreciseConstType& IntConstant() SHARED_REQUIRES(Locks::mutator_lock_);
    144   const ImpreciseConstType& PosByteConstant() SHARED_REQUIRES(Locks::mutator_lock_);
    145   const ImpreciseConstType& PosShortConstant() SHARED_REQUIRES(Locks::mutator_lock_);
    146   const RegType& GetComponentType(const RegType& array, mirror::ClassLoader* loader)
    147       SHARED_REQUIRES(Locks::mutator_lock_);
    148   void Dump(std::ostream& os) SHARED_REQUIRES(Locks::mutator_lock_);
    149   const RegType& RegTypeFromPrimitiveType(Primitive::Type) const;
    150 
    151   void VisitRoots(RootVisitor* visitor, const RootInfo& root_info)
    152       SHARED_REQUIRES(Locks::mutator_lock_);
    153   static void VisitStaticRoots(RootVisitor* visitor)
    154       SHARED_REQUIRES(Locks::mutator_lock_);
    155 
    156  private:
    157   void FillPrimitiveAndSmallConstantTypes() SHARED_REQUIRES(Locks::mutator_lock_);
    158   mirror::Class* ResolveClass(const char* descriptor, mirror::ClassLoader* loader)
    159       SHARED_REQUIRES(Locks::mutator_lock_);
    160   bool MatchDescriptor(size_t idx, const StringPiece& descriptor, bool precise)
    161       SHARED_REQUIRES(Locks::mutator_lock_);
    162   const ConstantType& FromCat1NonSmallConstant(int32_t value, bool precise)
    163       SHARED_REQUIRES(Locks::mutator_lock_);
    164 
    165   // Returns the pass in RegType.
    166   template <class RegTypeType>
    167   RegTypeType& AddEntry(RegTypeType* new_entry) SHARED_REQUIRES(Locks::mutator_lock_);
    168 
    169   // Add a string piece to the arena allocator so that it stays live for the lifetime of the
    170   // verifier.
    171   StringPiece AddString(const StringPiece& string_piece);
    172 
    173   template <class Type>
    174   static const Type* CreatePrimitiveTypeInstance(const std::string& descriptor)
    175       SHARED_REQUIRES(Locks::mutator_lock_);
    176   static void CreatePrimitiveAndSmallConstantTypes() SHARED_REQUIRES(Locks::mutator_lock_);
    177 
    178   // A quick look up for popular small constants.
    179   static constexpr int32_t kMinSmallConstant = -1;
    180   static constexpr int32_t kMaxSmallConstant = 4;
    181   static const PreciseConstType* small_precise_constants_[kMaxSmallConstant -
    182                                                           kMinSmallConstant + 1];
    183 
    184   static constexpr size_t kNumPrimitivesAndSmallConstants =
    185       12 + (kMaxSmallConstant - kMinSmallConstant + 1);
    186 
    187   // Have the well known global primitives been created?
    188   static bool primitive_initialized_;
    189 
    190   // Number of well known primitives that will be copied into a RegTypeCache upon construction.
    191   static uint16_t primitive_count_;
    192 
    193   // The actual storage for the RegTypes.
    194   ScopedArenaVector<const RegType*> entries_;
    195 
    196   // Fast lookup for quickly finding entries that have a matching class.
    197   ScopedArenaVector<std::pair<GcRoot<mirror::Class>, const RegType*>> klass_entries_;
    198 
    199   // Whether or not we're allowed to load classes.
    200   const bool can_load_classes_;
    201 
    202   // Arena allocator.
    203   ScopedArenaAllocator& arena_;
    204 
    205   DISALLOW_COPY_AND_ASSIGN(RegTypeCache);
    206 };
    207 
    208 }  // namespace verifier
    209 }  // namespace art
    210 
    211 #endif  // ART_RUNTIME_VERIFIER_REG_TYPE_CACHE_H_
    212