blob: f62e8b6f54ea4c0e6d7374c5260d4d112f988bd8 [file] [log] [blame]
/*
* Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef ART_RUNTIME_VERIFIER_REG_TYPE_CACHE_INL_H_
#define ART_RUNTIME_VERIFIER_REG_TYPE_CACHE_INL_H_
#include "class_linker.h"
#include "class_root.h"
#include "mirror/class-inl.h"
#include "mirror/method_handle_impl.h"
#include "mirror/method_type.h"
#include "mirror/string.h"
#include "mirror/throwable.h"
#include "reg_type.h"
#include "reg_type_cache.h"
namespace art {
namespace verifier {
inline const art::verifier::RegType& RegTypeCache::GetFromId(uint16_t id) const {
DCHECK_LT(id, entries_.size());
const RegType* result = entries_[id];
DCHECK(result != nullptr);
return *result;
}
inline const ConstantType& RegTypeCache::FromCat1Const(int32_t value, bool precise) {
// We only expect 0 to be a precise constant.
DCHECK(value != 0 || precise);
if (precise && (value >= kMinSmallConstant) && (value <= kMaxSmallConstant)) {
return *small_precise_constants_[value - kMinSmallConstant];
}
return FromCat1NonSmallConstant(value, precise);
}
inline const BooleanType& RegTypeCache::Boolean() {
return *BooleanType::GetInstance();
}
inline const ByteType& RegTypeCache::Byte() {
return *ByteType::GetInstance();
}
inline const CharType& RegTypeCache::Char() {
return *CharType::GetInstance();
}
inline const ShortType& RegTypeCache::Short() {
return *ShortType::GetInstance();
}
inline const IntegerType& RegTypeCache::Integer() {
return *IntegerType::GetInstance();
}
inline const FloatType& RegTypeCache::Float() {
return *FloatType::GetInstance();
}
inline const LongLoType& RegTypeCache::LongLo() {
return *LongLoType::GetInstance();
}
inline const LongHiType& RegTypeCache::LongHi() {
return *LongHiType::GetInstance();
}
inline const DoubleLoType& RegTypeCache::DoubleLo() {
return *DoubleLoType::GetInstance();
}
inline const DoubleHiType& RegTypeCache::DoubleHi() {
return *DoubleHiType::GetInstance();
}
inline const UndefinedType& RegTypeCache::Undefined() {
return *UndefinedType::GetInstance();
}
inline const ConflictType& RegTypeCache::Conflict() {
return *ConflictType::GetInstance();
}
inline const NullType& RegTypeCache::Null() {
return *NullType::GetInstance();
}
inline const ImpreciseConstType& RegTypeCache::ByteConstant() {
const ConstantType& result = FromCat1Const(std::numeric_limits<jbyte>::min(), false);
DCHECK(result.IsImpreciseConstant());
return *down_cast<const ImpreciseConstType*>(&result);
}
inline const ImpreciseConstType& RegTypeCache::CharConstant() {
int32_t jchar_max = static_cast<int32_t>(std::numeric_limits<jchar>::max());
const ConstantType& result = FromCat1Const(jchar_max, false);
DCHECK(result.IsImpreciseConstant());
return *down_cast<const ImpreciseConstType*>(&result);
}
inline const ImpreciseConstType& RegTypeCache::ShortConstant() {
const ConstantType& result = FromCat1Const(std::numeric_limits<jshort>::min(), false);
DCHECK(result.IsImpreciseConstant());
return *down_cast<const ImpreciseConstType*>(&result);
}
inline const ImpreciseConstType& RegTypeCache::IntConstant() {
const ConstantType& result = FromCat1Const(std::numeric_limits<jint>::max(), false);
DCHECK(result.IsImpreciseConstant());
return *down_cast<const ImpreciseConstType*>(&result);
}
inline const ImpreciseConstType& RegTypeCache::PosByteConstant() {
const ConstantType& result = FromCat1Const(std::numeric_limits<jbyte>::max(), false);
DCHECK(result.IsImpreciseConstant());
return *down_cast<const ImpreciseConstType*>(&result);
}
inline const ImpreciseConstType& RegTypeCache::PosShortConstant() {
const ConstantType& result = FromCat1Const(std::numeric_limits<jshort>::max(), false);
DCHECK(result.IsImpreciseConstant());
return *down_cast<const ImpreciseConstType*>(&result);
}
inline const PreciseReferenceType& RegTypeCache::JavaLangClass() {
const RegType* result = &FromClass("Ljava/lang/Class;",
GetClassRoot<mirror::Class>(),
/* precise= */ true);
DCHECK(result->IsPreciseReference());
return *down_cast<const PreciseReferenceType*>(result);
}
inline const PreciseReferenceType& RegTypeCache::JavaLangString() {
// String is final and therefore always precise.
const RegType* result = &FromClass("Ljava/lang/String;",
GetClassRoot<mirror::String>(),
/* precise= */ true);
DCHECK(result->IsPreciseReference());
return *down_cast<const PreciseReferenceType*>(result);
}
inline const PreciseReferenceType& RegTypeCache::JavaLangInvokeMethodHandle() {
const RegType* result = &FromClass("Ljava/lang/invoke/MethodHandle;",
GetClassRoot<mirror::MethodHandle>(),
/* precise= */ true);
DCHECK(result->IsPreciseReference());
return *down_cast<const PreciseReferenceType*>(result);
}
inline const PreciseReferenceType& RegTypeCache::JavaLangInvokeMethodType() {
const RegType* result = &FromClass("Ljava/lang/invoke/MethodType;",
GetClassRoot<mirror::MethodType>(),
/* precise= */ true);
DCHECK(result->IsPreciseReference());
return *down_cast<const PreciseReferenceType*>(result);
}
inline const RegType& RegTypeCache::JavaLangThrowable(bool precise) {
const RegType* result = &FromClass("Ljava/lang/Throwable;",
GetClassRoot<mirror::Throwable>(),
precise);
if (precise) {
DCHECK(result->IsPreciseReference());
return *down_cast<const PreciseReferenceType*>(result);
} else {
DCHECK(result->IsReference());
return *down_cast<const ReferenceType*>(result);
}
}
inline const RegType& RegTypeCache::JavaLangObject(bool precise) {
const RegType* result = &FromClass("Ljava/lang/Object;", GetClassRoot<mirror::Object>(), precise);
if (precise) {
DCHECK(result->IsPreciseReference());
return *down_cast<const PreciseReferenceType*>(result);
} else {
DCHECK(result->IsReference());
return *down_cast<const ReferenceType*>(result);
}
}
template <class RegTypeType>
inline RegTypeType& RegTypeCache::AddEntry(RegTypeType* new_entry) {
DCHECK(new_entry != nullptr);
entries_.push_back(new_entry);
if (new_entry->HasClass()) {
ObjPtr<mirror::Class> klass = new_entry->GetClass();
DCHECK(!klass->IsPrimitive());
klass_entries_.push_back(std::make_pair(GcRoot<mirror::Class>(klass), new_entry));
}
return *new_entry;
}
} // namespace verifier
} // namespace art
#endif // ART_RUNTIME_VERIFIER_REG_TYPE_CACHE_INL_H_