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