reg_type_cache.h revision 3e79aadc447dcdb9e52368baced9405667e68e6a
1776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers/*
2776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Copyright (C) 2012 The Android Open Source Project
3776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers *
4776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Licensed under the Apache License, Version 2.0 (the "License");
5776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * you may not use this file except in compliance with the License.
6776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * You may obtain a copy of the License at
7776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers *
8776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers *      http://www.apache.org/licenses/LICENSE-2.0
9776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers *
10776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Unless required by applicable law or agreed to in writing, software
11776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * distributed under the License is distributed on an "AS IS" BASIS,
12776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * See the License for the specific language governing permissions and
14776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * limitations under the License.
15776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers */
16776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers
17fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#ifndef ART_RUNTIME_VERIFIER_REG_TYPE_CACHE_H_
18fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#define ART_RUNTIME_VERIFIER_REG_TYPE_CACHE_H_
19776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers
2051a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal#include "base/casts.h"
21761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes#include "base/macros.h"
221aa246dec5abe212f699de1413a0c4a191ca364aElliott Hughes#include "base/stl_util.h"
23776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers#include "reg_type.h"
2451a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal#include "runtime.h"
25776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers
2651a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal#include <stdint.h>
272dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include <vector>
282dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
29776ac1fa61237db645adb4370a4aab888530caf4Ian Rogersnamespace art {
302dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersnamespace mirror {
312dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersclass Class;
322dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersclass ClassLoader;
332dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}  // namespace mirror
34776ac1fa61237db645adb4370a4aab888530caf4Ian Rogersnamespace verifier {
35776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers
3651a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asalclass RegType;
3751a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal
3862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersconst size_t kNumPrimitives = 12;
39776ac1fa61237db645adb4370a4aab888530caf4Ian Rogersclass RegTypeCache {
40776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers public:
4151a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  explicit RegTypeCache(bool can_load_classes) : can_load_classes_(can_load_classes) {
42637c65b1e431fd90195b71c141b3590bd81cc91aIan Rogers    entries_.reserve(64);
4351a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    FillPrimitiveTypes();
4451a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  }
4551a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  ~RegTypeCache();
4651a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  static void Init() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
47df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom    if (!RegTypeCache::primitive_initialized_) {
4851a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      CHECK_EQ(RegTypeCache::primitive_count_, 0);
4951a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      CreatePrimitiveTypes();
5062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers      CHECK_EQ(RegTypeCache::primitive_count_, kNumPrimitives);
5151a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      RegTypeCache::primitive_initialized_ = true;
5251a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    }
5351a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  }
5451a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  static void ShutDown();
5551a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  const art::verifier::RegType& GetFromId(uint16_t id) const;
561bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers  const RegType& From(mirror::ClassLoader* loader, const char* descriptor, bool precise)
5751a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
5851a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  template <class Type>
591bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers  static Type* CreatePrimitiveTypeInstance(const std::string& descriptor)
60b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
6151a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  void FillPrimitiveTypes() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
62637c65b1e431fd90195b71c141b3590bd81cc91aIan Rogers  const RegType& FromClass(const char* descriptor, mirror::Class* klass, bool precise)
63b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
642bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers  const RegType& FromCat1Const(int32_t value, bool precise)
652bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
662dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  const RegType& FromCat2ConstLo(int32_t value, bool precise)
672dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
682dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  const RegType& FromCat2ConstHi(int32_t value, bool precise)
692dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
702dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  const RegType& FromDescriptor(mirror::ClassLoader* loader, const char* descriptor, bool precise)
71b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
722dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  const RegType& FromUnresolvedMerge(const RegType& left, const RegType& right)
732dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
742dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  const RegType& FromUnresolvedSuperClass(const RegType& child)
752dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
7651a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  const RegType& JavaLangString() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
7751a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    // String is final and therefore always precise.
7851a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    return From(NULL, "Ljava/lang/String;", true);
7900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
8051a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  const RegType& JavaLangThrowable(bool precise)
8151a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
8251a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    return From(NULL, "Ljava/lang/Throwable;", precise);
8300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
8451a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  const RegType& Zero() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
8551a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    return FromCat1Const(0, true);
8600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
8751a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  size_t GetCacheSize() {
8851a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    return entries_.size();
8900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
9051a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  const RegType& Boolean() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
9151a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    return *BooleanType::GetInstance();
9200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
9351a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  const RegType& Byte() {
9451a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    return *ByteType::GetInstance();
9500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
9651a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  const RegType& Char()  {
9751a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    return *CharType::GetInstance();
9800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
9951a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  const RegType& Short()  {
10051a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    return *ShortType::GetInstance();
1012bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers  }
10251a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  const RegType& Integer() {
10351a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    return *IntegerType::GetInstance();
10400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
10551a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  const RegType& Float() {
10651a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    return *FloatType::GetInstance();
1072bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers  }
10851a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  const RegType& LongLo() {
10951a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    return *LongLoType::GetInstance();
11000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
11151a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  const RegType& LongHi() {
11251a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    return *LongHiType::GetInstance();
11300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
11451a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  const RegType& DoubleLo() {
11551a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    return *DoubleLoType::GetInstance();
11600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
11751a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  const RegType& DoubleHi() {
11851a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    return *DoubleHiType::GetInstance();
11900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
12051a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  const RegType& Undefined() {
12151a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    return *UndefinedType::GetInstance();
12200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
12351a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  const RegType& Conflict() {
12451a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    return *ConflictType::GetInstance();
12500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
12651a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  const RegType& JavaLangClass(bool precise) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
12751a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    return From(NULL, "Ljava/lang/Class;", precise);
12851a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  }
12951a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  const RegType& JavaLangObject(bool precise) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
13051a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    return From(NULL, "Ljava/lang/Object;", precise);
13100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
1322dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  const RegType& Uninitialized(const RegType& type, uint32_t allocation_pc)
1332dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
134ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers  // Create an uninitialized 'this' argument for the given type.
1352dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  const RegType& UninitializedThisArgument(const RegType& type)
1362dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
1372dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  const RegType& FromUninitialized(const RegType& uninit_type)
1382dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
1392dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  const RegType& ByteConstant() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
1402dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  const RegType& ShortConstant() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
1412dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  const RegType& IntConstant() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
1422dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  const RegType& GetComponentType(const RegType& array, mirror::ClassLoader* loader)
143b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
144b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers  void Dump(std::ostream& os) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
14551a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  const RegType& RegTypeFromPrimitiveType(Primitive::Type) const;
146b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers
147776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers private:
148776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  std::vector<RegType*> entries_;
14951a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  static bool primitive_initialized_;
15051a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  static uint16_t primitive_start_;
15151a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  static uint16_t primitive_count_;
15251a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  static void CreatePrimitiveTypes() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
15380537bb742dff4ccdf6d04b1c0bb7d2179acc8cbElliott Hughes  // Whether or not we're allowed to load classes.
15480537bb742dff4ccdf6d04b1c0bb7d2179acc8cbElliott Hughes  const bool can_load_classes_;
1551bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers  mirror::Class* ResolveClass(const char* descriptor, mirror::ClassLoader* loader)
15651a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
15751a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  void ClearException();
1581bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers  bool MatchDescriptor(size_t idx, const char* descriptor, bool precise)
15951a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
1603e79aadc447dcdb9e52368baced9405667e68e6aBrian Carlstrom  DISALLOW_COPY_AND_ASSIGN(RegTypeCache);
161776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers};
162776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers
163776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers}  // namespace verifier
164776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers}  // namespace art
165776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers
166fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif  // ART_RUNTIME_VERIFIER_REG_TYPE_CACHE_H_
167