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 "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:
     41   explicit RegTypeCache(bool can_load_classes) : can_load_classes_(can_load_classes) {
     42     entries_.reserve(64);
     43     FillPrimitiveTypes();
     44   }
     45   ~RegTypeCache();
     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_);
     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   }
     80   const RegType& JavaLangThrowable(bool precise)
     81       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     82     return From(NULL, "Ljava/lang/Throwable;", precise);
     83   }
     84   const RegType& Zero() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     85     return FromCat1Const(0, true);
     86   }
     87   size_t GetCacheSize() {
     88     return entries_.size();
     89   }
     90   const RegType& Boolean() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     91     return *BooleanType::GetInstance();
     92   }
     93   const RegType& Byte() {
     94     return *ByteType::GetInstance();
     95   }
     96   const RegType& Char()  {
     97     return *CharType::GetInstance();
     98   }
     99   const RegType& Short()  {
    100     return *ShortType::GetInstance();
    101   }
    102   const RegType& Integer() {
    103     return *IntegerType::GetInstance();
    104   }
    105   const RegType& Float() {
    106     return *FloatType::GetInstance();
    107   }
    108   const RegType& LongLo() {
    109     return *LongLoType::GetInstance();
    110   }
    111   const RegType& LongHi() {
    112     return *LongHiType::GetInstance();
    113   }
    114   const RegType& DoubleLo() {
    115     return *DoubleLoType::GetInstance();
    116   }
    117   const RegType& DoubleHi() {
    118     return *DoubleHiType::GetInstance();
    119   }
    120   const RegType& Undefined() {
    121     return *UndefinedType::GetInstance();
    122   }
    123   const RegType& Conflict() {
    124     return *ConflictType::GetInstance();
    125   }
    126   const RegType& JavaLangClass(bool precise) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    127     return From(NULL, "Ljava/lang/Class;", precise);
    128   }
    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