diff options
author | Ian Rogers <irogers@google.com> | 2014-09-10 22:41:42 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2014-09-10 22:41:43 +0000 |
commit | a87a7950ee79f42351992d211517f9f22e9393ee (patch) | |
tree | 251ccde96c5913a93782041fcf9624233794d773 /runtime | |
parent | be428b4da47339409aac0cfa153888c384dfaef7 (diff) | |
parent | d8f69b086baf6717ce949d1c4de90d73b91083b0 (diff) | |
download | art-a87a7950ee79f42351992d211517f9f22e9393ee.zip art-a87a7950ee79f42351992d211517f9f22e9393ee.tar.gz art-a87a7950ee79f42351992d211517f9f22e9393ee.tar.bz2 |
Merge "Revert "Add read barriers for the roots in the verifier.""
Diffstat (limited to 'runtime')
-rw-r--r-- | runtime/verifier/method_verifier-inl.h | 4 | ||||
-rw-r--r-- | runtime/verifier/method_verifier.cc | 192 | ||||
-rw-r--r-- | runtime/verifier/method_verifier.h | 32 | ||||
-rw-r--r-- | runtime/verifier/reg_type.cc | 113 | ||||
-rw-r--r-- | runtime/verifier/reg_type.h | 98 | ||||
-rw-r--r-- | runtime/verifier/reg_type_cache-inl.h | 4 | ||||
-rw-r--r-- | runtime/verifier/reg_type_cache.cc | 76 | ||||
-rw-r--r-- | runtime/verifier/reg_type_cache.h | 78 | ||||
-rw-r--r-- | runtime/verifier/reg_type_test.cc | 179 | ||||
-rw-r--r-- | runtime/verifier/register_line-inl.h | 2 | ||||
-rw-r--r-- | runtime/verifier/register_line.cc | 109 | ||||
-rw-r--r-- | runtime/verifier/register_line.h | 66 |
12 files changed, 478 insertions, 475 deletions
diff --git a/runtime/verifier/method_verifier-inl.h b/runtime/verifier/method_verifier-inl.h index 0f9aeb5..2d9fd53 100644 --- a/runtime/verifier/method_verifier-inl.h +++ b/runtime/verifier/method_verifier-inl.h @@ -66,9 +66,9 @@ inline bool MethodVerifier::HasFailures() const { return !failure_messages_.empty(); } -inline RegType& MethodVerifier::ResolveCheckedClass(uint32_t class_idx) { +inline const RegType& MethodVerifier::ResolveCheckedClass(uint32_t class_idx) { DCHECK(!HasFailures()); - RegType& result = ResolveClassAndCheckAccess(class_idx); + const RegType& result = ResolveClassAndCheckAccess(class_idx); DCHECK(!HasFailures()); return result; } 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 @@ bool MethodVerifier::SetTypesFromSignature() { // 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 @@ bool MethodVerifier::SetTypesFromSignature() { // 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 @@ bool MethodVerifier::SetTypesFromSignature() { 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 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) { * 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 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) { 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 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) { // 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 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) { 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 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) { 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 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) { 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 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) { /* 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 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) { 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 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) { */ 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 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) { } // 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 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) { 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 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) { 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 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) { << "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 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) { 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 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) { 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 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) { } 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 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) { 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 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) { } 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 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) { // 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 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) { 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 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) { 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 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) { 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 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) { * 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 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) { } /* 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 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) { } 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 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) { /* 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 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) { } 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 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) { 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 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) { 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 @@ RegType& MethodVerifier::ResolveClassAndCheckAccess(uint32_t class_idx) { 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 @@ RegType& MethodVerifier::GetCaughtExceptionType() { 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 @@ RegType& MethodVerifier::GetCaughtExceptionType() { 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 @@ mirror::ArtMethod* MethodVerifier::ResolveMethodAndCheckAccess(uint32_t dex_meth 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 @@ mirror::ArtMethod* MethodVerifier::VerifyInvocationArgsFromIterator(T* it, const * 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 @@ mirror::ArtMethod* MethodVerifier::VerifyInvocationArgsFromIterator(T* it, const } } 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 @@ mirror::ArtMethod* MethodVerifier::VerifyInvocationArgsFromIterator(T* it, const 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 @@ mirror::ArtMethod* MethodVerifier::VerifyInvocationArgs(const Instruction* inst, // 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 @@ mirror::ArtMethod* MethodVerifier::GetQuickInvokedMethod(const Instruction* inst 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 @@ mirror::ArtMethod* MethodVerifier::VerifyInvokeVirtualQuickArgs(const Instructio // 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 @@ mirror::ArtMethod* MethodVerifier::VerifyInvokeVirtualQuickArgs(const Instructio 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 @@ mirror::ArtMethod* MethodVerifier::VerifyInvokeVirtualQuickArgs(const Instructio << " 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 @@ void MethodVerifier::VerifyNewArray(const Instruction* inst, bool is_filled, boo 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 @@ void MethodVerifier::VerifyNewArray(const Instruction* inst, bool is_filled, boo /* 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 @@ void MethodVerifier::VerifyNewArray(const Instruction* inst, bool is_filled, boo } } // 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 @@ void MethodVerifier::VerifyAGet(const Instruction* inst, 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::VerifyAGet(const Instruction* inst, } } -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 @@ void MethodVerifier::VerifyPrimitivePut(RegType& target_type, RegType& insn_type // 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 @@ void MethodVerifier::VerifyPrimitivePut(RegType& target_type, RegType& insn_type // 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::VerifyPrimitivePut(RegType& target_type, RegType& insn_type } 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 @@ void MethodVerifier::VerifyAPut(const Instruction* inst, 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 @@ mirror::ArtField* MethodVerifier::GetStaticField(int field_idx) { 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 @@ mirror::ArtField* MethodVerifier::GetInstanceField(RegType& obj_type, int field_ 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 @@ mirror::ArtField* MethodVerifier::GetInstanceField(RegType& obj_type, int field_ } } -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::VerifyISGet(const Instruction* inst, RegType& insn_type, } } -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 @@ mirror::ArtField* MethodVerifier::GetQuickFieldAccess(const Instruction* inst, 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 @@ mirror::ArtField* MethodVerifier::GetQuickFieldAccess(const Instruction* inst, 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 @@ void MethodVerifier::VerifyIGetQuick(const Instruction* inst, RegType& insn_type 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::VerifyIGetQuick(const Instruction* inst, RegType& insn_type } } -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 @@ void MethodVerifier::VerifyIPutQuick(const Instruction* inst, RegType& insn_type } 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 @@ void MethodVerifier::VerifyIPutQuick(const Instruction* inst, RegType& insn_type // 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 @@ InstructionFlags* MethodVerifier::CurrentInsnFlags() { 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 @@ RegType& MethodVerifier::GetMethodReturnType() { 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 @@ std::vector<int32_t> MethodVerifier::DescribeVRegs(uint32_t dex_pc) { 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 @@ std::vector<int32_t> MethodVerifier::DescribeVRegs(uint32_t dex_pc) { 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); diff --git a/runtime/verifier/method_verifier.h b/runtime/verifier/method_verifier.h index af33414..45c0a03 100644 --- a/runtime/verifier/method_verifier.h +++ b/runtime/verifier/method_verifier.h @@ -232,7 +232,7 @@ class MethodVerifier { bool HasCheckCasts() const; bool HasVirtualOrInterfaceInvokes() const; bool HasFailures() const; - RegType& ResolveCheckedClass(uint32_t class_idx) + const RegType& ResolveCheckedClass(uint32_t class_idx) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); private: @@ -473,34 +473,34 @@ class MethodVerifier { SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // Helper to perform verification on puts of primitive type. - void VerifyPrimitivePut(RegType& target_type, RegType& insn_type, + void VerifyPrimitivePut(const RegType& target_type, const RegType& insn_type, const uint32_t vregA) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // Perform verification of an aget instruction. The destination register's type will be set to // be that of component type of the array unless the array type is unknown, in which case a // bottom type inferred from the type of instruction is used. is_primitive is false for an // aget-object. - void VerifyAGet(const Instruction* inst, RegType& insn_type, + void VerifyAGet(const Instruction* inst, const RegType& insn_type, bool is_primitive) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // Perform verification of an aput instruction. - void VerifyAPut(const Instruction* inst, RegType& insn_type, + void VerifyAPut(const Instruction* inst, const RegType& insn_type, bool is_primitive) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // Lookup instance field and fail for resolution violations - mirror::ArtField* GetInstanceField(RegType& obj_type, int field_idx) + mirror::ArtField* GetInstanceField(const RegType& obj_type, int field_idx) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // Lookup static field and fail for resolution violations mirror::ArtField* GetStaticField(int field_idx) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // Perform verification of an iget or sget instruction. - void VerifyISGet(const Instruction* inst, RegType& insn_type, + void VerifyISGet(const Instruction* inst, const RegType& insn_type, bool is_primitive, bool is_static) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // Perform verification of an iput or sput instruction. - void VerifyISPut(const Instruction* inst, RegType& insn_type, + void VerifyISPut(const Instruction* inst, const RegType& insn_type, bool is_primitive, bool is_static) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); @@ -510,18 +510,18 @@ class MethodVerifier { SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // Perform verification of an iget-quick instruction. - void VerifyIGetQuick(const Instruction* inst, RegType& insn_type, + void VerifyIGetQuick(const Instruction* inst, const RegType& insn_type, bool is_primitive) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // Perform verification of an iput-quick instruction. - void VerifyIPutQuick(const Instruction* inst, RegType& insn_type, + void VerifyIPutQuick(const Instruction* inst, const RegType& insn_type, bool is_primitive) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // Resolves a class based on an index and performs access checks to ensure the referrer can // access the resolved class. - RegType& ResolveClassAndCheckAccess(uint32_t class_idx) + const RegType& ResolveClassAndCheckAccess(uint32_t class_idx) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); /* @@ -529,7 +529,7 @@ class MethodVerifier { * address, determine the Join of all exceptions that can land here. Fails if no matching * exception handler can be found or if the Join of exception types fails. */ - RegType& GetCaughtExceptionType() + const RegType& GetCaughtExceptionType() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); /* @@ -615,14 +615,14 @@ class MethodVerifier { } // Return the register type for the method. - RegType& GetMethodReturnType() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + const RegType& GetMethodReturnType() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // Get a type representing the declaring class of the method. - RegType& GetDeclaringClass() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + const RegType& GetDeclaringClass() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); InstructionFlags* CurrentInsnFlags(); - RegType& DetermineCat1Constant(int32_t value, bool precise) + const RegType& DetermineCat1Constant(int32_t value, bool precise) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); RegTypeCache reg_types_; @@ -643,7 +643,7 @@ class MethodVerifier { // Its object representation if known. ConstHandle<mirror::ArtMethod> mirror_method_ GUARDED_BY(Locks::mutator_lock_); const uint32_t method_access_flags_; // Method's access flags. - RegType* return_type_; // Lazily computed return type of the method. + const RegType* return_type_; // Lazily computed return type of the method. const DexFile* const dex_file_; // The dex file containing the method. // The dex_cache for the declaring class of the method. ConstHandle<mirror::DexCache> dex_cache_ GUARDED_BY(Locks::mutator_lock_); @@ -651,7 +651,7 @@ class MethodVerifier { ConstHandle<mirror::ClassLoader> class_loader_ GUARDED_BY(Locks::mutator_lock_); const DexFile::ClassDef* const class_def_; // The class def of the declaring class of the method. const DexFile::CodeItem* const code_item_; // The code item containing the code for the method. - RegType* declaring_class_; // Lazily computed reg type of the method's declaring class. + const RegType* declaring_class_; // Lazily computed reg type of the method's declaring class. // Instruction widths and flags, one entry per code unit. std::unique_ptr<InstructionFlags[]> insn_flags_; // The dex PC of a FindLocksAtDexPc request, -1 otherwise. diff --git a/runtime/verifier/reg_type.cc b/runtime/verifier/reg_type.cc index 30be82f..197b120 100644 --- a/runtime/verifier/reg_type.cc +++ b/runtime/verifier/reg_type.cc @@ -81,7 +81,7 @@ Cat2Type::Cat2Type(mirror::Class* klass, const std::string& descriptor, uint16_t : PrimitiveType(klass, descriptor, cache_id) { } -std::string PreciseConstType::Dump() { +std::string PreciseConstType::Dump() const { std::stringstream result; uint32_t val = ConstantValue(); if (val == 0) { @@ -98,47 +98,47 @@ std::string PreciseConstType::Dump() { return result.str(); } -std::string BooleanType::Dump() { +std::string BooleanType::Dump() const { return "Boolean"; } -std::string ConflictType::Dump() { +std::string ConflictType::Dump() const { return "Conflict"; } -std::string ByteType::Dump() { +std::string ByteType::Dump() const { return "Byte"; } -std::string ShortType::Dump() { +std::string ShortType::Dump() const { return "Short"; } -std::string CharType::Dump() { +std::string CharType::Dump() const { return "Char"; } -std::string FloatType::Dump() { +std::string FloatType::Dump() const { return "Float"; } -std::string LongLoType::Dump() { +std::string LongLoType::Dump() const { return "Long (Low Half)"; } -std::string LongHiType::Dump() { +std::string LongHiType::Dump() const { return "Long (High Half)"; } -std::string DoubleLoType::Dump() { +std::string DoubleLoType::Dump() const { return "Double (Low Half)"; } -std::string DoubleHiType::Dump() { +std::string DoubleHiType::Dump() const { return "Double (High Half)"; } -std::string IntegerType::Dump() { +std::string IntegerType::Dump() const { return "Integer"; } @@ -361,7 +361,7 @@ void BooleanType::Destroy() { } } -std::string UndefinedType::Dump() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { +std::string UndefinedType::Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { return "Undefined"; } @@ -391,7 +391,7 @@ PreciseReferenceType::PreciseReferenceType(mirror::Class* klass, const std::stri DCHECK(klass->IsInstantiable()); } -std::string UnresolvedMergedType::Dump() { +std::string UnresolvedMergedType::Dump() const { std::stringstream result; std::set<uint16_t> types = GetMergedTypes(); result << "UnresolvedMergedReferences("; @@ -405,20 +405,20 @@ std::string UnresolvedMergedType::Dump() { return result.str(); } -std::string UnresolvedSuperClass::Dump() { +std::string UnresolvedSuperClass::Dump() const { std::stringstream result; uint16_t super_type_id = GetUnresolvedSuperClassChildId(); result << "UnresolvedSuperClass(" << reg_type_cache_->GetFromId(super_type_id).Dump() << ")"; return result.str(); } -std::string UnresolvedReferenceType::Dump() { +std::string UnresolvedReferenceType::Dump() const { std::stringstream result; result << "Unresolved Reference" << ": " << PrettyDescriptor(GetDescriptor().c_str()); return result.str(); } -std::string UnresolvedUninitializedRefType::Dump() { +std::string UnresolvedUninitializedRefType::Dump() const { std::stringstream result; result << "Unresolved And Uninitialized Reference" << ": " << PrettyDescriptor(GetDescriptor().c_str()) @@ -426,40 +426,40 @@ std::string UnresolvedUninitializedRefType::Dump() { return result.str(); } -std::string UnresolvedUninitializedThisRefType::Dump() { +std::string UnresolvedUninitializedThisRefType::Dump() const { std::stringstream result; result << "Unresolved And Uninitialized This Reference" << PrettyDescriptor(GetDescriptor().c_str()); return result.str(); } -std::string ReferenceType::Dump() { +std::string ReferenceType::Dump() const { std::stringstream result; result << "Reference" << ": " << PrettyDescriptor(GetClass()); return result.str(); } -std::string PreciseReferenceType::Dump() { +std::string PreciseReferenceType::Dump() const { std::stringstream result; result << "Precise Reference" << ": "<< PrettyDescriptor(GetClass()); return result.str(); } -std::string UninitializedReferenceType::Dump() { +std::string UninitializedReferenceType::Dump() const { std::stringstream result; result << "Uninitialized Reference" << ": " << PrettyDescriptor(GetClass()); result << " Allocation PC: " << GetAllocationPc(); return result.str(); } -std::string UninitializedThisReferenceType::Dump() { +std::string UninitializedThisReferenceType::Dump() const { std::stringstream result; result << "Uninitialized This Reference" << ": " << PrettyDescriptor(GetClass()); result << "Allocation PC: " << GetAllocationPc(); return result.str(); } -std::string ImpreciseConstType::Dump() { +std::string ImpreciseConstType::Dump() const { std::stringstream result; uint32_t val = ConstantValue(); if (val == 0) { @@ -474,7 +474,7 @@ std::string ImpreciseConstType::Dump() { } return result.str(); } -std::string PreciseConstLoType::Dump() { +std::string PreciseConstLoType::Dump() const { std::stringstream result; int32_t val = ConstantValueLo(); @@ -488,7 +488,7 @@ std::string PreciseConstLoType::Dump() { return result.str(); } -std::string ImpreciseConstLoType::Dump() { +std::string ImpreciseConstLoType::Dump() const { std::stringstream result; int32_t val = ConstantValueLo(); @@ -502,7 +502,7 @@ std::string ImpreciseConstLoType::Dump() { return result.str(); } -std::string PreciseConstHiType::Dump() { +std::string PreciseConstHiType::Dump() const { std::stringstream result; int32_t val = ConstantValueHi(); result << "Precise "; @@ -515,7 +515,7 @@ std::string PreciseConstHiType::Dump() { return result.str(); } -std::string ImpreciseConstHiType::Dump() { +std::string ImpreciseConstHiType::Dump() const { std::stringstream result; int32_t val = ConstantValueHi(); result << "Imprecise "; @@ -532,7 +532,7 @@ ConstantType::ConstantType(uint32_t constant, uint16_t cache_id) : RegType(NULL, "", cache_id), constant_(constant) { } -RegType& UndefinedType::Merge(RegType& incoming_type, RegTypeCache* reg_types) +const RegType& UndefinedType::Merge(const RegType& incoming_type, RegTypeCache* reg_types) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { if (incoming_type.IsUndefined()) { return *this; // Undefined MERGE Undefined => Undefined @@ -540,7 +540,7 @@ RegType& UndefinedType::Merge(RegType& incoming_type, RegTypeCache* reg_types) return reg_types->Conflict(); } -RegType& RegType::HighHalf(RegTypeCache* cache) const { +const RegType& RegType::HighHalf(RegTypeCache* cache) const { DCHECK(IsLowHalf()); if (IsLongLo()) { return cache->LongHi(); @@ -588,10 +588,12 @@ bool UnresolvedType::IsNonZeroReferenceTypes() const { } std::set<uint16_t> UnresolvedMergedType::GetMergedTypes() const { std::pair<uint16_t, uint16_t> refs = GetTopMergedTypes(); - RegType& _left(reg_type_cache_->GetFromId(refs.first)); - UnresolvedMergedType* left = down_cast<UnresolvedMergedType*>(&_left); + const RegType& _left(reg_type_cache_->GetFromId(refs.first)); + RegType& __left(const_cast<RegType&>(_left)); + UnresolvedMergedType* left = down_cast<UnresolvedMergedType*>(&__left); - RegType& _right(reg_type_cache_->GetFromId(refs.second)); + RegType& _right( + const_cast<RegType&>(reg_type_cache_->GetFromId(refs.second))); UnresolvedMergedType* right = down_cast<UnresolvedMergedType*>(&_right); std::set<uint16_t> types; @@ -614,7 +616,7 @@ std::set<uint16_t> UnresolvedMergedType::GetMergedTypes() const { return types; } -RegType& RegType::GetSuperClass(RegTypeCache* cache) { +const RegType& RegType::GetSuperClass(RegTypeCache* cache) const { if (!IsUnresolvedTypes()) { mirror::Class* super_klass = GetClass()->GetSuperClass(); if (super_klass != NULL) { @@ -636,7 +638,7 @@ RegType& RegType::GetSuperClass(RegTypeCache* cache) { } } -bool RegType::CanAccess(RegType& other) { +bool RegType::CanAccess(const RegType& other) const { if (Equals(other)) { return true; // Trivial accessibility. } else { @@ -652,7 +654,7 @@ bool RegType::CanAccess(RegType& other) { } } -bool RegType::CanAccessMember(mirror::Class* klass, uint32_t access_flags) { +bool RegType::CanAccessMember(mirror::Class* klass, uint32_t access_flags) const { if ((access_flags & kAccPublic) != 0) { return true; } @@ -663,7 +665,7 @@ bool RegType::CanAccessMember(mirror::Class* klass, uint32_t access_flags) { } } -bool RegType::IsObjectArrayTypes() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { +bool RegType::IsObjectArrayTypes() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { if (IsUnresolvedTypes() && !IsUnresolvedMergedReference() && !IsUnresolvedSuperClass()) { // Primitive arrays will always resolve DCHECK(descriptor_[1] == 'L' || descriptor_[1] == '['); @@ -676,11 +678,11 @@ bool RegType::IsObjectArrayTypes() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { } } -bool RegType::IsJavaLangObject() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { +bool RegType::IsJavaLangObject() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { return IsReference() && GetClass()->IsObjectClass(); } -bool RegType::IsArrayTypes() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { +bool RegType::IsArrayTypes() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { if (IsUnresolvedTypes() && !IsUnresolvedMergedReference() && !IsUnresolvedSuperClass()) { return descriptor_[0] == '['; } else if (HasClass()) { @@ -690,7 +692,7 @@ bool RegType::IsArrayTypes() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { } } -bool RegType::IsJavaLangObjectArray() { +bool RegType::IsJavaLangObjectArray() const { if (HasClass()) { mirror::Class* type = GetClass(); return type->IsArrayClass() && type->GetComponentType()->IsObjectClass(); @@ -698,7 +700,7 @@ bool RegType::IsJavaLangObjectArray() { return false; } -bool RegType::IsInstantiableTypes() { +bool RegType::IsInstantiableTypes() const { return IsUnresolvedTypes() || (IsNonZeroReferenceTypes() && GetClass()->IsInstantiable()); } @@ -706,7 +708,7 @@ ImpreciseConstType::ImpreciseConstType(uint32_t constat, uint16_t cache_id) : ConstantType(constat, cache_id) { } -static bool AssignableFrom(RegType& lhs, RegType& rhs, bool strict) +static bool AssignableFrom(const RegType& lhs, const RegType& rhs, bool strict) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { if (lhs.Equals(rhs)) { return true; @@ -754,11 +756,11 @@ static bool AssignableFrom(RegType& lhs, RegType& rhs, bool strict) } } -bool RegType::IsAssignableFrom(RegType& src) { +bool RegType::IsAssignableFrom(const RegType& src) const { return AssignableFrom(*this, src, false); } -bool RegType::IsStrictlyAssignableFrom(RegType& src) { +bool RegType::IsStrictlyAssignableFrom(const RegType& src) const { return AssignableFrom(*this, src, true); } @@ -776,11 +778,11 @@ int32_t ConstantType::ConstantValueHi() const { } } -static RegType& SelectNonConstant(RegType& a, RegType& b) { +static const RegType& SelectNonConstant(const RegType& a, const RegType& b) { return a.IsConstantTypes() ? b : a; } -RegType& RegType::Merge(RegType& incoming_type, RegTypeCache* reg_types) { +const RegType& RegType::Merge(const RegType& incoming_type, RegTypeCache* reg_types) const { DCHECK(!Equals(incoming_type)); // Trivial equality handled by caller if (IsConflict()) { return *this; // Conflict MERGE * => Conflict @@ -960,16 +962,16 @@ mirror::Class* RegType::ClassJoin(mirror::Class* s, mirror::Class* t) { void RegType::CheckInvariants() const { if (IsConstant() || IsConstantLo() || IsConstantHi()) { CHECK(descriptor_.empty()) << *this; - CHECK(klass_.IsNull()) << *this; + CHECK(klass_ == NULL) << *this; } - if (!klass_.IsNull()) { + if (klass_ != NULL) { CHECK(!descriptor_.empty()) << *this; } } void RegType::VisitRoots(RootCallback* callback, void* arg) { - if (!klass_.IsNull()) { - klass_.VisitRoot(callback, arg, 0, kRootUnknown); + if (klass_ != nullptr) { + callback(reinterpret_cast<mirror::Object**>(&klass_), arg, 0, kRootUnknown); } } @@ -980,37 +982,36 @@ void UninitializedThisReferenceType::CheckInvariants() const { void UnresolvedUninitializedThisRefType::CheckInvariants() const { CHECK_EQ(GetAllocationPc(), 0U) << *this; CHECK(!descriptor_.empty()) << *this; - CHECK(klass_.IsNull()) << *this; + CHECK(klass_ == NULL) << *this; } void UnresolvedUninitializedRefType::CheckInvariants() const { CHECK(!descriptor_.empty()) << *this; - CHECK(klass_.IsNull()) << *this; + CHECK(klass_ == NULL) << *this; } void UnresolvedMergedType::CheckInvariants() const { // Unresolved merged types: merged types should be defined. CHECK(descriptor_.empty()) << *this; - CHECK(klass_.IsNull()) << *this; + CHECK(klass_ == NULL) << *this; CHECK_NE(merged_types_.first, 0U) << *this; CHECK_NE(merged_types_.second, 0U) << *this; } void UnresolvedReferenceType::CheckInvariants() const { CHECK(!descriptor_.empty()) << *this; - CHECK(klass_.IsNull()) << *this; + CHECK(klass_ == NULL) << *this; } void UnresolvedSuperClass::CheckInvariants() const { // Unresolved merged types: merged types should be defined. CHECK(descriptor_.empty()) << *this; - CHECK(klass_.IsNull()) << *this; + CHECK(klass_ == NULL) << *this; CHECK_NE(unresolved_child_id_, 0U) << *this; } std::ostream& operator<<(std::ostream& os, const RegType& rhs) { - RegType& rhs_non_const = const_cast<RegType&>(rhs); - os << rhs_non_const.Dump(); + os << rhs.Dump(); return os; } diff --git a/runtime/verifier/reg_type.h b/runtime/verifier/reg_type.h index 1682d4e..f211f8a 100644 --- a/runtime/verifier/reg_type.h +++ b/runtime/verifier/reg_type.h @@ -26,7 +26,6 @@ #include "base/macros.h" #include "base/mutex.h" -#include "gc_root.h" #include "globals.h" #include "object_callbacks.h" #include "primitive.h" @@ -109,7 +108,7 @@ class RegType { return IsLowHalf(); } // Check this is the low half, and that type_h is its matching high-half. - inline bool CheckWidePair(RegType& type_h) const { + inline bool CheckWidePair(const RegType& type_h) const { if (IsLowHalf()) { return ((IsPreciseConstantLo() && type_h.IsPreciseConstantHi()) || (IsPreciseConstantLo() && type_h.IsImpreciseConstantHi()) || @@ -121,7 +120,7 @@ class RegType { return false; } // The high half that corresponds to this low half - RegType& HighHalf(RegTypeCache* cache) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + const RegType& HighHalf(RegTypeCache* cache) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); bool IsConstantBoolean() const { return IsConstant() && (ConstantValue() >= 0) && (ConstantValue() <= 1); @@ -200,54 +199,55 @@ class RegType { virtual bool HasClass() const { return false; } - bool IsJavaLangObject() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - bool IsArrayTypes() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - bool IsObjectArrayTypes() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + bool IsJavaLangObject() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + bool IsArrayTypes() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + bool IsObjectArrayTypes() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); Primitive::Type GetPrimitiveType() const; - bool IsJavaLangObjectArray() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - bool IsInstantiableTypes() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + bool IsJavaLangObjectArray() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + bool IsInstantiableTypes() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); const std::string& GetDescriptor() const { DCHECK(HasClass() || (IsUnresolvedTypes() && !IsUnresolvedMergedReference() && !IsUnresolvedSuperClass())); return descriptor_; } - mirror::Class* GetClass() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { + mirror::Class* GetClass() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { DCHECK(!IsUnresolvedReference()); - DCHECK(!klass_.IsNull()) << Dump(); + DCHECK(klass_ != NULL) << Dump(); DCHECK(HasClass()); - return klass_.Read(); + return klass_; } uint16_t GetId() const { return cache_id_; } - RegType& GetSuperClass(RegTypeCache* cache) + const RegType& GetSuperClass(RegTypeCache* cache) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - virtual std::string Dump() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) = 0; + virtual std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) = 0; // Can this type access other? - bool CanAccess(RegType& other) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + bool CanAccess(const RegType& other) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // Can this type access a member with the given properties? - bool CanAccessMember(mirror::Class* klass, uint32_t access_flags) + bool CanAccessMember(mirror::Class* klass, uint32_t access_flags) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // Can this type be assigned by src? // Note: Object and interface types may always be assigned to one another, see comment on // ClassJoin. - bool IsAssignableFrom(RegType& src) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + bool IsAssignableFrom(const RegType& src) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // Can this type be assigned by src? Variant of IsAssignableFrom that doesn't allow assignment to // an interface from an Object. - bool IsStrictlyAssignableFrom(RegType& src) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + bool IsStrictlyAssignableFrom(const RegType& src) const + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // Are these RegTypes the same? - bool Equals(RegType& other) const { + bool Equals(const RegType& other) const { return GetId() == other.GetId(); } // Compute the merge of this register from one edge (path) with incoming_type from another. - virtual RegType& Merge(RegType& incoming_type, RegTypeCache* reg_types) + virtual const RegType& Merge(const RegType& incoming_type, RegTypeCache* reg_types) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); /* @@ -276,7 +276,7 @@ class RegType { protected: RegType(mirror::Class* klass, const std::string& descriptor, uint16_t cache_id) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) - : descriptor_(descriptor), klass_(GcRoot<mirror::Class>(klass)), cache_id_(cache_id) { + : descriptor_(descriptor), klass_(klass), cache_id_(cache_id) { if (kIsDebugBuild) { CheckInvariants(); } @@ -286,7 +286,7 @@ class RegType { const std::string descriptor_; - GcRoot<mirror::Class> klass_; + mirror::Class* klass_; // Non-const only due to moving classes. const uint16_t cache_id_; friend class RegTypeCache; @@ -302,7 +302,7 @@ class ConflictType : public RegType { return true; } - std::string Dump() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // Get the singleton Conflict instance. static ConflictType* GetInstance(); @@ -332,7 +332,7 @@ class UndefinedType : public RegType { return true; } - std::string Dump() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // Get the singleton Undefined instance. static UndefinedType* GetInstance(); @@ -351,7 +351,7 @@ class UndefinedType : public RegType { : RegType(klass, descriptor, cache_id) { } - virtual RegType& Merge(RegType& incoming_type, RegTypeCache* reg_types) + virtual const RegType& Merge(const RegType& incoming_type, RegTypeCache* reg_types) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); static UndefinedType* instance_; @@ -374,7 +374,7 @@ class IntegerType : public Cat1Type { bool IsInteger() const { return true; } - std::string Dump() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); static IntegerType* CreateInstance(mirror::Class* klass, const std::string& descriptor, uint16_t cache_id) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); @@ -393,7 +393,7 @@ class BooleanType : public Cat1Type { bool IsBoolean() const { return true; } - std::string Dump() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); static BooleanType* CreateInstance(mirror::Class* klass, const std::string& descriptor, uint16_t cache_id) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); @@ -413,7 +413,7 @@ class ByteType : public Cat1Type { bool IsByte() const { return true; } - std::string Dump() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); static ByteType* CreateInstance(mirror::Class* klass, const std::string& descriptor, uint16_t cache_id) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); @@ -432,7 +432,7 @@ class ShortType : public Cat1Type { bool IsShort() const { return true; } - std::string Dump() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); static ShortType* CreateInstance(mirror::Class* klass, const std::string& descriptor, uint16_t cache_id) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); @@ -451,7 +451,7 @@ class CharType : public Cat1Type { bool IsChar() const { return true; } - std::string Dump() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); static CharType* CreateInstance(mirror::Class* klass, const std::string& descriptor, uint16_t cache_id) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); @@ -470,7 +470,7 @@ class FloatType : public Cat1Type { bool IsFloat() const { return true; } - std::string Dump() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); static FloatType* CreateInstance(mirror::Class* klass, const std::string& descriptor, uint16_t cache_id) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); @@ -492,7 +492,7 @@ class Cat2Type : public PrimitiveType { class LongLoType : public Cat2Type { public: - std::string Dump() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); bool IsLongLo() const { return true; } @@ -514,7 +514,7 @@ class LongLoType : public Cat2Type { class LongHiType : public Cat2Type { public: - std::string Dump() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); bool IsLongHi() const { return true; } @@ -533,7 +533,7 @@ class LongHiType : public Cat2Type { class DoubleLoType : public Cat2Type { public: - std::string Dump() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); bool IsDoubleLo() const { return true; } @@ -555,7 +555,7 @@ class DoubleLoType : public Cat2Type { class DoubleHiType : public Cat2Type { public: - std::string Dump(); + std::string Dump() const; virtual bool IsDoubleHi() const { return true; } @@ -622,7 +622,7 @@ class PreciseConstType : public ConstantType { return true; } - std::string Dump() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); }; class PreciseConstLoType : public ConstantType { @@ -634,7 +634,7 @@ class PreciseConstLoType : public ConstantType { bool IsPreciseConstantLo() const { return true; } - std::string Dump() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); }; class PreciseConstHiType : public ConstantType { @@ -646,7 +646,7 @@ class PreciseConstHiType : public ConstantType { bool IsPreciseConstantHi() const { return true; } - std::string Dump() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); }; class ImpreciseConstType : public ConstantType { @@ -656,7 +656,7 @@ class ImpreciseConstType : public ConstantType { bool IsImpreciseConstant() const { return true; } - std::string Dump() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); }; class ImpreciseConstLoType : public ConstantType { @@ -667,7 +667,7 @@ class ImpreciseConstLoType : public ConstantType { bool IsImpreciseConstantLo() const { return true; } - std::string Dump() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); }; class ImpreciseConstHiType : public ConstantType { @@ -678,7 +678,7 @@ class ImpreciseConstHiType : public ConstantType { bool IsImpreciseConstantHi() const { return true; } - std::string Dump() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); }; // Common parent of all uninitialized types. Uninitialized types are created by "new" dex @@ -719,7 +719,7 @@ class UninitializedReferenceType : public UninitializedType { return true; } - std::string Dump() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); }; // Similar to UnresolvedReferenceType but not yet having been passed to a constructor. @@ -738,7 +738,7 @@ class UnresolvedUninitializedRefType : public UninitializedType { return true; } - std::string Dump() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); private: void CheckInvariants() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); }; @@ -763,7 +763,7 @@ class UninitializedThisReferenceType : public UninitializedType { return true; } - std::string Dump() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); private: void CheckInvariants() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); @@ -783,7 +783,7 @@ class UnresolvedUninitializedThisRefType : public UninitializedType { return true; } - std::string Dump() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); private: void CheckInvariants() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); }; @@ -808,7 +808,7 @@ class ReferenceType : public RegType { return true; } - std::string Dump() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); }; // A type of register holding a reference to an Object of type GetClass and only an object of that @@ -830,7 +830,7 @@ class PreciseReferenceType : public RegType { return true; } - std::string Dump() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); }; // Common parent of unresolved types. @@ -858,7 +858,7 @@ class UnresolvedReferenceType : public UnresolvedType { return true; } - std::string Dump() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); private: void CheckInvariants() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); }; @@ -884,7 +884,7 @@ class UnresolvedSuperClass : public UnresolvedType { return static_cast<uint16_t>(unresolved_child_id_ & 0xFFFF); } - std::string Dump() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); private: void CheckInvariants() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); @@ -919,7 +919,7 @@ class UnresolvedMergedType : public UnresolvedType { return true; } - std::string Dump() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); private: void CheckInvariants() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); diff --git a/runtime/verifier/reg_type_cache-inl.h b/runtime/verifier/reg_type_cache-inl.h index fdf96a8..fc9e5c9 100644 --- a/runtime/verifier/reg_type_cache-inl.h +++ b/runtime/verifier/reg_type_cache-inl.h @@ -24,14 +24,14 @@ namespace art { namespace verifier { -inline RegType& RegTypeCache::GetFromId(uint16_t id) const { +inline const art::verifier::RegType& RegTypeCache::GetFromId(uint16_t id) const { DCHECK_LT(id, entries_.size()); RegType* result = entries_[id]; DCHECK(result != NULL); return *result; } -inline ConstantType& RegTypeCache::FromCat1Const(int32_t value, bool precise) { +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)) { diff --git a/runtime/verifier/reg_type_cache.cc b/runtime/verifier/reg_type_cache.cc index 482bb4d..641f327 100644 --- a/runtime/verifier/reg_type_cache.cc +++ b/runtime/verifier/reg_type_cache.cc @@ -65,8 +65,8 @@ void RegTypeCache::FillPrimitiveAndSmallConstantTypes() { DCHECK_EQ(entries_.size(), primitive_count_); } -RegType& RegTypeCache::FromDescriptor(mirror::ClassLoader* loader, const char* descriptor, - bool precise) { +const RegType& RegTypeCache::FromDescriptor(mirror::ClassLoader* loader, const char* descriptor, + bool precise) { DCHECK(RegTypeCache::primitive_initialized_); if (descriptor[1] == '\0') { switch (descriptor[0]) { @@ -97,7 +97,7 @@ RegType& RegTypeCache::FromDescriptor(mirror::ClassLoader* loader, const char* d } }; -RegType& RegTypeCache::RegTypeFromPrimitiveType(Primitive::Type prim_type) const { +const RegType& RegTypeCache::RegTypeFromPrimitiveType(Primitive::Type prim_type) const { CHECK(RegTypeCache::primitive_initialized_); switch (prim_type) { case Primitive::kPrimBoolean: @@ -156,8 +156,8 @@ mirror::Class* RegTypeCache::ResolveClass(const char* descriptor, mirror::ClassL return klass; } -RegType& RegTypeCache::From(mirror::ClassLoader* loader, const char* descriptor, - bool precise) { +const RegType& RegTypeCache::From(mirror::ClassLoader* loader, const char* descriptor, + bool precise) { // Try looking up the class in the cache first. We use a StringPiece to avoid continual strlen // operations on the descriptor. StringPiece descriptor_sp(descriptor); @@ -210,7 +210,7 @@ RegType& RegTypeCache::From(mirror::ClassLoader* loader, const char* descriptor, } } -RegType& RegTypeCache::FromClass(const char* descriptor, mirror::Class* klass, bool precise) { +const RegType& RegTypeCache::FromClass(const char* descriptor, mirror::Class* klass, bool precise) { DCHECK(klass != nullptr); if (klass->IsPrimitive()) { // Note: precise isn't used for primitive classes. A char is assignable to an int. All @@ -220,7 +220,7 @@ RegType& RegTypeCache::FromClass(const char* descriptor, mirror::Class* klass, b // Look for the reference in the list of entries to have. for (size_t i = primitive_count_; i < entries_.size(); i++) { RegType* cur_entry = entries_[i]; - if (cur_entry->klass_.Read() == klass && MatchingPrecisionForClass(cur_entry, precise)) { + if (cur_entry->klass_ == klass && MatchingPrecisionForClass(cur_entry, precise)) { return *cur_entry; } } @@ -313,15 +313,17 @@ void RegTypeCache::CreatePrimitiveAndSmallConstantTypes() { } } -RegType& RegTypeCache::FromUnresolvedMerge(RegType& left, RegType& right) { +const RegType& RegTypeCache::FromUnresolvedMerge(const RegType& left, const RegType& right) { std::set<uint16_t> types; if (left.IsUnresolvedMergedReference()) { - types = (down_cast<UnresolvedMergedType*>(&left))->GetMergedTypes(); + RegType& non_const(const_cast<RegType&>(left)); + types = (down_cast<UnresolvedMergedType*>(&non_const))->GetMergedTypes(); } else { types.insert(left.GetId()); } if (right.IsUnresolvedMergedReference()) { - std::set<uint16_t> right_types = (down_cast<UnresolvedMergedType*>(&right))->GetMergedTypes(); + RegType& non_const(const_cast<RegType&>(right)); + std::set<uint16_t> right_types = (down_cast<UnresolvedMergedType*>(&non_const))->GetMergedTypes(); types.insert(right_types.begin(), right_types.end()); } else { types.insert(right.GetId()); @@ -348,7 +350,7 @@ RegType& RegTypeCache::FromUnresolvedMerge(RegType& left, RegType& right) { return *entry; } -RegType& RegTypeCache::FromUnresolvedSuperClass(RegType& child) { +const RegType& RegTypeCache::FromUnresolvedSuperClass(const RegType& child) { // Check if entry already exists. for (size_t i = primitive_count_; i < entries_.size(); i++) { RegType* cur_entry = entries_[i]; @@ -367,7 +369,7 @@ RegType& RegTypeCache::FromUnresolvedSuperClass(RegType& child) { return *entry; } -UninitializedType& RegTypeCache::Uninitialized(RegType& type, uint32_t allocation_pc) { +const UninitializedType& RegTypeCache::Uninitialized(const RegType& type, uint32_t allocation_pc) { UninitializedType* entry = NULL; const std::string& descriptor(type.GetDescriptor()); if (type.IsUnresolvedTypes()) { @@ -397,7 +399,7 @@ UninitializedType& RegTypeCache::Uninitialized(RegType& type, uint32_t allocatio return *entry; } -RegType& RegTypeCache::FromUninitialized(RegType& uninit_type) { +const RegType& RegTypeCache::FromUninitialized(const RegType& uninit_type) { RegType* entry; if (uninit_type.IsUnresolvedTypes()) { @@ -439,44 +441,44 @@ RegType& RegTypeCache::FromUninitialized(RegType& uninit_type) { return *entry; } -ImpreciseConstType& RegTypeCache::ByteConstant() { - ConstantType& result = FromCat1Const(std::numeric_limits<jbyte>::min(), false); +const ImpreciseConstType& RegTypeCache::ByteConstant() { + const ConstantType& result = FromCat1Const(std::numeric_limits<jbyte>::min(), false); DCHECK(result.IsImpreciseConstant()); - return *down_cast<ImpreciseConstType*>(&result); + return *down_cast<const ImpreciseConstType*>(&result); } -ImpreciseConstType& RegTypeCache::CharConstant() { +const ImpreciseConstType& RegTypeCache::CharConstant() { int32_t jchar_max = static_cast<int32_t>(std::numeric_limits<jchar>::max()); - ConstantType& result = FromCat1Const(jchar_max, false); + const ConstantType& result = FromCat1Const(jchar_max, false); DCHECK(result.IsImpreciseConstant()); - return *down_cast<ImpreciseConstType*>(&result); + return *down_cast<const ImpreciseConstType*>(&result); } -ImpreciseConstType& RegTypeCache::ShortConstant() { - ConstantType& result = FromCat1Const(std::numeric_limits<jshort>::min(), false); +const ImpreciseConstType& RegTypeCache::ShortConstant() { + const ConstantType& result = FromCat1Const(std::numeric_limits<jshort>::min(), false); DCHECK(result.IsImpreciseConstant()); - return *down_cast<ImpreciseConstType*>(&result); + return *down_cast<const ImpreciseConstType*>(&result); } -ImpreciseConstType& RegTypeCache::IntConstant() { - ConstantType& result = FromCat1Const(std::numeric_limits<jint>::max(), false); +const ImpreciseConstType& RegTypeCache::IntConstant() { + const ConstantType& result = FromCat1Const(std::numeric_limits<jint>::max(), false); DCHECK(result.IsImpreciseConstant()); - return *down_cast<ImpreciseConstType*>(&result); + return *down_cast<const ImpreciseConstType*>(&result); } -ImpreciseConstType& RegTypeCache::PosByteConstant() { - ConstantType& result = FromCat1Const(std::numeric_limits<jbyte>::max(), false); +const ImpreciseConstType& RegTypeCache::PosByteConstant() { + const ConstantType& result = FromCat1Const(std::numeric_limits<jbyte>::max(), false); DCHECK(result.IsImpreciseConstant()); - return *down_cast<ImpreciseConstType*>(&result); + return *down_cast<const ImpreciseConstType*>(&result); } -ImpreciseConstType& RegTypeCache::PosShortConstant() { - ConstantType& result = FromCat1Const(std::numeric_limits<jshort>::max(), false); +const ImpreciseConstType& RegTypeCache::PosShortConstant() { + const ConstantType& result = FromCat1Const(std::numeric_limits<jshort>::max(), false); DCHECK(result.IsImpreciseConstant()); - return *down_cast<ImpreciseConstType*>(&result); + return *down_cast<const ImpreciseConstType*>(&result); } -UninitializedType& RegTypeCache::UninitializedThisArgument(RegType& type) { +const UninitializedType& RegTypeCache::UninitializedThisArgument(const RegType& type) { UninitializedType* entry; const std::string& descriptor(type.GetDescriptor()); if (type.IsUnresolvedTypes()) { @@ -502,10 +504,10 @@ UninitializedType& RegTypeCache::UninitializedThisArgument(RegType& type) { return *entry; } -ConstantType& RegTypeCache::FromCat1NonSmallConstant(int32_t value, bool precise) { +const ConstantType& RegTypeCache::FromCat1NonSmallConstant(int32_t value, bool precise) { for (size_t i = primitive_count_; i < entries_.size(); i++) { RegType* cur_entry = entries_[i]; - if (cur_entry->klass_.IsNull() && cur_entry->IsConstant() && + if (cur_entry->klass_ == NULL && cur_entry->IsConstant() && cur_entry->IsPreciseConstant() == precise && (down_cast<ConstantType*>(cur_entry))->ConstantValue() == value) { return *down_cast<ConstantType*>(cur_entry); @@ -521,7 +523,7 @@ ConstantType& RegTypeCache::FromCat1NonSmallConstant(int32_t value, bool precise return *entry; } -ConstantType& RegTypeCache::FromCat2ConstLo(int32_t value, bool precise) { +const ConstantType& RegTypeCache::FromCat2ConstLo(int32_t value, bool precise) { for (size_t i = primitive_count_; i < entries_.size(); i++) { RegType* cur_entry = entries_[i]; if (cur_entry->IsConstantLo() && (cur_entry->IsPrecise() == precise) && @@ -539,7 +541,7 @@ ConstantType& RegTypeCache::FromCat2ConstLo(int32_t value, bool precise) { return *entry; } -ConstantType& RegTypeCache::FromCat2ConstHi(int32_t value, bool precise) { +const ConstantType& RegTypeCache::FromCat2ConstHi(int32_t value, bool precise) { for (size_t i = primitive_count_; i < entries_.size(); i++) { RegType* cur_entry = entries_[i]; if (cur_entry->IsConstantHi() && (cur_entry->IsPrecise() == precise) && @@ -557,7 +559,7 @@ ConstantType& RegTypeCache::FromCat2ConstHi(int32_t value, bool precise) { return *entry; } -RegType& RegTypeCache::GetComponentType(RegType& array, mirror::ClassLoader* loader) { +const RegType& RegTypeCache::GetComponentType(const RegType& array, mirror::ClassLoader* loader) { if (!array.IsArrayTypes()) { return Conflict(); } else if (array.IsUnresolvedTypes()) { diff --git a/runtime/verifier/reg_type_cache.h b/runtime/verifier/reg_type_cache.h index c0427eb..8baf3ff 100644 --- a/runtime/verifier/reg_type_cache.h +++ b/runtime/verifier/reg_type_cache.h @@ -51,99 +51,99 @@ class RegTypeCache { } } static void ShutDown(); - RegType& GetFromId(uint16_t id) const; - RegType& From(mirror::ClassLoader* loader, const char* descriptor, bool precise) + const art::verifier::RegType& GetFromId(uint16_t id) const; + const RegType& From(mirror::ClassLoader* loader, const char* descriptor, bool precise) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - RegType& FromClass(const char* descriptor, mirror::Class* klass, bool precise) + const RegType& FromClass(const char* descriptor, mirror::Class* klass, bool precise) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - ConstantType& FromCat1Const(int32_t value, bool precise) + const ConstantType& FromCat1Const(int32_t value, bool precise) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - ConstantType& FromCat2ConstLo(int32_t value, bool precise) + const ConstantType& FromCat2ConstLo(int32_t value, bool precise) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - ConstantType& FromCat2ConstHi(int32_t value, bool precise) + const ConstantType& FromCat2ConstHi(int32_t value, bool precise) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - RegType& FromDescriptor(mirror::ClassLoader* loader, const char* descriptor, bool precise) + const RegType& FromDescriptor(mirror::ClassLoader* loader, const char* descriptor, bool precise) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - RegType& FromUnresolvedMerge(RegType& left, RegType& right) + const RegType& FromUnresolvedMerge(const RegType& left, const RegType& right) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - RegType& FromUnresolvedSuperClass(RegType& child) + const RegType& FromUnresolvedSuperClass(const RegType& child) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - RegType& JavaLangString() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { + const RegType& JavaLangString() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { // String is final and therefore always precise. return From(NULL, "Ljava/lang/String;", true); } - RegType& JavaLangThrowable(bool precise) + const RegType& JavaLangThrowable(bool precise) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { return From(NULL, "Ljava/lang/Throwable;", precise); } - ConstantType& Zero() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { + const ConstantType& Zero() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { return FromCat1Const(0, true); } - ConstantType& One() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { + const ConstantType& One() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { return FromCat1Const(1, true); } size_t GetCacheSize() { return entries_.size(); } - RegType& Boolean() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { + const RegType& Boolean() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { return *BooleanType::GetInstance(); } - RegType& Byte() { + const RegType& Byte() { return *ByteType::GetInstance(); } - RegType& Char() { + const RegType& Char() { return *CharType::GetInstance(); } - RegType& Short() { + const RegType& Short() { return *ShortType::GetInstance(); } - RegType& Integer() { + const RegType& Integer() { return *IntegerType::GetInstance(); } - RegType& Float() { + const RegType& Float() { return *FloatType::GetInstance(); } - RegType& LongLo() { + const RegType& LongLo() { return *LongLoType::GetInstance(); } - RegType& LongHi() { + const RegType& LongHi() { return *LongHiType::GetInstance(); } - RegType& DoubleLo() { + const RegType& DoubleLo() { return *DoubleLoType::GetInstance(); } - RegType& DoubleHi() { + const RegType& DoubleHi() { return *DoubleHiType::GetInstance(); } - RegType& Undefined() { + const RegType& Undefined() { return *UndefinedType::GetInstance(); } - RegType& Conflict() { + const RegType& Conflict() { return *ConflictType::GetInstance(); } - RegType& JavaLangClass(bool precise) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { + const RegType& JavaLangClass(bool precise) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { return From(NULL, "Ljava/lang/Class;", precise); } - RegType& JavaLangObject(bool precise) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { + const RegType& JavaLangObject(bool precise) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { return From(NULL, "Ljava/lang/Object;", precise); } - UninitializedType& Uninitialized(RegType& type, uint32_t allocation_pc) + const UninitializedType& Uninitialized(const RegType& type, uint32_t allocation_pc) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // Create an uninitialized 'this' argument for the given type. - UninitializedType& UninitializedThisArgument(RegType& type) + const UninitializedType& UninitializedThisArgument(const RegType& type) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - RegType& FromUninitialized(RegType& uninit_type) + const RegType& FromUninitialized(const RegType& uninit_type) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - ImpreciseConstType& ByteConstant() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - ImpreciseConstType& CharConstant() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - ImpreciseConstType& ShortConstant() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - ImpreciseConstType& IntConstant() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - ImpreciseConstType& PosByteConstant() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - ImpreciseConstType& PosShortConstant() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - RegType& GetComponentType(RegType& array, mirror::ClassLoader* loader) + const ImpreciseConstType& ByteConstant() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + const ImpreciseConstType& CharConstant() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + const ImpreciseConstType& ShortConstant() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + const ImpreciseConstType& IntConstant() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + const ImpreciseConstType& PosByteConstant() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + const ImpreciseConstType& PosShortConstant() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + const RegType& GetComponentType(const RegType& array, mirror::ClassLoader* loader) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); void Dump(std::ostream& os) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - RegType& RegTypeFromPrimitiveType(Primitive::Type) const; + const RegType& RegTypeFromPrimitiveType(Primitive::Type) const; void VisitRoots(RootCallback* callback, void* arg) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); @@ -153,7 +153,7 @@ class RegTypeCache { SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); bool MatchDescriptor(size_t idx, const StringPiece& descriptor, bool precise) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - ConstantType& FromCat1NonSmallConstant(int32_t value, bool precise) + const ConstantType& FromCat1NonSmallConstant(int32_t value, bool precise) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); void AddEntry(RegType* new_entry); diff --git a/runtime/verifier/reg_type_test.cc b/runtime/verifier/reg_type_test.cc index e27558a..9dc0df1 100644 --- a/runtime/verifier/reg_type_test.cc +++ b/runtime/verifier/reg_type_test.cc @@ -33,21 +33,21 @@ TEST_F(RegTypeTest, ConstLoHi) { // Tests creating primitive types types. ScopedObjectAccess soa(Thread::Current()); RegTypeCache cache(true); - RegType& ref_type_const_0 = cache.FromCat1Const(10, true); - RegType& ref_type_const_1 = cache.FromCat1Const(10, true); - RegType& ref_type_const_2 = cache.FromCat1Const(30, true); - RegType& ref_type_const_3 = cache.FromCat1Const(30, false); + const RegType& ref_type_const_0 = cache.FromCat1Const(10, true); + const RegType& ref_type_const_1 = cache.FromCat1Const(10, true); + const RegType& ref_type_const_2 = cache.FromCat1Const(30, true); + const RegType& ref_type_const_3 = cache.FromCat1Const(30, false); EXPECT_TRUE(ref_type_const_0.Equals(ref_type_const_1)); EXPECT_FALSE(ref_type_const_0.Equals(ref_type_const_2)); EXPECT_FALSE(ref_type_const_0.Equals(ref_type_const_3)); - RegType& ref_type_const_wide_0 = cache.FromCat2ConstHi(50, true); - RegType& ref_type_const_wide_1 = cache.FromCat2ConstHi(50, true); + const RegType& ref_type_const_wide_0 = cache.FromCat2ConstHi(50, true); + const RegType& ref_type_const_wide_1 = cache.FromCat2ConstHi(50, true); EXPECT_TRUE(ref_type_const_wide_0.Equals(ref_type_const_wide_1)); - RegType& ref_type_const_wide_2 = cache.FromCat2ConstLo(50, true); - RegType& ref_type_const_wide_3 = cache.FromCat2ConstLo(50, true); - RegType& ref_type_const_wide_4 = cache.FromCat2ConstLo(55, true); + const RegType& ref_type_const_wide_2 = cache.FromCat2ConstLo(50, true); + const RegType& ref_type_const_wide_3 = cache.FromCat2ConstLo(50, true); + const RegType& ref_type_const_wide_4 = cache.FromCat2ConstLo(55, true); EXPECT_TRUE(ref_type_const_wide_2.Equals(ref_type_const_wide_3)); EXPECT_FALSE(ref_type_const_wide_2.Equals(ref_type_const_wide_4)); } @@ -56,11 +56,11 @@ TEST_F(RegTypeTest, Pairs) { ScopedObjectAccess soa(Thread::Current()); RegTypeCache cache(true); int64_t val = static_cast<int32_t>(1234); - RegType& precise_lo = cache.FromCat2ConstLo(static_cast<int32_t>(val), true); - RegType& precise_hi = cache.FromCat2ConstHi(static_cast<int32_t>(val >> 32), true); - RegType& precise_const = cache.FromCat1Const(static_cast<int32_t>(val >> 32), true); - RegType& long_lo = cache.LongLo(); - RegType& long_hi = cache.LongHi(); + const RegType& precise_lo = cache.FromCat2ConstLo(static_cast<int32_t>(val), true); + const RegType& precise_hi = cache.FromCat2ConstHi(static_cast<int32_t>(val >> 32), true); + const RegType& precise_const = cache.FromCat1Const(static_cast<int32_t>(val >> 32), true); + const RegType& long_lo = cache.LongLo(); + const RegType& long_hi = cache.LongHi(); // Check sanity of types. EXPECT_TRUE(precise_lo.IsLowHalf()); EXPECT_FALSE(precise_hi.IsLowHalf()); @@ -80,7 +80,7 @@ TEST_F(RegTypeTest, Primitives) { ScopedObjectAccess soa(Thread::Current()); RegTypeCache cache(true); - RegType& bool_reg_type = cache.Boolean(); + const RegType& bool_reg_type = cache.Boolean(); EXPECT_FALSE(bool_reg_type.IsUndefined()); EXPECT_FALSE(bool_reg_type.IsConflict()); EXPECT_FALSE(bool_reg_type.IsZero()); @@ -112,7 +112,7 @@ TEST_F(RegTypeTest, Primitives) { EXPECT_TRUE(bool_reg_type.IsArrayIndexTypes()); EXPECT_FALSE(bool_reg_type.IsNonZeroReferenceTypes()); - RegType& byte_reg_type = cache.Byte(); + const RegType& byte_reg_type = cache.Byte(); EXPECT_FALSE(byte_reg_type.IsUndefined()); EXPECT_FALSE(byte_reg_type.IsConflict()); EXPECT_FALSE(byte_reg_type.IsZero()); @@ -144,7 +144,7 @@ TEST_F(RegTypeTest, Primitives) { EXPECT_TRUE(byte_reg_type.IsArrayIndexTypes()); EXPECT_FALSE(byte_reg_type.IsNonZeroReferenceTypes()); - RegType& char_reg_type = cache.Char(); + const RegType& char_reg_type = cache.Char(); EXPECT_FALSE(char_reg_type.IsUndefined()); EXPECT_FALSE(char_reg_type.IsConflict()); EXPECT_FALSE(char_reg_type.IsZero()); @@ -176,7 +176,7 @@ TEST_F(RegTypeTest, Primitives) { EXPECT_TRUE(char_reg_type.IsArrayIndexTypes()); EXPECT_FALSE(char_reg_type.IsNonZeroReferenceTypes()); - RegType& short_reg_type = cache.Short(); + const RegType& short_reg_type = cache.Short(); EXPECT_FALSE(short_reg_type.IsUndefined()); EXPECT_FALSE(short_reg_type.IsConflict()); EXPECT_FALSE(short_reg_type.IsZero()); @@ -208,7 +208,7 @@ TEST_F(RegTypeTest, Primitives) { EXPECT_TRUE(short_reg_type.IsArrayIndexTypes()); EXPECT_FALSE(short_reg_type.IsNonZeroReferenceTypes()); - RegType& int_reg_type = cache.Integer(); + const RegType& int_reg_type = cache.Integer(); EXPECT_FALSE(int_reg_type.IsUndefined()); EXPECT_FALSE(int_reg_type.IsConflict()); EXPECT_FALSE(int_reg_type.IsZero()); @@ -240,7 +240,7 @@ TEST_F(RegTypeTest, Primitives) { EXPECT_TRUE(int_reg_type.IsArrayIndexTypes()); EXPECT_FALSE(int_reg_type.IsNonZeroReferenceTypes()); - RegType& long_reg_type = cache.LongLo(); + const RegType& long_reg_type = cache.LongLo(); EXPECT_FALSE(long_reg_type.IsUndefined()); EXPECT_FALSE(long_reg_type.IsConflict()); EXPECT_FALSE(long_reg_type.IsZero()); @@ -272,7 +272,7 @@ TEST_F(RegTypeTest, Primitives) { EXPECT_FALSE(long_reg_type.IsArrayIndexTypes()); EXPECT_FALSE(long_reg_type.IsNonZeroReferenceTypes()); - RegType& float_reg_type = cache.Float(); + const RegType& float_reg_type = cache.Float(); EXPECT_FALSE(float_reg_type.IsUndefined()); EXPECT_FALSE(float_reg_type.IsConflict()); EXPECT_FALSE(float_reg_type.IsZero()); @@ -304,7 +304,7 @@ TEST_F(RegTypeTest, Primitives) { EXPECT_FALSE(float_reg_type.IsArrayIndexTypes()); EXPECT_FALSE(float_reg_type.IsNonZeroReferenceTypes()); - RegType& double_reg_type = cache.DoubleLo(); + const RegType& double_reg_type = cache.DoubleLo(); EXPECT_FALSE(double_reg_type.IsUndefined()); EXPECT_FALSE(double_reg_type.IsConflict()); EXPECT_FALSE(double_reg_type.IsZero()); @@ -344,9 +344,9 @@ TEST_F(RegTypeReferenceTest, JavalangObjectImprecise) { // match the one that is imprecise. ScopedObjectAccess soa(Thread::Current()); RegTypeCache cache(true); - RegType& imprecise_obj = cache.JavaLangObject(false); - RegType& precise_obj = cache.JavaLangObject(true); - RegType& precise_obj_2 = cache.FromDescriptor(NULL, "Ljava/lang/Object;", true); + const RegType& imprecise_obj = cache.JavaLangObject(false); + const RegType& precise_obj = cache.JavaLangObject(true); + const RegType& precise_obj_2 = cache.FromDescriptor(NULL, "Ljava/lang/Object;", true); EXPECT_TRUE(precise_obj.Equals(precise_obj_2)); EXPECT_FALSE(imprecise_obj.Equals(precise_obj)); @@ -359,14 +359,14 @@ TEST_F(RegTypeReferenceTest, UnresolvedType) { // a hit second time. ScopedObjectAccess soa(Thread::Current()); RegTypeCache cache(true); - RegType& ref_type_0 = cache.FromDescriptor(NULL, "Ljava/lang/DoesNotExist;", true); + const RegType& ref_type_0 = cache.FromDescriptor(NULL, "Ljava/lang/DoesNotExist;", true); EXPECT_TRUE(ref_type_0.IsUnresolvedReference()); EXPECT_TRUE(ref_type_0.IsNonZeroReferenceTypes()); - RegType& ref_type_1 = cache.FromDescriptor(NULL, "Ljava/lang/DoesNotExist;", true); + const RegType& ref_type_1 = cache.FromDescriptor(NULL, "Ljava/lang/DoesNotExist;", true); EXPECT_TRUE(ref_type_0.Equals(ref_type_1)); - RegType& unresolved_super_class = cache.FromUnresolvedSuperClass(ref_type_0); + const RegType& unresolved_super_class = cache.FromUnresolvedSuperClass(ref_type_0); EXPECT_TRUE(unresolved_super_class.IsUnresolvedSuperClass()); EXPECT_TRUE(unresolved_super_class.IsNonZeroReferenceTypes()); } @@ -375,21 +375,21 @@ TEST_F(RegTypeReferenceTest, UnresolvedUnintializedType) { // Tests creating types uninitialized types from unresolved types. ScopedObjectAccess soa(Thread::Current()); RegTypeCache cache(true); - RegType& ref_type_0 = cache.FromDescriptor(NULL, "Ljava/lang/DoesNotExist;", true); + const RegType& ref_type_0 = cache.FromDescriptor(NULL, "Ljava/lang/DoesNotExist;", true); EXPECT_TRUE(ref_type_0.IsUnresolvedReference()); - RegType& ref_type = cache.FromDescriptor(NULL, "Ljava/lang/DoesNotExist;", true); + const RegType& ref_type = cache.FromDescriptor(NULL, "Ljava/lang/DoesNotExist;", true); EXPECT_TRUE(ref_type_0.Equals(ref_type)); // Create an uninitialized type of this unresolved type - RegType& unresolved_unintialised = cache.Uninitialized(ref_type, 1101ull); + const RegType& unresolved_unintialised = cache.Uninitialized(ref_type, 1101ull); EXPECT_TRUE(unresolved_unintialised.IsUnresolvedAndUninitializedReference()); EXPECT_TRUE(unresolved_unintialised.IsUninitializedTypes()); EXPECT_TRUE(unresolved_unintialised.IsNonZeroReferenceTypes()); // Create an uninitialized type of this unresolved type with different PC - RegType& ref_type_unresolved_unintialised_1 = cache.Uninitialized(ref_type, 1102ull); + const RegType& ref_type_unresolved_unintialised_1 = cache.Uninitialized(ref_type, 1102ull); EXPECT_TRUE(unresolved_unintialised.IsUnresolvedAndUninitializedReference()); EXPECT_FALSE(unresolved_unintialised.Equals(ref_type_unresolved_unintialised_1)); // Create an uninitialized type of this unresolved type with the same PC - RegType& unresolved_unintialised_2 = cache.Uninitialized(ref_type, 1101ull); + const RegType& unresolved_unintialised_2 = cache.Uninitialized(ref_type, 1101ull); EXPECT_TRUE(unresolved_unintialised.Equals(unresolved_unintialised_2)); } @@ -397,12 +397,12 @@ TEST_F(RegTypeReferenceTest, Dump) { // Tests types for proper Dump messages. ScopedObjectAccess soa(Thread::Current()); RegTypeCache cache(true); - RegType& unresolved_ref = cache.FromDescriptor(NULL, "Ljava/lang/DoesNotExist;", true); - RegType& unresolved_ref_another = cache.FromDescriptor(NULL, "Ljava/lang/DoesNotExistEither;", true); - RegType& resolved_ref = cache.JavaLangString(); - RegType& resolved_unintialiesd = cache.Uninitialized(resolved_ref, 10); - RegType& unresolved_unintialized = cache.Uninitialized(unresolved_ref, 12); - RegType& unresolved_merged = cache.FromUnresolvedMerge(unresolved_ref, unresolved_ref_another); + const RegType& unresolved_ref = cache.FromDescriptor(NULL, "Ljava/lang/DoesNotExist;", true); + const RegType& unresolved_ref_another = cache.FromDescriptor(NULL, "Ljava/lang/DoesNotExistEither;", true); + const RegType& resolved_ref = cache.JavaLangString(); + const RegType& resolved_unintialiesd = cache.Uninitialized(resolved_ref, 10); + const RegType& unresolved_unintialized = cache.Uninitialized(unresolved_ref, 12); + const RegType& unresolved_merged = cache.FromUnresolvedMerge(unresolved_ref, unresolved_ref_another); std::string expected = "Unresolved Reference: java.lang.DoesNotExist"; EXPECT_EQ(expected, unresolved_ref.Dump()); @@ -422,16 +422,16 @@ TEST_F(RegTypeReferenceTest, JavalangString) { // The JavaLangObject method instead of FromDescriptor. String class is final. ScopedObjectAccess soa(Thread::Current()); RegTypeCache cache(true); - RegType& ref_type = cache.JavaLangString(); - RegType& ref_type_2 = cache.JavaLangString(); - RegType& ref_type_3 = cache.FromDescriptor(NULL, "Ljava/lang/String;", true); + const RegType& ref_type = cache.JavaLangString(); + const RegType& ref_type_2 = cache.JavaLangString(); + const RegType& ref_type_3 = cache.FromDescriptor(NULL, "Ljava/lang/String;", true); EXPECT_TRUE(ref_type.Equals(ref_type_2)); EXPECT_TRUE(ref_type_2.Equals(ref_type_3)); EXPECT_TRUE(ref_type.IsPreciseReference()); // Create an uninitialized type out of this: - RegType& ref_type_unintialized = cache.Uninitialized(ref_type, 0110ull); + const RegType& ref_type_unintialized = cache.Uninitialized(ref_type, 0110ull); EXPECT_TRUE(ref_type_unintialized.IsUninitializedReference()); EXPECT_FALSE(ref_type_unintialized.IsUnresolvedAndUninitializedReference()); } @@ -442,9 +442,9 @@ TEST_F(RegTypeReferenceTest, JavalangObject) { // The JavaLangObject method instead of FromDescriptor. Object Class in not final. ScopedObjectAccess soa(Thread::Current()); RegTypeCache cache(true); - RegType& ref_type = cache.JavaLangObject(true); - RegType& ref_type_2 = cache.JavaLangObject(true); - RegType& ref_type_3 = cache.FromDescriptor(NULL, "Ljava/lang/Object;", true); + const RegType& ref_type = cache.JavaLangObject(true); + const RegType& ref_type_2 = cache.JavaLangObject(true); + const RegType& ref_type_3 = cache.FromDescriptor(NULL, "Ljava/lang/Object;", true); EXPECT_TRUE(ref_type.Equals(ref_type_2)); EXPECT_TRUE(ref_type_3.Equals(ref_type_2)); @@ -455,19 +455,20 @@ TEST_F(RegTypeReferenceTest, Merging) { // String and object , LUB is object. ScopedObjectAccess soa(Thread::Current()); RegTypeCache cache_new(true); - RegType& string = cache_new.JavaLangString(); - RegType& Object = cache_new.JavaLangObject(true); + const RegType& string = cache_new.JavaLangString(); + const RegType& Object = cache_new.JavaLangObject(true); EXPECT_TRUE(string.Merge(Object, &cache_new).IsJavaLangObject()); // Merge two unresolved types. - RegType& ref_type_0 = cache_new.FromDescriptor(NULL, "Ljava/lang/DoesNotExist;", true); + const RegType& ref_type_0 = cache_new.FromDescriptor(NULL, "Ljava/lang/DoesNotExist;", true); EXPECT_TRUE(ref_type_0.IsUnresolvedReference()); - RegType& ref_type_1 = cache_new.FromDescriptor(NULL, "Ljava/lang/DoesNotExistToo;", true); + const RegType& ref_type_1 = cache_new.FromDescriptor(NULL, "Ljava/lang/DoesNotExistToo;", true); EXPECT_FALSE(ref_type_0.Equals(ref_type_1)); - RegType& merged = ref_type_1.Merge(ref_type_0, &cache_new); + const RegType& merged = ref_type_1.Merge(ref_type_0, &cache_new); EXPECT_TRUE(merged.IsUnresolvedMergedReference()); + RegType& merged_nonconst = const_cast<RegType&>(merged); - std::set<uint16_t> merged_ids = (down_cast<UnresolvedMergedType*>(&merged))->GetMergedTypes(); + std::set<uint16_t> merged_ids = (down_cast<UnresolvedMergedType*>(&merged_nonconst))->GetMergedTypes(); EXPECT_EQ(ref_type_0.GetId(), *(merged_ids.begin())); EXPECT_EQ(ref_type_1.GetId(), *((++merged_ids.begin()))); } @@ -478,27 +479,27 @@ TEST_F(RegTypeTest, MergingFloat) { RegTypeCache cache_new(true); constexpr int32_t kTestConstantValue = 10; - RegType& float_type = cache_new.Float(); - RegType& precise_cst = cache_new.FromCat1Const(kTestConstantValue, true); - RegType& imprecise_cst = cache_new.FromCat1Const(kTestConstantValue, false); + const RegType& float_type = cache_new.Float(); + const RegType& precise_cst = cache_new.FromCat1Const(kTestConstantValue, true); + const RegType& imprecise_cst = cache_new.FromCat1Const(kTestConstantValue, false); { // float MERGE precise cst => float. - RegType& merged = float_type.Merge(precise_cst, &cache_new); + const RegType& merged = float_type.Merge(precise_cst, &cache_new); EXPECT_TRUE(merged.IsFloat()); } { // precise cst MERGE float => float. - RegType& merged = precise_cst.Merge(float_type, &cache_new); + const RegType& merged = precise_cst.Merge(float_type, &cache_new); EXPECT_TRUE(merged.IsFloat()); } { // float MERGE imprecise cst => float. - RegType& merged = float_type.Merge(imprecise_cst, &cache_new); + const RegType& merged = float_type.Merge(imprecise_cst, &cache_new); EXPECT_TRUE(merged.IsFloat()); } { // imprecise cst MERGE float => float. - RegType& merged = imprecise_cst.Merge(float_type, &cache_new); + const RegType& merged = imprecise_cst.Merge(float_type, &cache_new); EXPECT_TRUE(merged.IsFloat()); } } @@ -509,50 +510,50 @@ TEST_F(RegTypeTest, MergingLong) { RegTypeCache cache_new(true); constexpr int32_t kTestConstantValue = 10; - RegType& long_lo_type = cache_new.LongLo(); - RegType& long_hi_type = cache_new.LongHi(); - RegType& precise_cst_lo = cache_new.FromCat2ConstLo(kTestConstantValue, true); - RegType& imprecise_cst_lo = cache_new.FromCat2ConstLo(kTestConstantValue, false); - RegType& precise_cst_hi = cache_new.FromCat2ConstHi(kTestConstantValue, true); - RegType& imprecise_cst_hi = cache_new.FromCat2ConstHi(kTestConstantValue, false); + const RegType& long_lo_type = cache_new.LongLo(); + const RegType& long_hi_type = cache_new.LongHi(); + const RegType& precise_cst_lo = cache_new.FromCat2ConstLo(kTestConstantValue, true); + const RegType& imprecise_cst_lo = cache_new.FromCat2ConstLo(kTestConstantValue, false); + const RegType& precise_cst_hi = cache_new.FromCat2ConstHi(kTestConstantValue, true); + const RegType& imprecise_cst_hi = cache_new.FromCat2ConstHi(kTestConstantValue, false); { // lo MERGE precise cst lo => lo. - RegType& merged = long_lo_type.Merge(precise_cst_lo, &cache_new); + const RegType& merged = long_lo_type.Merge(precise_cst_lo, &cache_new); EXPECT_TRUE(merged.IsLongLo()); } { // precise cst lo MERGE lo => lo. - RegType& merged = precise_cst_lo.Merge(long_lo_type, &cache_new); + const RegType& merged = precise_cst_lo.Merge(long_lo_type, &cache_new); EXPECT_TRUE(merged.IsLongLo()); } { // lo MERGE imprecise cst lo => lo. - RegType& merged = long_lo_type.Merge(imprecise_cst_lo, &cache_new); + const RegType& merged = long_lo_type.Merge(imprecise_cst_lo, &cache_new); EXPECT_TRUE(merged.IsLongLo()); } { // imprecise cst lo MERGE lo => lo. - RegType& merged = imprecise_cst_lo.Merge(long_lo_type, &cache_new); + const RegType& merged = imprecise_cst_lo.Merge(long_lo_type, &cache_new); EXPECT_TRUE(merged.IsLongLo()); } { // hi MERGE precise cst hi => hi. - RegType& merged = long_hi_type.Merge(precise_cst_hi, &cache_new); + const RegType& merged = long_hi_type.Merge(precise_cst_hi, &cache_new); EXPECT_TRUE(merged.IsLongHi()); } { // precise cst hi MERGE hi => hi. - RegType& merged = precise_cst_hi.Merge(long_hi_type, &cache_new); + const RegType& merged = precise_cst_hi.Merge(long_hi_type, &cache_new); EXPECT_TRUE(merged.IsLongHi()); } { // hi MERGE imprecise cst hi => hi. - RegType& merged = long_hi_type.Merge(imprecise_cst_hi, &cache_new); + const RegType& merged = long_hi_type.Merge(imprecise_cst_hi, &cache_new); EXPECT_TRUE(merged.IsLongHi()); } { // imprecise cst hi MERGE hi => hi. - RegType& merged = imprecise_cst_hi.Merge(long_hi_type, &cache_new); + const RegType& merged = imprecise_cst_hi.Merge(long_hi_type, &cache_new); EXPECT_TRUE(merged.IsLongHi()); } } @@ -563,50 +564,50 @@ TEST_F(RegTypeTest, MergingDouble) { RegTypeCache cache_new(true); constexpr int32_t kTestConstantValue = 10; - RegType& double_lo_type = cache_new.DoubleLo(); - RegType& double_hi_type = cache_new.DoubleHi(); - RegType& precise_cst_lo = cache_new.FromCat2ConstLo(kTestConstantValue, true); - RegType& imprecise_cst_lo = cache_new.FromCat2ConstLo(kTestConstantValue, false); - RegType& precise_cst_hi = cache_new.FromCat2ConstHi(kTestConstantValue, true); - RegType& imprecise_cst_hi = cache_new.FromCat2ConstHi(kTestConstantValue, false); + const RegType& double_lo_type = cache_new.DoubleLo(); + const RegType& double_hi_type = cache_new.DoubleHi(); + const RegType& precise_cst_lo = cache_new.FromCat2ConstLo(kTestConstantValue, true); + const RegType& imprecise_cst_lo = cache_new.FromCat2ConstLo(kTestConstantValue, false); + const RegType& precise_cst_hi = cache_new.FromCat2ConstHi(kTestConstantValue, true); + const RegType& imprecise_cst_hi = cache_new.FromCat2ConstHi(kTestConstantValue, false); { // lo MERGE precise cst lo => lo. - RegType& merged = double_lo_type.Merge(precise_cst_lo, &cache_new); + const RegType& merged = double_lo_type.Merge(precise_cst_lo, &cache_new); EXPECT_TRUE(merged.IsDoubleLo()); } { // precise cst lo MERGE lo => lo. - RegType& merged = precise_cst_lo.Merge(double_lo_type, &cache_new); + const RegType& merged = precise_cst_lo.Merge(double_lo_type, &cache_new); EXPECT_TRUE(merged.IsDoubleLo()); } { // lo MERGE imprecise cst lo => lo. - RegType& merged = double_lo_type.Merge(imprecise_cst_lo, &cache_new); + const RegType& merged = double_lo_type.Merge(imprecise_cst_lo, &cache_new); EXPECT_TRUE(merged.IsDoubleLo()); } { // imprecise cst lo MERGE lo => lo. - RegType& merged = imprecise_cst_lo.Merge(double_lo_type, &cache_new); + const RegType& merged = imprecise_cst_lo.Merge(double_lo_type, &cache_new); EXPECT_TRUE(merged.IsDoubleLo()); } { // hi MERGE precise cst hi => hi. - RegType& merged = double_hi_type.Merge(precise_cst_hi, &cache_new); + const RegType& merged = double_hi_type.Merge(precise_cst_hi, &cache_new); EXPECT_TRUE(merged.IsDoubleHi()); } { // precise cst hi MERGE hi => hi. - RegType& merged = precise_cst_hi.Merge(double_hi_type, &cache_new); + const RegType& merged = precise_cst_hi.Merge(double_hi_type, &cache_new); EXPECT_TRUE(merged.IsDoubleHi()); } { // hi MERGE imprecise cst hi => hi. - RegType& merged = double_hi_type.Merge(imprecise_cst_hi, &cache_new); + const RegType& merged = double_hi_type.Merge(imprecise_cst_hi, &cache_new); EXPECT_TRUE(merged.IsDoubleHi()); } { // imprecise cst hi MERGE hi => hi. - RegType& merged = imprecise_cst_hi.Merge(double_hi_type, &cache_new); + const RegType& merged = imprecise_cst_hi.Merge(double_hi_type, &cache_new); EXPECT_TRUE(merged.IsDoubleHi()); } } @@ -615,8 +616,8 @@ TEST_F(RegTypeTest, ConstPrecision) { // Tests creating primitive types types. ScopedObjectAccess soa(Thread::Current()); RegTypeCache cache_new(true); - RegType& imprecise_const = cache_new.FromCat1Const(10, false); - RegType& precise_const = cache_new.FromCat1Const(10, true); + const RegType& imprecise_const = cache_new.FromCat1Const(10, false); + const RegType& precise_const = cache_new.FromCat1Const(10, true); EXPECT_TRUE(imprecise_const.IsImpreciseConstant()); EXPECT_TRUE(precise_const.IsPreciseConstant()); diff --git a/runtime/verifier/register_line-inl.h b/runtime/verifier/register_line-inl.h index 378c6d3..0989cd0 100644 --- a/runtime/verifier/register_line-inl.h +++ b/runtime/verifier/register_line-inl.h @@ -25,7 +25,7 @@ namespace art { namespace verifier { -inline RegType& RegisterLine::GetRegisterType(uint32_t vsrc) const { +inline const RegType& RegisterLine::GetRegisterType(uint32_t vsrc) const { // The register index was validated during the static pass, so we don't need to check it here. DCHECK_LT(vsrc, num_regs_); return verifier_->GetRegTypeCache()->GetFromId(line_[vsrc]); diff --git a/runtime/verifier/register_line.cc b/runtime/verifier/register_line.cc index 4d67cfb..556056c 100644 --- a/runtime/verifier/register_line.cc +++ b/runtime/verifier/register_line.cc @@ -36,7 +36,7 @@ bool RegisterLine::CheckConstructorReturn() const { return true; } -bool RegisterLine::SetRegisterType(uint32_t vdst, RegType& new_type) { +bool RegisterLine::SetRegisterType(uint32_t vdst, const RegType& new_type) { DCHECK_LT(vdst, num_regs_); if (new_type.IsLowHalf() || new_type.IsHighHalf()) { verifier_->Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Expected category1 register type not '" @@ -53,8 +53,8 @@ bool RegisterLine::SetRegisterType(uint32_t vdst, RegType& new_type) { return true; } -bool RegisterLine::SetRegisterTypeWide(uint32_t vdst, RegType& new_type1, - RegType& new_type2) { +bool RegisterLine::SetRegisterTypeWide(uint32_t vdst, const RegType& new_type1, + const RegType& new_type2) { DCHECK_LT(vdst + 1, num_regs_); if (!new_type1.CheckWidePair(new_type2)) { verifier_->Fail(VERIFY_ERROR_BAD_CLASS_SOFT) << "Invalid wide pair '" @@ -75,21 +75,21 @@ void RegisterLine::SetResultTypeToUnknown() { result_[1] = result_[0]; } -void RegisterLine::SetResultRegisterType(RegType& new_type) { +void RegisterLine::SetResultRegisterType(const RegType& new_type) { DCHECK(!new_type.IsLowHalf()); DCHECK(!new_type.IsHighHalf()); result_[0] = new_type.GetId(); result_[1] = verifier_->GetRegTypeCache()->Undefined().GetId(); } -void RegisterLine::SetResultRegisterTypeWide(RegType& new_type1, - RegType& new_type2) { +void RegisterLine::SetResultRegisterTypeWide(const RegType& new_type1, + const RegType& new_type2) { DCHECK(new_type1.CheckWidePair(new_type2)); result_[0] = new_type1.GetId(); result_[1] = new_type2.GetId(); } -RegType& RegisterLine::GetInvocationThis(const Instruction* inst, bool is_range) { +const RegType& RegisterLine::GetInvocationThis(const Instruction* inst, bool is_range) { const size_t args_count = is_range ? inst->VRegA_3rc() : inst->VRegA_35c(); if (args_count < 1) { verifier_->Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invoke lacks 'this'"; @@ -97,7 +97,7 @@ RegType& RegisterLine::GetInvocationThis(const Instruction* inst, bool is_range) } /* Get the element type of the array held in vsrc */ const uint32_t this_reg = (is_range) ? inst->VRegC_3rc() : inst->VRegC_35c(); - RegType& this_type = GetRegisterType(this_reg); + const RegType& this_type = GetRegisterType(this_reg); if (!this_type.IsReferenceTypes()) { verifier_->Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "tried to get class from non-reference register v" << this_reg << " (type=" << this_type << ")"; @@ -107,9 +107,9 @@ RegType& RegisterLine::GetInvocationThis(const Instruction* inst, bool is_range) } bool RegisterLine::VerifyRegisterType(uint32_t vsrc, - RegType& check_type) { + const RegType& check_type) { // Verify the src register type against the check type refining the type of the register - RegType& src_type = GetRegisterType(vsrc); + const RegType& src_type = GetRegisterType(vsrc); if (!(check_type.IsAssignableFrom(src_type))) { enum VerifyError fail_type; if (!check_type.IsNonZeroReferenceTypes() || !src_type.IsNonZeroReferenceTypes()) { @@ -125,7 +125,7 @@ bool RegisterLine::VerifyRegisterType(uint32_t vsrc, return false; } if (check_type.IsLowHalf()) { - RegType& src_type_h = GetRegisterType(vsrc + 1); + const RegType& src_type_h = GetRegisterType(vsrc + 1); if (!src_type.CheckWidePair(src_type_h)) { verifier_->Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "wide register v" << vsrc << " has type " << src_type << "/" << src_type_h; @@ -139,17 +139,17 @@ bool RegisterLine::VerifyRegisterType(uint32_t vsrc, return true; } -bool RegisterLine::VerifyRegisterTypeWide(uint32_t vsrc, RegType& check_type1, - RegType& check_type2) { +bool RegisterLine::VerifyRegisterTypeWide(uint32_t vsrc, const RegType& check_type1, + const RegType& check_type2) { DCHECK(check_type1.CheckWidePair(check_type2)); // Verify the src register type against the check type refining the type of the register - RegType& src_type = GetRegisterType(vsrc); + const RegType& src_type = GetRegisterType(vsrc); if (!check_type1.IsAssignableFrom(src_type)) { verifier_->Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "register v" << vsrc << " has type " << src_type << " but expected " << check_type1; return false; } - RegType& src_type_h = GetRegisterType(vsrc + 1); + const RegType& src_type_h = GetRegisterType(vsrc + 1); if (!src_type.CheckWidePair(src_type_h)) { verifier_->Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "wide register v" << vsrc << " has type " << src_type << "/" << src_type_h; @@ -162,9 +162,9 @@ bool RegisterLine::VerifyRegisterTypeWide(uint32_t vsrc, RegType& check_type1, return true; } -void RegisterLine::MarkRefsAsInitialized(RegType& uninit_type) { +void RegisterLine::MarkRefsAsInitialized(const RegType& uninit_type) { DCHECK(uninit_type.IsUninitializedTypes()); - RegType& init_type = verifier_->GetRegTypeCache()->FromUninitialized(uninit_type); + const RegType& init_type = verifier_->GetRegTypeCache()->FromUninitialized(uninit_type); size_t changed = 0; for (uint32_t i = 0; i < num_regs_; i++) { if (GetRegisterType(i).Equals(uninit_type)) { @@ -200,7 +200,7 @@ void RegisterLine::MarkAllRegistersAsConflictsExceptWide(uint32_t vsrc) { } } -std::string RegisterLine::Dump() { +std::string RegisterLine::Dump() const { std::string result; for (size_t i = 0; i < num_regs_; i++) { result += StringPrintf("%zd:[", i); @@ -213,7 +213,7 @@ std::string RegisterLine::Dump() { return result; } -void RegisterLine::MarkUninitRefsAsInvalid(RegType& uninit_type) { +void RegisterLine::MarkUninitRefsAsInvalid(const RegType& uninit_type) { for (size_t i = 0; i < num_regs_; i++) { if (GetRegisterType(i).Equals(uninit_type)) { line_[i] = verifier_->GetRegTypeCache()->Conflict().GetId(); @@ -224,7 +224,7 @@ void RegisterLine::MarkUninitRefsAsInvalid(RegType& uninit_type) { void RegisterLine::CopyRegister1(uint32_t vdst, uint32_t vsrc, TypeCategory cat) { DCHECK(cat == kTypeCategory1nr || cat == kTypeCategoryRef); - RegType& type = GetRegisterType(vsrc); + const RegType& type = GetRegisterType(vsrc); if (!SetRegisterType(vdst, type)) { return; } @@ -238,8 +238,8 @@ void RegisterLine::CopyRegister1(uint32_t vdst, uint32_t vsrc, TypeCategory cat) } void RegisterLine::CopyRegister2(uint32_t vdst, uint32_t vsrc) { - RegType& type_l = GetRegisterType(vsrc); - RegType& type_h = GetRegisterType(vsrc + 1); + const RegType& type_l = GetRegisterType(vsrc); + const RegType& type_h = GetRegisterType(vsrc + 1); if (!type_l.CheckWidePair(type_h)) { verifier_->Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "copy2 v" << vdst << "<-v" << vsrc @@ -250,7 +250,7 @@ void RegisterLine::CopyRegister2(uint32_t vdst, uint32_t vsrc) { } void RegisterLine::CopyResultRegister1(uint32_t vdst, bool is_reference) { - RegType& type = verifier_->GetRegTypeCache()->GetFromId(result_[0]); + const RegType& type = verifier_->GetRegTypeCache()->GetFromId(result_[0]); if ((!is_reference && !type.IsCategory1Types()) || (is_reference && !type.IsReferenceTypes())) { verifier_->Fail(VERIFY_ERROR_BAD_CLASS_HARD) @@ -267,8 +267,8 @@ void RegisterLine::CopyResultRegister1(uint32_t vdst, bool is_reference) { * register to another register, and reset the result register. */ void RegisterLine::CopyResultRegister2(uint32_t vdst) { - RegType& type_l = verifier_->GetRegTypeCache()->GetFromId(result_[0]); - RegType& type_h = verifier_->GetRegTypeCache()->GetFromId(result_[1]); + const RegType& type_l = verifier_->GetRegTypeCache()->GetFromId(result_[0]); + const RegType& type_h = verifier_->GetRegTypeCache()->GetFromId(result_[1]); if (!type_l.IsCategory2Types()) { verifier_->Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "copyRes2 v" << vdst << "<- result0" << " type=" << type_l; @@ -281,40 +281,40 @@ void RegisterLine::CopyResultRegister2(uint32_t vdst) { } void RegisterLine::CheckUnaryOp(const Instruction* inst, - RegType& dst_type, - RegType& src_type) { + const RegType& dst_type, + const RegType& src_type) { if (VerifyRegisterType(inst->VRegB_12x(), src_type)) { SetRegisterType(inst->VRegA_12x(), dst_type); } } void RegisterLine::CheckUnaryOpWide(const Instruction* inst, - RegType& dst_type1, RegType& dst_type2, - RegType& src_type1, RegType& src_type2) { + const RegType& dst_type1, const RegType& dst_type2, + const RegType& src_type1, const RegType& src_type2) { if (VerifyRegisterTypeWide(inst->VRegB_12x(), src_type1, src_type2)) { SetRegisterTypeWide(inst->VRegA_12x(), dst_type1, dst_type2); } } void RegisterLine::CheckUnaryOpToWide(const Instruction* inst, - RegType& dst_type1, RegType& dst_type2, - RegType& src_type) { + const RegType& dst_type1, const RegType& dst_type2, + const RegType& src_type) { if (VerifyRegisterType(inst->VRegB_12x(), src_type)) { SetRegisterTypeWide(inst->VRegA_12x(), dst_type1, dst_type2); } } void RegisterLine::CheckUnaryOpFromWide(const Instruction* inst, - RegType& dst_type, - RegType& src_type1, RegType& src_type2) { + const RegType& dst_type, + const RegType& src_type1, const RegType& src_type2) { if (VerifyRegisterTypeWide(inst->VRegB_12x(), src_type1, src_type2)) { SetRegisterType(inst->VRegA_12x(), dst_type); } } void RegisterLine::CheckBinaryOp(const Instruction* inst, - RegType& dst_type, - RegType& src_type1, RegType& src_type2, + const RegType& dst_type, + const RegType& src_type1, const RegType& src_type2, bool check_boolean_op) { const uint32_t vregB = inst->VRegB_23x(); const uint32_t vregC = inst->VRegC_23x(); @@ -333,9 +333,9 @@ void RegisterLine::CheckBinaryOp(const Instruction* inst, } void RegisterLine::CheckBinaryOpWide(const Instruction* inst, - RegType& dst_type1, RegType& dst_type2, - RegType& src_type1_1, RegType& src_type1_2, - RegType& src_type2_1, RegType& src_type2_2) { + const RegType& dst_type1, const RegType& dst_type2, + const RegType& src_type1_1, const RegType& src_type1_2, + const RegType& src_type2_1, const RegType& src_type2_2) { if (VerifyRegisterTypeWide(inst->VRegB_23x(), src_type1_1, src_type1_2) && VerifyRegisterTypeWide(inst->VRegC_23x(), src_type2_1, src_type2_2)) { SetRegisterTypeWide(inst->VRegA_23x(), dst_type1, dst_type2); @@ -343,8 +343,8 @@ void RegisterLine::CheckBinaryOpWide(const Instruction* inst, } void RegisterLine::CheckBinaryOpWideShift(const Instruction* inst, - RegType& long_lo_type, RegType& long_hi_type, - RegType& int_type) { + const RegType& long_lo_type, const RegType& long_hi_type, + const RegType& int_type) { if (VerifyRegisterTypeWide(inst->VRegB_23x(), long_lo_type, long_hi_type) && VerifyRegisterType(inst->VRegC_23x(), int_type)) { SetRegisterTypeWide(inst->VRegA_23x(), long_lo_type, long_hi_type); @@ -352,8 +352,8 @@ void RegisterLine::CheckBinaryOpWideShift(const Instruction* inst, } void RegisterLine::CheckBinaryOp2addr(const Instruction* inst, - RegType& dst_type, RegType& src_type1, - RegType& src_type2, bool check_boolean_op) { + const RegType& dst_type, const RegType& src_type1, + const RegType& src_type2, bool check_boolean_op) { const uint32_t vregA = inst->VRegA_12x(); const uint32_t vregB = inst->VRegB_12x(); if (VerifyRegisterType(vregA, src_type1) && @@ -371,9 +371,9 @@ void RegisterLine::CheckBinaryOp2addr(const Instruction* inst, } void RegisterLine::CheckBinaryOp2addrWide(const Instruction* inst, - RegType& dst_type1, RegType& dst_type2, - RegType& src_type1_1, RegType& src_type1_2, - RegType& src_type2_1, RegType& src_type2_2) { + const RegType& dst_type1, const RegType& dst_type2, + const RegType& src_type1_1, const RegType& src_type1_2, + const RegType& src_type2_1, const RegType& src_type2_2) { const uint32_t vregA = inst->VRegA_12x(); const uint32_t vregB = inst->VRegB_12x(); if (VerifyRegisterTypeWide(vregA, src_type1_1, src_type1_2) && @@ -383,8 +383,8 @@ void RegisterLine::CheckBinaryOp2addrWide(const Instruction* inst, } void RegisterLine::CheckBinaryOp2addrWideShift(const Instruction* inst, - RegType& long_lo_type, RegType& long_hi_type, - RegType& int_type) { + const RegType& long_lo_type, const RegType& long_hi_type, + const RegType& int_type) { const uint32_t vregA = inst->VRegA_12x(); const uint32_t vregB = inst->VRegB_12x(); if (VerifyRegisterTypeWide(vregA, long_lo_type, long_hi_type) && @@ -394,7 +394,7 @@ void RegisterLine::CheckBinaryOp2addrWideShift(const Instruction* inst, } void RegisterLine::CheckLiteralOp(const Instruction* inst, - RegType& dst_type, RegType& src_type, + const RegType& dst_type, const RegType& src_type, bool check_boolean_op, bool is_lit16) { const uint32_t vregA = is_lit16 ? inst->VRegA_22s() : inst->VRegA_22b(); const uint32_t vregB = is_lit16 ? inst->VRegB_22s() : inst->VRegB_22b(); @@ -413,7 +413,7 @@ void RegisterLine::CheckLiteralOp(const Instruction* inst, } void RegisterLine::PushMonitor(uint32_t reg_idx, int32_t insn_idx) { - RegType& reg_type = GetRegisterType(reg_idx); + const RegType& reg_type = GetRegisterType(reg_idx); if (!reg_type.IsReferenceTypes()) { verifier_->Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "monitor-enter on non-object (" << reg_type << ")"; } else if (monitors_.size() >= 32) { @@ -425,7 +425,7 @@ void RegisterLine::PushMonitor(uint32_t reg_idx, int32_t insn_idx) { } void RegisterLine::PopMonitor(uint32_t reg_idx) { - RegType& reg_type = GetRegisterType(reg_idx); + const RegType& reg_type = GetRegisterType(reg_idx); if (!reg_type.IsReferenceTypes()) { verifier_->Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "monitor-exit on non-object (" << reg_type << ")"; } else if (monitors_.empty()) { @@ -460,9 +460,9 @@ bool RegisterLine::MergeRegisters(const RegisterLine* incoming_line) { DCHECK(incoming_line != nullptr); for (size_t idx = 0; idx < num_regs_; idx++) { if (line_[idx] != incoming_line->line_[idx]) { - RegType& incoming_reg_type = incoming_line->GetRegisterType(idx); - RegType& cur_type = GetRegisterType(idx); - RegType& new_type = cur_type.Merge(incoming_reg_type, verifier_->GetRegTypeCache()); + const RegType& incoming_reg_type = incoming_line->GetRegisterType(idx); + const RegType& cur_type = GetRegisterType(idx); + const RegType& new_type = cur_type.Merge(incoming_reg_type, verifier_->GetRegTypeCache()); changed = changed || !cur_type.Equals(new_type); line_[idx] = new_type.GetId(); } @@ -508,8 +508,7 @@ void RegisterLine::WriteReferenceBitMap(std::vector<uint8_t>& data, size_t max_b std::ostream& operator<<(std::ostream& os, const RegisterLine& rhs) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { - RegisterLine& rhs_non_const = const_cast<RegisterLine&>(rhs); - os << rhs_non_const.Dump(); + os << rhs.Dump(); return os; } diff --git a/runtime/verifier/register_line.h b/runtime/verifier/register_line.h index 06b7cca..a9d0dbb 100644 --- a/runtime/verifier/register_line.h +++ b/runtime/verifier/register_line.h @@ -81,26 +81,26 @@ class RegisterLine { // Set the type of register N, verifying that the register is valid. If "newType" is the "Lo" // part of a 64-bit value, register N+1 will be set to "newType+1". // The register index was validated during the static pass, so we don't need to check it here. - bool SetRegisterType(uint32_t vdst, RegType& new_type) + bool SetRegisterType(uint32_t vdst, const RegType& new_type) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - bool SetRegisterTypeWide(uint32_t vdst, RegType& new_type1, RegType& new_type2) + bool SetRegisterTypeWide(uint32_t vdst, const RegType& new_type1, const RegType& new_type2) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); /* Set the type of the "result" register. */ - void SetResultRegisterType(RegType& new_type) + void SetResultRegisterType(const RegType& new_type) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - void SetResultRegisterTypeWide(RegType& new_type1, RegType& new_type2) + void SetResultRegisterTypeWide(const RegType& new_type1, const RegType& new_type2) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // Get the type of register vsrc. - RegType& GetRegisterType(uint32_t vsrc) const; + const RegType& GetRegisterType(uint32_t vsrc) const; - bool VerifyRegisterType(uint32_t vsrc, RegType& check_type) + bool VerifyRegisterType(uint32_t vsrc, const RegType& check_type) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - bool VerifyRegisterTypeWide(uint32_t vsrc, RegType& check_type1, RegType& check_type2) + bool VerifyRegisterTypeWide(uint32_t vsrc, const RegType& check_type1, const RegType& check_type2) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); void CopyFromLine(const RegisterLine* src) { @@ -110,7 +110,7 @@ class RegisterLine { reg_to_lock_depths_ = src->reg_to_lock_depths_; } - std::string Dump() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); void FillWithGarbage() { memset(&line_, 0xf1, num_regs_ * sizeof(uint16_t)); @@ -126,7 +126,7 @@ class RegisterLine { * to prevent them from being used (otherwise, MarkRefsAsInitialized would mark the old ones and * the new ones at the same time). */ - void MarkUninitRefsAsInvalid(RegType& uninit_type) + void MarkUninitRefsAsInvalid(const RegType& uninit_type) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); /* @@ -134,7 +134,7 @@ class RegisterLine { * reference type. This is called when an appropriate constructor is invoked -- all copies of * the reference must be marked as initialized. */ - void MarkRefsAsInitialized(RegType& uninit_type) + void MarkRefsAsInitialized(const RegType& uninit_type) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); /* @@ -173,30 +173,30 @@ class RegisterLine { * The argument count is in vA, and the first argument is in vC, for both "simple" and "range" * versions. We just need to make sure vA is >= 1 and then return vC. */ - RegType& GetInvocationThis(const Instruction* inst, bool is_range) + const RegType& GetInvocationThis(const Instruction* inst, bool is_range) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); /* * Verify types for a simple two-register instruction (e.g. "neg-int"). * "dst_type" is stored into vA, and "src_type" is verified against vB. */ - void CheckUnaryOp(const Instruction* inst, RegType& dst_type, - RegType& src_type) + void CheckUnaryOp(const Instruction* inst, const RegType& dst_type, + const RegType& src_type) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); void CheckUnaryOpWide(const Instruction* inst, - RegType& dst_type1, RegType& dst_type2, - RegType& src_type1, RegType& src_type2) + const RegType& dst_type1, const RegType& dst_type2, + const RegType& src_type1, const RegType& src_type2) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); void CheckUnaryOpToWide(const Instruction* inst, - RegType& dst_type1, RegType& dst_type2, - RegType& src_type) + const RegType& dst_type1, const RegType& dst_type2, + const RegType& src_type) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); void CheckUnaryOpFromWide(const Instruction* inst, - RegType& dst_type, - RegType& src_type1, RegType& src_type2) + const RegType& dst_type, + const RegType& src_type1, const RegType& src_type2) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); /* @@ -205,19 +205,19 @@ class RegisterLine { * against vB/vC. */ void CheckBinaryOp(const Instruction* inst, - RegType& dst_type, RegType& src_type1, RegType& src_type2, + const RegType& dst_type, const RegType& src_type1, const RegType& src_type2, bool check_boolean_op) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); void CheckBinaryOpWide(const Instruction* inst, - RegType& dst_type1, RegType& dst_type2, - RegType& src_type1_1, RegType& src_type1_2, - RegType& src_type2_1, RegType& src_type2_2) + const RegType& dst_type1, const RegType& dst_type2, + const RegType& src_type1_1, const RegType& src_type1_2, + const RegType& src_type2_1, const RegType& src_type2_2) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); void CheckBinaryOpWideShift(const Instruction* inst, - RegType& long_lo_type, RegType& long_hi_type, - RegType& int_type) + const RegType& long_lo_type, const RegType& long_hi_type, + const RegType& int_type) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); /* @@ -225,20 +225,20 @@ class RegisterLine { * are verified against vA/vB, then "dst_type" is stored into vA. */ void CheckBinaryOp2addr(const Instruction* inst, - RegType& dst_type, - RegType& src_type1, RegType& src_type2, + const RegType& dst_type, + const RegType& src_type1, const RegType& src_type2, bool check_boolean_op) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); void CheckBinaryOp2addrWide(const Instruction* inst, - RegType& dst_type1, RegType& dst_type2, - RegType& src_type1_1, RegType& src_type1_2, - RegType& src_type2_1, RegType& src_type2_2) + const RegType& dst_type1, const RegType& dst_type2, + const RegType& src_type1_1, const RegType& src_type1_2, + const RegType& src_type2_1, const RegType& src_type2_2) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); void CheckBinaryOp2addrWideShift(const Instruction* inst, - RegType& long_lo_type, RegType& long_hi_type, - RegType& int_type) + const RegType& long_lo_type, const RegType& long_hi_type, + const RegType& int_type) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); /* @@ -248,7 +248,7 @@ class RegisterLine { * If "check_boolean_op" is set, we use the constant value in vC. */ void CheckLiteralOp(const Instruction* inst, - RegType& dst_type, RegType& src_type, + const RegType& dst_type, const RegType& src_type, bool check_boolean_op, bool is_lit16) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); |