Revert "Add read barriers for the roots in the verifier."
This reverts commit 7da9586b559290e1c16207c6513ffe485de61655.
Bug: 17398101
Change-Id: I1d6110fdf0d3a3c9241c8e7e7f4b85a298f9dd8e
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index c21a7a4..9cde8da 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -1187,7 +1187,7 @@
// If this is a constructor for a class other than java.lang.Object, mark the first ("this")
// argument as uninitialized. This restricts field access until the superclass constructor is
// called.
- RegType& declaring_class = GetDeclaringClass();
+ const RegType& declaring_class = GetDeclaringClass();
if (IsConstructor() && !declaring_class.IsJavaLangObject()) {
reg_line->SetRegisterType(arg_start + cur_arg,
reg_types_.UninitializedThisArgument(declaring_class));
@@ -1219,7 +1219,7 @@
// it's effectively considered initialized the instant we reach here (in the sense that we
// can return without doing anything or call virtual methods).
{
- RegType& reg_type = ResolveClassAndCheckAccess(iterator.GetTypeIdx());
+ const RegType& reg_type = ResolveClassAndCheckAccess(iterator.GetTypeIdx());
if (!reg_type.IsNonZeroReferenceTypes()) {
DCHECK(HasFailures());
return false;
@@ -1253,8 +1253,8 @@
return false;
}
- RegType& lo_half = descriptor[0] == 'J' ? reg_types_.LongLo() : reg_types_.DoubleLo();
- RegType& hi_half = descriptor[0] == 'J' ? reg_types_.LongHi() : reg_types_.DoubleHi();
+ const RegType& lo_half = descriptor[0] == 'J' ? reg_types_.LongLo() : reg_types_.DoubleLo();
+ const RegType& hi_half = descriptor[0] == 'J' ? reg_types_.LongHi() : reg_types_.DoubleHi();
reg_line->SetRegisterTypeWide(arg_start + cur_arg, lo_half, hi_half);
cur_arg++;
break;
@@ -1546,7 +1546,7 @@
* This statement can only appear as the first instruction in an exception handler. We verify
* that as part of extracting the exception type from the catch block list.
*/
- RegType& res_type = GetCaughtExceptionType();
+ const RegType& res_type = GetCaughtExceptionType();
work_line_->SetRegisterType(inst->VRegA_11x(), res_type);
break;
}
@@ -1560,7 +1560,7 @@
case Instruction::RETURN:
if (!IsConstructor() || work_line_->CheckConstructorReturn()) {
/* check the method signature */
- RegType& return_type = GetMethodReturnType();
+ const RegType& return_type = GetMethodReturnType();
if (!return_type.IsCategory1Types()) {
Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unexpected non-category 1 return type "
<< return_type;
@@ -1568,7 +1568,7 @@
// Compilers may generate synthetic functions that write byte values into boolean fields.
// Also, it may use integer values for boolean, byte, short, and character return types.
const uint32_t vregA = inst->VRegA_11x();
- RegType& src_type = work_line_->GetRegisterType(vregA);
+ const RegType& src_type = work_line_->GetRegisterType(vregA);
bool use_src = ((return_type.IsBoolean() && src_type.IsByte()) ||
((return_type.IsBoolean() || return_type.IsByte() ||
return_type.IsShort() || return_type.IsChar()) &&
@@ -1585,7 +1585,7 @@
case Instruction::RETURN_WIDE:
if (!IsConstructor() || work_line_->CheckConstructorReturn()) {
/* check the method signature */
- RegType& return_type = GetMethodReturnType();
+ const RegType& return_type = GetMethodReturnType();
if (!return_type.IsCategory2Types()) {
Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "return-wide not expected";
} else {
@@ -1600,7 +1600,7 @@
break;
case Instruction::RETURN_OBJECT:
if (!IsConstructor() || work_line_->CheckConstructorReturn()) {
- RegType& return_type = GetMethodReturnType();
+ const RegType& return_type = GetMethodReturnType();
if (!return_type.IsReferenceTypes()) {
Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "return-object not expected";
} else {
@@ -1608,7 +1608,7 @@
DCHECK(!return_type.IsZero());
DCHECK(!return_type.IsUninitializedReference());
const uint32_t vregA = inst->VRegA_11x();
- RegType& reg_type = work_line_->GetRegisterType(vregA);
+ const RegType& reg_type = work_line_->GetRegisterType(vregA);
// Disallow returning uninitialized values and verify that the reference in vAA is an
// instance of the "return_type"
if (reg_type.IsUninitializedTypes()) {
@@ -1655,29 +1655,29 @@
/* could be long or double; resolved upon use */
case Instruction::CONST_WIDE_16: {
int64_t val = static_cast<int16_t>(inst->VRegB_21s());
- RegType& lo = reg_types_.FromCat2ConstLo(static_cast<int32_t>(val), true);
- RegType& hi = reg_types_.FromCat2ConstHi(static_cast<int32_t>(val >> 32), true);
+ const RegType& lo = reg_types_.FromCat2ConstLo(static_cast<int32_t>(val), true);
+ const RegType& hi = reg_types_.FromCat2ConstHi(static_cast<int32_t>(val >> 32), true);
work_line_->SetRegisterTypeWide(inst->VRegA_21s(), lo, hi);
break;
}
case Instruction::CONST_WIDE_32: {
int64_t val = static_cast<int32_t>(inst->VRegB_31i());
- RegType& lo = reg_types_.FromCat2ConstLo(static_cast<int32_t>(val), true);
- RegType& hi = reg_types_.FromCat2ConstHi(static_cast<int32_t>(val >> 32), true);
+ const RegType& lo = reg_types_.FromCat2ConstLo(static_cast<int32_t>(val), true);
+ const RegType& hi = reg_types_.FromCat2ConstHi(static_cast<int32_t>(val >> 32), true);
work_line_->SetRegisterTypeWide(inst->VRegA_31i(), lo, hi);
break;
}
case Instruction::CONST_WIDE: {
int64_t val = inst->VRegB_51l();
- RegType& lo = reg_types_.FromCat2ConstLo(static_cast<int32_t>(val), true);
- RegType& hi = reg_types_.FromCat2ConstHi(static_cast<int32_t>(val >> 32), true);
+ const RegType& lo = reg_types_.FromCat2ConstLo(static_cast<int32_t>(val), true);
+ const RegType& hi = reg_types_.FromCat2ConstHi(static_cast<int32_t>(val >> 32), true);
work_line_->SetRegisterTypeWide(inst->VRegA_51l(), lo, hi);
break;
}
case Instruction::CONST_WIDE_HIGH16: {
int64_t val = static_cast<uint64_t>(inst->VRegB_21h()) << 48;
- RegType& lo = reg_types_.FromCat2ConstLo(static_cast<int32_t>(val), true);
- RegType& hi = reg_types_.FromCat2ConstHi(static_cast<int32_t>(val >> 32), true);
+ const RegType& lo = reg_types_.FromCat2ConstLo(static_cast<int32_t>(val), true);
+ const RegType& hi = reg_types_.FromCat2ConstHi(static_cast<int32_t>(val >> 32), true);
work_line_->SetRegisterTypeWide(inst->VRegA_21h(), lo, hi);
break;
}
@@ -1690,7 +1690,7 @@
case Instruction::CONST_CLASS: {
// Get type from instruction if unresolved then we need an access check
// TODO: check Compiler::CanAccessTypeWithoutChecks returns false when res_type is unresolved
- RegType& res_type = ResolveClassAndCheckAccess(inst->VRegB_21c());
+ const RegType& res_type = ResolveClassAndCheckAccess(inst->VRegB_21c());
// Register holds class, ie its type is class, on error it will hold Conflict.
work_line_->SetRegisterType(inst->VRegA_21c(),
res_type.IsConflict() ? res_type
@@ -1736,7 +1736,7 @@
*/
const bool is_checkcast = (inst->Opcode() == Instruction::CHECK_CAST);
const uint32_t type_idx = (is_checkcast) ? inst->VRegB_21c() : inst->VRegC_22c();
- RegType& res_type = ResolveClassAndCheckAccess(type_idx);
+ const RegType& res_type = ResolveClassAndCheckAccess(type_idx);
if (res_type.IsConflict()) {
// If this is a primitive type, fail HARD.
mirror::Class* klass = dex_cache_->GetResolvedType(type_idx);
@@ -1755,7 +1755,7 @@
}
// TODO: check Compiler::CanAccessTypeWithoutChecks returns false when res_type is unresolved
uint32_t orig_type_reg = (is_checkcast) ? inst->VRegA_21c() : inst->VRegB_22c();
- RegType& orig_type = work_line_->GetRegisterType(orig_type_reg);
+ const RegType& orig_type = work_line_->GetRegisterType(orig_type_reg);
if (!res_type.IsNonZeroReferenceTypes()) {
if (is_checkcast) {
Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "check-cast on unexpected class " << res_type;
@@ -1778,7 +1778,7 @@
break;
}
case Instruction::ARRAY_LENGTH: {
- RegType& res_type = work_line_->GetRegisterType(inst->VRegB_12x());
+ const RegType& res_type = work_line_->GetRegisterType(inst->VRegB_12x());
if (res_type.IsReferenceTypes()) {
if (!res_type.IsArrayTypes() && !res_type.IsZero()) { // ie not an array or null
Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "array-length on non-array " << res_type;
@@ -1791,7 +1791,7 @@
break;
}
case Instruction::NEW_INSTANCE: {
- RegType& res_type = ResolveClassAndCheckAccess(inst->VRegB_21c());
+ const RegType& res_type = ResolveClassAndCheckAccess(inst->VRegB_21c());
if (res_type.IsConflict()) {
DCHECK_NE(failures_.size(), 0U);
break; // bad class
@@ -1803,7 +1803,7 @@
<< "new-instance on primitive, interface or abstract class" << res_type;
// Soft failure so carry on to set register type.
}
- RegType& uninit_type = reg_types_.Uninitialized(res_type, work_insn_idx_);
+ const RegType& uninit_type = reg_types_.Uninitialized(res_type, work_insn_idx_);
// Any registers holding previous allocations from this address that have not yet been
// initialized must be marked invalid.
work_line_->MarkUninitRefsAsInvalid(uninit_type);
@@ -1856,7 +1856,7 @@
work_line_->SetRegisterType(inst->VRegA_23x(), reg_types_.Integer());
break;
case Instruction::THROW: {
- RegType& res_type = work_line_->GetRegisterType(inst->VRegA_11x());
+ const RegType& res_type = work_line_->GetRegisterType(inst->VRegA_11x());
if (!reg_types_.JavaLangThrowable(false).IsAssignableFrom(res_type)) {
Fail(res_type.IsUnresolvedTypes() ? VERIFY_ERROR_NO_CLASS : VERIFY_ERROR_BAD_CLASS_SOFT)
<< "thrown class " << res_type << " not instanceof Throwable";
@@ -1877,14 +1877,14 @@
case Instruction::FILL_ARRAY_DATA: {
/* Similar to the verification done for APUT */
- RegType& array_type = work_line_->GetRegisterType(inst->VRegA_31t());
+ const RegType& array_type = work_line_->GetRegisterType(inst->VRegA_31t());
/* array_type can be null if the reg type is Zero */
if (!array_type.IsZero()) {
if (!array_type.IsArrayTypes()) {
Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid fill-array-data with array type "
<< array_type;
} else {
- RegType& component_type = reg_types_.GetComponentType(array_type, GetClassLoader());
+ const RegType& component_type = reg_types_.GetComponentType(array_type, GetClassLoader());
DCHECK(!component_type.IsConflict());
if (component_type.IsNonZeroReferenceTypes()) {
Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid fill-array-data with component type "
@@ -1911,8 +1911,8 @@
}
case Instruction::IF_EQ:
case Instruction::IF_NE: {
- RegType& reg_type1 = work_line_->GetRegisterType(inst->VRegA_22t());
- RegType& reg_type2 = work_line_->GetRegisterType(inst->VRegB_22t());
+ const RegType& reg_type1 = work_line_->GetRegisterType(inst->VRegA_22t());
+ const RegType& reg_type2 = work_line_->GetRegisterType(inst->VRegB_22t());
bool mismatch = false;
if (reg_type1.IsZero()) { // zero then integral or reference expected
mismatch = !reg_type2.IsReferenceTypes() && !reg_type2.IsIntegralTypes();
@@ -1931,8 +1931,8 @@
case Instruction::IF_GE:
case Instruction::IF_GT:
case Instruction::IF_LE: {
- RegType& reg_type1 = work_line_->GetRegisterType(inst->VRegA_22t());
- RegType& reg_type2 = work_line_->GetRegisterType(inst->VRegB_22t());
+ const RegType& reg_type1 = work_line_->GetRegisterType(inst->VRegA_22t());
+ const RegType& reg_type2 = work_line_->GetRegisterType(inst->VRegB_22t());
if (!reg_type1.IsIntegralTypes() || !reg_type2.IsIntegralTypes()) {
Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "args to 'if' (" << reg_type1 << ","
<< reg_type2 << ") must be integral";
@@ -1941,7 +1941,7 @@
}
case Instruction::IF_EQZ:
case Instruction::IF_NEZ: {
- RegType& reg_type = work_line_->GetRegisterType(inst->VRegA_21t());
+ const RegType& reg_type = work_line_->GetRegisterType(inst->VRegA_21t());
if (!reg_type.IsReferenceTypes() && !reg_type.IsIntegralTypes()) {
Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "type " << reg_type
<< " unexpected as arg to if-eqz/if-nez";
@@ -1987,8 +1987,8 @@
// type is assignable to the original then allow optimization. This check is performed to
// ensure that subsequent merges don't lose type information - such as becoming an
// interface from a class that would lose information relevant to field checks.
- RegType& orig_type = work_line_->GetRegisterType(instance_of_inst->VRegB_22c());
- RegType& cast_type = ResolveClassAndCheckAccess(instance_of_inst->VRegC_22c());
+ const RegType& orig_type = work_line_->GetRegisterType(instance_of_inst->VRegB_22c());
+ const RegType& cast_type = ResolveClassAndCheckAccess(instance_of_inst->VRegC_22c());
if (!orig_type.Equals(cast_type) &&
!cast_type.IsUnresolvedTypes() && !orig_type.IsUnresolvedTypes() &&
@@ -2043,7 +2043,7 @@
case Instruction::IF_GEZ:
case Instruction::IF_GTZ:
case Instruction::IF_LEZ: {
- RegType& reg_type = work_line_->GetRegisterType(inst->VRegA_21t());
+ const RegType& reg_type = work_line_->GetRegisterType(inst->VRegA_21t());
if (!reg_type.IsIntegralTypes()) {
Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "type " << reg_type
<< " unexpected as arg to if-ltz/if-gez/if-gtz/if-lez";
@@ -2192,7 +2192,7 @@
inst->Opcode() == Instruction::INVOKE_SUPER_RANGE);
mirror::ArtMethod* called_method = VerifyInvocationArgs(inst, METHOD_VIRTUAL, is_range,
is_super);
- RegType* return_type = nullptr;
+ const RegType* return_type = nullptr;
if (called_method != nullptr) {
Thread* self = Thread::Current();
StackHandleScope<1> hs(self);
@@ -2230,7 +2230,7 @@
is_range, false);
const char* return_type_descriptor;
bool is_constructor;
- RegType* return_type = nullptr;
+ const RegType* return_type = nullptr;
if (called_method == NULL) {
uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c();
const DexFile::MethodId& method_id = dex_file_->GetMethodId(method_idx);
@@ -2262,7 +2262,7 @@
* allowing the latter only if the "this" argument is the same as the "this" argument to
* this method (which implies that we're in a constructor ourselves).
*/
- RegType& this_type = work_line_->GetInvocationThis(inst, is_range);
+ const RegType& this_type = work_line_->GetInvocationThis(inst, is_range);
if (this_type.IsConflict()) // failure.
break;
@@ -2273,7 +2273,7 @@
}
/* must be in same class or in superclass */
- // RegType& this_super_klass = this_type.GetSuperClass(®_types_);
+ // const RegType& this_super_klass = this_type.GetSuperClass(®_types_);
// TODO: re-enable constructor type verification
// if (this_super_klass.IsConflict()) {
// Unknown super class, fail so we re-check at runtime.
@@ -2322,7 +2322,7 @@
} else {
descriptor = called_method->GetReturnTypeDescriptor();
}
- RegType& return_type = reg_types_.FromDescriptor(GetClassLoader(), descriptor, false);
+ const RegType& return_type = reg_types_.FromDescriptor(GetClassLoader(), descriptor, false);
if (!return_type.IsLowHalf()) {
work_line_->SetResultRegisterType(return_type);
} else {
@@ -2349,7 +2349,7 @@
/* Get the type of the "this" arg, which should either be a sub-interface of called
* interface or Object (see comments in RegType::JoinClass).
*/
- RegType& this_type = work_line_->GetInvocationThis(inst, is_range);
+ const RegType& this_type = work_line_->GetInvocationThis(inst, is_range);
if (this_type.IsZero()) {
/* null pointer always passes (and always fails at runtime) */
} else {
@@ -2379,7 +2379,7 @@
} else {
descriptor = abs_method->GetReturnTypeDescriptor();
}
- RegType& return_type = reg_types_.FromDescriptor(GetClassLoader(), descriptor, false);
+ const RegType& return_type = reg_types_.FromDescriptor(GetClassLoader(), descriptor, false);
if (!return_type.IsLowHalf()) {
work_line_->SetResultRegisterType(return_type);
} else {
@@ -2656,7 +2656,7 @@
mirror::ArtMethod* called_method = VerifyInvokeVirtualQuickArgs(inst, is_range);
if (called_method != NULL) {
const char* descriptor = called_method->GetReturnTypeDescriptor();
- RegType& return_type = reg_types_.FromDescriptor(GetClassLoader(), descriptor, false);
+ const RegType& return_type = reg_types_.FromDescriptor(GetClassLoader(), descriptor, false);
if (!return_type.IsLowHalf()) {
work_line_->SetResultRegisterType(return_type);
} else {
@@ -2935,11 +2935,11 @@
return true;
} // NOLINT(readability/fn_size)
-RegType& MethodVerifier::ResolveClassAndCheckAccess(uint32_t class_idx) {
+const RegType& MethodVerifier::ResolveClassAndCheckAccess(uint32_t class_idx) {
const char* descriptor = dex_file_->StringByTypeIdx(class_idx);
- RegType& referrer = GetDeclaringClass();
+ const RegType& referrer = GetDeclaringClass();
mirror::Class* klass = dex_cache_->GetResolvedType(class_idx);
- RegType& result = klass != NULL ?
+ const RegType& result = klass != NULL ?
reg_types_.FromClass(descriptor, klass, klass->CannotBeAssignedFromOtherTypes()) :
reg_types_.FromDescriptor(GetClassLoader(), descriptor, false);
if (result.IsConflict()) {
@@ -2961,8 +2961,8 @@
return result;
}
-RegType& MethodVerifier::GetCaughtExceptionType() {
- RegType* common_super = NULL;
+const RegType& MethodVerifier::GetCaughtExceptionType() {
+ const RegType* common_super = NULL;
if (code_item_->tries_size_ != 0) {
const byte* handlers_ptr = DexFile::GetCatchHandlerData(*code_item_, 0);
uint32_t handlers_size = DecodeUnsignedLeb128(&handlers_ptr);
@@ -2973,7 +2973,7 @@
if (iterator.GetHandlerTypeIndex() == DexFile::kDexNoIndex16) {
common_super = ®_types_.JavaLangThrowable(false);
} else {
- RegType& exception = ResolveClassAndCheckAccess(iterator.GetHandlerTypeIndex());
+ const RegType& exception = ResolveClassAndCheckAccess(iterator.GetHandlerTypeIndex());
if (!reg_types_.JavaLangThrowable(false).IsAssignableFrom(exception)) {
if (exception.IsUnresolvedTypes()) {
// We don't know enough about the type. Fail here and let runtime handle it.
@@ -3008,7 +3008,7 @@
mirror::ArtMethod* MethodVerifier::ResolveMethodAndCheckAccess(uint32_t dex_method_idx,
MethodType method_type) {
const DexFile::MethodId& method_id = dex_file_->GetMethodId(dex_method_idx);
- RegType& klass_type = ResolveClassAndCheckAccess(method_id.class_idx_);
+ const RegType& klass_type = ResolveClassAndCheckAccess(method_id.class_idx_);
if (klass_type.IsConflict()) {
std::string append(" in attempt to access method ");
append += dex_file_->GetMethodName(method_id);
@@ -3019,7 +3019,7 @@
return NULL; // Can't resolve Class so no more to do here
}
mirror::Class* klass = klass_type.GetClass();
- RegType& referrer = GetDeclaringClass();
+ const RegType& referrer = GetDeclaringClass();
mirror::ArtMethod* res_method = dex_cache_->GetResolvedMethod(dex_method_idx);
if (res_method == NULL) {
const char* name = dex_file_->GetMethodName(method_id);
@@ -3126,7 +3126,7 @@
* rigorous check here (which is okay since we have to do it at runtime).
*/
if (method_type != METHOD_STATIC) {
- RegType& actual_arg_type = work_line_->GetInvocationThis(inst, is_range);
+ const RegType& actual_arg_type = work_line_->GetInvocationThis(inst, is_range);
if (actual_arg_type.IsConflict()) { // GetInvocationThis failed.
CHECK(have_pending_hard_failure_);
return nullptr;
@@ -3147,7 +3147,7 @@
}
}
if (method_type != METHOD_INTERFACE && !actual_arg_type.IsZero()) {
- RegType* res_method_class;
+ const RegType* res_method_class;
if (res_method != nullptr) {
mirror::Class* klass = res_method->GetDeclaringClass();
std::string temp;
@@ -3189,11 +3189,11 @@
return nullptr;
}
- RegType& reg_type = reg_types_.FromDescriptor(GetClassLoader(), param_descriptor, false);
+ const RegType& reg_type = reg_types_.FromDescriptor(GetClassLoader(), param_descriptor, false);
uint32_t get_reg = is_range ? inst->VRegC_3rc() + static_cast<uint32_t>(sig_registers) :
arg[sig_registers];
if (reg_type.IsIntegralTypes()) {
- RegType& src_type = work_line_->GetRegisterType(get_reg);
+ const RegType& src_type = work_line_->GetRegisterType(get_reg);
if (!src_type.IsIntegralTypes()) {
Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "register v" << get_reg << " has type " << src_type
<< " but expected " << reg_type;
@@ -3276,7 +3276,7 @@
// has a vtable entry for the target method.
if (is_super) {
DCHECK(method_type == METHOD_VIRTUAL);
- RegType& super = GetDeclaringClass().GetSuperClass(®_types_);
+ const RegType& super = GetDeclaringClass().GetSuperClass(®_types_);
if (super.IsUnresolvedTypes()) {
Fail(VERIFY_ERROR_NO_METHOD) << "unknown super class in invoke-super from "
<< PrettyMethod(dex_method_idx_, *dex_file_)
@@ -3304,7 +3304,7 @@
RegisterLine* reg_line, bool is_range) {
DCHECK(inst->Opcode() == Instruction::INVOKE_VIRTUAL_QUICK ||
inst->Opcode() == Instruction::INVOKE_VIRTUAL_RANGE_QUICK);
- RegType& actual_arg_type = reg_line->GetInvocationThis(inst, is_range);
+ const RegType& actual_arg_type = reg_line->GetInvocationThis(inst, is_range);
if (!actual_arg_type.HasClass()) {
VLOG(verifier) << "Failed to get mirror::Class* from '" << actual_arg_type << "'";
return nullptr;
@@ -3342,7 +3342,7 @@
// We use vAA as our expected arg count, rather than res_method->insSize, because we need to
// match the call to the signature. Also, we might be calling through an abstract method
// definition (which doesn't have register count values).
- RegType& actual_arg_type = work_line_->GetInvocationThis(inst, is_range);
+ const RegType& actual_arg_type = work_line_->GetInvocationThis(inst, is_range);
if (actual_arg_type.IsConflict()) { // GetInvocationThis failed.
return NULL;
}
@@ -3367,7 +3367,7 @@
if (!actual_arg_type.IsZero()) {
mirror::Class* klass = res_method->GetDeclaringClass();
std::string temp;
- RegType& res_method_class =
+ const RegType& res_method_class =
reg_types_.FromClass(klass->GetDescriptor(&temp), klass,
klass->CannotBeAssignedFromOtherTypes());
if (!res_method_class.IsAssignableFrom(actual_arg_type)) {
@@ -3403,7 +3403,7 @@
<< " missing signature component";
return NULL;
}
- RegType& reg_type = reg_types_.FromDescriptor(GetClassLoader(), descriptor, false);
+ const RegType& reg_type = reg_types_.FromDescriptor(GetClassLoader(), descriptor, false);
uint32_t get_reg = is_range ? inst->VRegC_3rc() + actual_args : arg[actual_args];
if (!work_line_->VerifyRegisterType(get_reg, reg_type)) {
return res_method;
@@ -3431,7 +3431,7 @@
DCHECK_EQ(inst->Opcode(), Instruction::FILLED_NEW_ARRAY_RANGE);
type_idx = inst->VRegB_3rc();
}
- RegType& res_type = ResolveClassAndCheckAccess(type_idx);
+ const RegType& res_type = ResolveClassAndCheckAccess(type_idx);
if (res_type.IsConflict()) { // bad class
DCHECK_NE(failures_.size(), 0U);
} else {
@@ -3442,12 +3442,12 @@
/* make sure "size" register is valid type */
work_line_->VerifyRegisterType(inst->VRegB_22c(), reg_types_.Integer());
/* set register type to array class */
- RegType& precise_type = reg_types_.FromUninitialized(res_type);
+ const RegType& precise_type = reg_types_.FromUninitialized(res_type);
work_line_->SetRegisterType(inst->VRegA_22c(), precise_type);
} else {
// Verify each register. If "arg_count" is bad, VerifyRegisterType() will run off the end of
// the list and fail. It's legal, if silly, for arg_count to be zero.
- RegType& expected_type = reg_types_.GetComponentType(res_type, GetClassLoader());
+ const RegType& expected_type = reg_types_.GetComponentType(res_type, GetClassLoader());
uint32_t arg_count = (is_range) ? inst->VRegA_3rc() : inst->VRegA_35c();
uint32_t arg[5];
if (!is_range) {
@@ -3461,19 +3461,19 @@
}
}
// filled-array result goes into "result" register
- RegType& precise_type = reg_types_.FromUninitialized(res_type);
+ const RegType& precise_type = reg_types_.FromUninitialized(res_type);
work_line_->SetResultRegisterType(precise_type);
}
}
}
void MethodVerifier::VerifyAGet(const Instruction* inst,
- RegType& insn_type, bool is_primitive) {
- RegType& index_type = work_line_->GetRegisterType(inst->VRegC_23x());
+ const RegType& insn_type, bool is_primitive) {
+ const RegType& index_type = work_line_->GetRegisterType(inst->VRegC_23x());
if (!index_type.IsArrayIndexTypes()) {
Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Invalid reg type for array index (" << index_type << ")";
} else {
- RegType& array_type = work_line_->GetRegisterType(inst->VRegB_23x());
+ const RegType& array_type = work_line_->GetRegisterType(inst->VRegB_23x());
if (array_type.IsZero()) {
// Null array class; this code path will fail at runtime. Infer a merge-able type from the
// instruction type. TODO: have a proper notion of bottom here.
@@ -3489,7 +3489,7 @@
Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "not array type " << array_type << " with aget";
} else {
/* verify the class */
- RegType& component_type = reg_types_.GetComponentType(array_type, GetClassLoader());
+ const RegType& component_type = reg_types_.GetComponentType(array_type, GetClassLoader());
if (!component_type.IsReferenceTypes() && !is_primitive) {
Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "primitive array type " << array_type
<< " source for aget-object";
@@ -3516,12 +3516,12 @@
}
}
-void MethodVerifier::VerifyPrimitivePut(RegType& target_type, RegType& insn_type,
+void MethodVerifier::VerifyPrimitivePut(const RegType& target_type, const RegType& insn_type,
const uint32_t vregA) {
// Primitive assignability rules are weaker than regular assignability rules.
bool instruction_compatible;
bool value_compatible;
- RegType& value_type = work_line_->GetRegisterType(vregA);
+ const RegType& value_type = work_line_->GetRegisterType(vregA);
if (target_type.IsIntegralTypes()) {
instruction_compatible = target_type.Equals(insn_type);
value_compatible = value_type.IsIntegralTypes();
@@ -3533,7 +3533,7 @@
// Additional register check: this is not checked statically (as part of VerifyInstructions),
// as target_type depends on the resolved type of the field.
if (instruction_compatible && work_line_->NumRegs() > vregA + 1) {
- RegType& value_type_hi = work_line_->GetRegisterType(vregA + 1);
+ const RegType& value_type_hi = work_line_->GetRegisterType(vregA + 1);
value_compatible = value_type.IsLongTypes() && value_type.CheckWidePair(value_type_hi);
} else {
value_compatible = false;
@@ -3543,7 +3543,7 @@
// Additional register check: this is not checked statically (as part of VerifyInstructions),
// as target_type depends on the resolved type of the field.
if (instruction_compatible && work_line_->NumRegs() > vregA + 1) {
- RegType& value_type_hi = work_line_->GetRegisterType(vregA + 1);
+ const RegType& value_type_hi = work_line_->GetRegisterType(vregA + 1);
value_compatible = value_type.IsDoubleTypes() && value_type.CheckWidePair(value_type_hi);
} else {
value_compatible = false;
@@ -3568,19 +3568,19 @@
}
void MethodVerifier::VerifyAPut(const Instruction* inst,
- RegType& insn_type, bool is_primitive) {
- RegType& index_type = work_line_->GetRegisterType(inst->VRegC_23x());
+ const RegType& insn_type, bool is_primitive) {
+ const RegType& index_type = work_line_->GetRegisterType(inst->VRegC_23x());
if (!index_type.IsArrayIndexTypes()) {
Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Invalid reg type for array index (" << index_type << ")";
} else {
- RegType& array_type = work_line_->GetRegisterType(inst->VRegB_23x());
+ const RegType& array_type = work_line_->GetRegisterType(inst->VRegB_23x());
if (array_type.IsZero()) {
// Null array type; this code path will fail at runtime. Infer a merge-able type from the
// instruction type.
} else if (!array_type.IsArrayTypes()) {
Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "not array type " << array_type << " with aput";
} else {
- RegType& component_type = reg_types_.GetComponentType(array_type, GetClassLoader());
+ const RegType& component_type = reg_types_.GetComponentType(array_type, GetClassLoader());
const uint32_t vregA = inst->VRegA_23x();
if (is_primitive) {
VerifyPrimitivePut(component_type, insn_type, vregA);
@@ -3602,7 +3602,7 @@
mirror::ArtField* MethodVerifier::GetStaticField(int field_idx) {
const DexFile::FieldId& field_id = dex_file_->GetFieldId(field_idx);
// Check access to class
- RegType& klass_type = ResolveClassAndCheckAccess(field_id.class_idx_);
+ const RegType& klass_type = ResolveClassAndCheckAccess(field_id.class_idx_);
if (klass_type.IsConflict()) { // bad class
AppendToLastFailMessage(StringPrintf(" in attempt to access static field %d (%s) in %s",
field_idx, dex_file_->GetFieldName(field_id),
@@ -3634,10 +3634,10 @@
return field;
}
-mirror::ArtField* MethodVerifier::GetInstanceField(RegType& obj_type, int field_idx) {
+mirror::ArtField* MethodVerifier::GetInstanceField(const RegType& obj_type, int field_idx) {
const DexFile::FieldId& field_id = dex_file_->GetFieldId(field_idx);
// Check access to class
- RegType& klass_type = ResolveClassAndCheckAccess(field_id.class_idx_);
+ const RegType& klass_type = ResolveClassAndCheckAccess(field_id.class_idx_);
if (klass_type.IsConflict()) {
AppendToLastFailMessage(StringPrintf(" in attempt to access instance field %d (%s) in %s",
field_idx, dex_file_->GetFieldName(field_id),
@@ -3676,7 +3676,7 @@
return NULL;
} else {
mirror::Class* klass = field->GetDeclaringClass();
- RegType& field_klass =
+ const RegType& field_klass =
reg_types_.FromClass(dex_file_->GetFieldDeclaringClassDescriptor(field_id),
klass, klass->CannotBeAssignedFromOtherTypes());
if (obj_type.IsUninitializedTypes() &&
@@ -3701,17 +3701,17 @@
}
}
-void MethodVerifier::VerifyISGet(const Instruction* inst, RegType& insn_type,
+void MethodVerifier::VerifyISGet(const Instruction* inst, const RegType& insn_type,
bool is_primitive, bool is_static) {
uint32_t field_idx = is_static ? inst->VRegB_21c() : inst->VRegC_22c();
mirror::ArtField* field;
if (is_static) {
field = GetStaticField(field_idx);
} else {
- RegType& object_type = work_line_->GetRegisterType(inst->VRegB_22c());
+ const RegType& object_type = work_line_->GetRegisterType(inst->VRegB_22c());
field = GetInstanceField(object_type, field_idx);
}
- RegType* field_type = nullptr;
+ const RegType* field_type = nullptr;
if (field != NULL) {
Thread* self = Thread::Current();
mirror::Class* field_type_class;
@@ -3767,17 +3767,17 @@
}
}
-void MethodVerifier::VerifyISPut(const Instruction* inst, RegType& insn_type,
+void MethodVerifier::VerifyISPut(const Instruction* inst, const RegType& insn_type,
bool is_primitive, bool is_static) {
uint32_t field_idx = is_static ? inst->VRegB_21c() : inst->VRegC_22c();
mirror::ArtField* field;
if (is_static) {
field = GetStaticField(field_idx);
} else {
- RegType& object_type = work_line_->GetRegisterType(inst->VRegB_22c());
+ const RegType& object_type = work_line_->GetRegisterType(inst->VRegB_22c());
field = GetInstanceField(object_type, field_idx);
}
- RegType* field_type = nullptr;
+ const RegType* field_type = nullptr;
if (field != NULL) {
if (field->IsFinal() && field->GetDeclaringClass() != GetDeclaringClass().GetClass()) {
Fail(VERIFY_ERROR_ACCESS_FIELD) << "cannot modify final field " << PrettyField(field)
@@ -3829,7 +3829,7 @@
inst->Opcode() == Instruction::IPUT_QUICK ||
inst->Opcode() == Instruction::IPUT_WIDE_QUICK ||
inst->Opcode() == Instruction::IPUT_OBJECT_QUICK);
- RegType& object_type = reg_line->GetRegisterType(inst->VRegB_22c());
+ const RegType& object_type = reg_line->GetRegisterType(inst->VRegB_22c());
if (!object_type.HasClass()) {
VLOG(verifier) << "Failed to get mirror::Class* from '" << object_type << "'";
return nullptr;
@@ -3844,7 +3844,7 @@
return f;
}
-void MethodVerifier::VerifyIGetQuick(const Instruction* inst, RegType& insn_type,
+void MethodVerifier::VerifyIGetQuick(const Instruction* inst, const RegType& insn_type,
bool is_primitive) {
DCHECK(Runtime::Current()->IsStarted());
mirror::ArtField* field = GetQuickFieldAccess(inst, work_line_.get());
@@ -3859,7 +3859,7 @@
FieldHelper fh(h_field);
field_type_class = fh.GetType(can_load_classes_);
}
- RegType* field_type;
+ const RegType* field_type;
if (field_type_class != nullptr) {
field_type = ®_types_.FromClass(field->GetTypeDescriptor(), field_type_class,
field_type_class->CannotBeAssignedFromOtherTypes());
@@ -3904,7 +3904,7 @@
}
}
-void MethodVerifier::VerifyIPutQuick(const Instruction* inst, RegType& insn_type,
+void MethodVerifier::VerifyIPutQuick(const Instruction* inst, const RegType& insn_type,
bool is_primitive) {
DCHECK(Runtime::Current()->IsStarted());
mirror::ArtField* field = GetQuickFieldAccess(inst, work_line_.get());
@@ -3914,7 +3914,7 @@
}
const char* descriptor = field->GetTypeDescriptor();
mirror::ClassLoader* loader = field->GetDeclaringClass()->GetClassLoader();
- RegType& field_type = reg_types_.FromDescriptor(loader, descriptor, false);
+ const RegType& field_type = reg_types_.FromDescriptor(loader, descriptor, false);
if (field != NULL) {
if (field->IsFinal() && field->GetDeclaringClass() != GetDeclaringClass().GetClass()) {
Fail(VERIFY_ERROR_ACCESS_FIELD) << "cannot modify final field " << PrettyField(field)
@@ -3927,7 +3927,7 @@
// Primitive field assignability rules are weaker than regular assignability rules
bool instruction_compatible;
bool value_compatible;
- RegType& value_type = work_line_->GetRegisterType(vregA);
+ const RegType& value_type = work_line_->GetRegisterType(vregA);
if (field_type.IsIntegralTypes()) {
instruction_compatible = insn_type.IsIntegralTypes();
value_compatible = value_type.IsIntegralTypes();
@@ -4045,7 +4045,7 @@
return &insn_flags_[work_insn_idx_];
}
-RegType& MethodVerifier::GetMethodReturnType() {
+const RegType& MethodVerifier::GetMethodReturnType() {
if (return_type_ == nullptr) {
if (mirror_method_.Get() != nullptr) {
Thread* self = Thread::Current();
@@ -4072,7 +4072,7 @@
return *return_type_;
}
-RegType& MethodVerifier::GetDeclaringClass() {
+const RegType& MethodVerifier::GetDeclaringClass() {
if (declaring_class_ == NULL) {
const DexFile::MethodId& method_id = dex_file_->GetMethodId(dex_method_idx_);
const char* descriptor
@@ -4093,7 +4093,7 @@
DCHECK(line != nullptr) << "No register line at DEX pc " << StringPrintf("0x%x", dex_pc);
std::vector<int32_t> result;
for (size_t i = 0; i < line->NumRegs(); ++i) {
- RegType& type = line->GetRegisterType(i);
+ const RegType& type = line->GetRegisterType(i);
if (type.IsConstant()) {
result.push_back(type.IsPreciseConstant() ? kConstant : kImpreciseConstant);
result.push_back(type.ConstantValue());
@@ -4133,7 +4133,7 @@
return result;
}
-RegType& MethodVerifier::DetermineCat1Constant(int32_t value, bool precise) {
+const RegType& MethodVerifier::DetermineCat1Constant(int32_t value, bool precise) {
if (precise) {
// Precise constant type.
return reg_types_.FromCat1Const(value, true);