diff options
author | Andreas Gampe <agampe@google.com> | 2016-11-17 15:21:22 -0800 |
---|---|---|
committer | Andreas Gampe <agampe@google.com> | 2016-11-21 10:57:00 -0800 |
commit | a5b09a67034e57a6e10231dd4bd92f4cb50b824c (patch) | |
tree | 304be738f4fa528b7ad2676103eecc84c79eaeeb | |
parent | dac7ad17c78387d15d7aefae0f852dddf5f37e34 (diff) |
ART: Add dex::TypeIndex
Add abstraction for uint16_t type index.
Test: m test-art-host
Change-Id: I47708741c7c579cbbe59ab723c1e31c5fe71f83a
93 files changed, 832 insertions, 571 deletions
diff --git a/compiler/compiled_method.h b/compiler/compiled_method.h index 99b0ac10d1..174e85e1bf 100644 --- a/compiler/compiled_method.h +++ b/compiler/compiled_method.h @@ -26,6 +26,7 @@ #include "base/array_ref.h" #include "base/bit_utils.h" #include "base/length_prefixed_array.h" +#include "dex_file_types.h" #include "method_reference.h" namespace art { @@ -302,9 +303,9 @@ class LinkerPatch { return target_dex_file_; } - uint32_t TargetTypeIndex() const { + dex::TypeIndex TargetTypeIndex() const { DCHECK(patch_type_ == Type::kType || patch_type_ == Type::kTypeRelative); - return type_idx_; + return dex::TypeIndex(type_idx_); } const DexFile* TargetStringDexFile() const { diff --git a/compiler/dex/verified_method.cc b/compiler/dex/verified_method.cc index e19fb7b300..1bdace9284 100644 --- a/compiler/dex/verified_method.cc +++ b/compiler/dex/verified_method.cc @@ -230,7 +230,7 @@ void VerifiedMethod::GenerateSafeCastSet(verifier::MethodVerifier* method_verifi const verifier::RegType& reg_type(line->GetRegisterType(method_verifier, inst->VRegA_21c())); const verifier::RegType& cast_type = - method_verifier->ResolveCheckedClass(inst->VRegB_21c()); + method_verifier->ResolveCheckedClass(dex::TypeIndex(inst->VRegB_21c())); is_safe_cast = cast_type.IsStrictlyAssignableFrom(reg_type, method_verifier); } else { const verifier::RegType& array_type(line->GetRegisterType(method_verifier, diff --git a/compiler/driver/compiler_driver-inl.h b/compiler/driver/compiler_driver-inl.h index 971151665a..f056dd3c00 100644 --- a/compiler/driver/compiler_driver-inl.h +++ b/compiler/driver/compiler_driver-inl.h @@ -38,7 +38,7 @@ inline mirror::ClassLoader* CompilerDriver::GetClassLoader(const ScopedObjectAcc inline mirror::Class* CompilerDriver::ResolveClass( const ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache, - Handle<mirror::ClassLoader> class_loader, uint16_t cls_index, + Handle<mirror::ClassLoader> class_loader, dex::TypeIndex cls_index, const DexCompilationUnit* mUnit) { DCHECK_EQ(dex_cache->GetDexFile(), mUnit->GetDexFile()); DCHECK_EQ(class_loader.Get(), GetClassLoader(soa, mUnit)); @@ -141,7 +141,7 @@ inline std::pair<bool, bool> CompilerDriver::IsClassOfStaticMemberAvailableToRef mirror::Class* referrer_class, ArtMember* resolved_member, uint16_t member_idx, - uint32_t* storage_index) { + dex::TypeIndex* storage_index) { DCHECK(resolved_member->IsStatic()); if (LIKELY(referrer_class != nullptr)) { ObjPtr<mirror::Class> members_class = resolved_member->GetDeclaringClass(); @@ -156,7 +156,7 @@ inline std::pair<bool, bool> CompilerDriver::IsClassOfStaticMemberAvailableToRef // TODO: for images we can elide the static storage base null check // if we know there's a non-null entry in the image const DexFile* dex_file = dex_cache->GetDexFile(); - uint32_t storage_idx = DexFile::kDexNoIndex; + dex::TypeIndex storage_idx(DexFile::kDexNoIndex16); if (LIKELY(members_class->GetDexCache() == dex_cache)) { // common case where the dex cache of both the referrer and the member are the same, // no need to search the dex file @@ -166,27 +166,27 @@ inline std::pair<bool, bool> CompilerDriver::IsClassOfStaticMemberAvailableToRef // of the class mentioned in the dex file and there is no dex cache entry. storage_idx = resolved_member->GetDeclaringClass()->FindTypeIndexInOtherDexFile(*dex_file); } - if (storage_idx != DexFile::kDexNoIndex) { + if (storage_idx.IsValid()) { *storage_index = storage_idx; return std::make_pair(true, !resolved_member->IsFinal()); } } } // Conservative defaults. - *storage_index = DexFile::kDexNoIndex; + *storage_index = dex::TypeIndex(DexFile::kDexNoIndex16); return std::make_pair(false, false); } inline std::pair<bool, bool> CompilerDriver::IsFastStaticField( mirror::DexCache* dex_cache, mirror::Class* referrer_class, - ArtField* resolved_field, uint16_t field_idx, uint32_t* storage_index) { + ArtField* resolved_field, uint16_t field_idx, dex::TypeIndex* storage_index) { return IsClassOfStaticMemberAvailableToReferrer( dex_cache, referrer_class, resolved_field, field_idx, storage_index); } inline bool CompilerDriver::IsClassOfStaticMethodAvailableToReferrer( mirror::DexCache* dex_cache, mirror::Class* referrer_class, - ArtMethod* resolved_method, uint16_t method_idx, uint32_t* storage_index) { + ArtMethod* resolved_method, uint16_t method_idx, dex::TypeIndex* storage_index) { std::pair<bool, bool> result = IsClassOfStaticMemberAvailableToReferrer( dex_cache, referrer_class, resolved_method, method_idx, storage_index); // Only the first member of `result` is meaningful, as there is no diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc index aa0d10b8d4..c62e2142b7 100644 --- a/compiler/driver/compiler_driver.cc +++ b/compiler/driver/compiler_driver.cc @@ -969,7 +969,7 @@ bool CompilerDriver::ShouldVerifyClassBasedOnProfile(const DexFile& dex_file, } DCHECK(profile_compilation_info_ != nullptr); const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_idx); - uint16_t type_idx = class_def.class_idx_; + dex::TypeIndex type_idx = class_def.class_idx_; bool result = profile_compilation_info_->ContainsClass(dex_file, type_idx); if (kDebugProfileGuidedCompilation) { LOG(INFO) << "[ProfileGuidedCompilation] " << (result ? "Verified" : "Skipped") << " method:" @@ -981,7 +981,7 @@ bool CompilerDriver::ShouldVerifyClassBasedOnProfile(const DexFile& dex_file, class ResolveCatchBlockExceptionsClassVisitor : public ClassVisitor { public: explicit ResolveCatchBlockExceptionsClassVisitor( - std::set<std::pair<uint16_t, const DexFile*>>& exceptions_to_resolve) + std::set<std::pair<dex::TypeIndex, const DexFile*>>& exceptions_to_resolve) : exceptions_to_resolve_(exceptions_to_resolve) {} virtual bool operator()(ObjPtr<mirror::Class> c) OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) { @@ -1012,8 +1012,8 @@ class ResolveCatchBlockExceptionsClassVisitor : public ClassVisitor { has_catch_all = true; } for (int32_t j = 0; j < encoded_catch_handler_size; j++) { - uint16_t encoded_catch_handler_handlers_type_idx = - DecodeUnsignedLeb128(&encoded_catch_handler_list); + dex::TypeIndex encoded_catch_handler_handlers_type_idx = + dex::TypeIndex(DecodeUnsignedLeb128(&encoded_catch_handler_list)); // Add to set of types to resolve if not already in the dex cache resolved types if (!method_handle->IsResolvedTypeIdx(encoded_catch_handler_handlers_type_idx, pointer_size)) { @@ -1030,7 +1030,7 @@ class ResolveCatchBlockExceptionsClassVisitor : public ClassVisitor { } } - std::set<std::pair<uint16_t, const DexFile*>>& exceptions_to_resolve_; + std::set<std::pair<dex::TypeIndex, const DexFile*>>& exceptions_to_resolve_; }; class RecordImageClassesVisitor : public ClassVisitor { @@ -1078,7 +1078,7 @@ void CompilerDriver::LoadImageClasses(TimingLogger* timings) { // Resolve exception classes referenced by the loaded classes. The catch logic assumes // exceptions are resolved by the verifier when there is a catch block in an interested method. // Do this here so that exception classes appear to have been specified image classes. - std::set<std::pair<uint16_t, const DexFile*>> unresolved_exception_types; + std::set<std::pair<dex::TypeIndex, const DexFile*>> unresolved_exception_types; StackHandleScope<1> hs(self); Handle<mirror::Class> java_lang_Throwable( hs.NewHandle(class_linker->FindSystemClass(self, "Ljava/lang/Throwable;"))); @@ -1086,8 +1086,8 @@ void CompilerDriver::LoadImageClasses(TimingLogger* timings) { unresolved_exception_types.clear(); ResolveCatchBlockExceptionsClassVisitor visitor(unresolved_exception_types); class_linker->VisitClasses(&visitor); - for (const std::pair<uint16_t, const DexFile*>& exception_type : unresolved_exception_types) { - uint16_t exception_type_idx = exception_type.first; + for (const auto& exception_type : unresolved_exception_types) { + dex::TypeIndex exception_type_idx = exception_type.first; const DexFile* dex_file = exception_type.second; StackHandleScope<2> hs2(self); Handle<mirror::DexCache> dex_cache(hs2.NewHandle(class_linker->RegisterDexFile(*dex_file, @@ -1338,7 +1338,7 @@ void CompilerDriver::MarkForDexToDexCompilation(Thread* self, const MethodRefere bool CompilerDriver::CanAccessTypeWithoutChecks(uint32_t referrer_idx, Handle<mirror::DexCache> dex_cache, - uint32_t type_idx) { + dex::TypeIndex type_idx) { // Get type from dex cache assuming it was populated by the verifier mirror::Class* resolved_class = dex_cache->GetResolvedType(type_idx); if (resolved_class == nullptr) { @@ -1367,7 +1367,7 @@ bool CompilerDriver::CanAccessTypeWithoutChecks(uint32_t referrer_idx, bool CompilerDriver::CanAccessInstantiableTypeWithoutChecks(uint32_t referrer_idx, Handle<mirror::DexCache> dex_cache, - uint32_t type_idx, + dex::TypeIndex type_idx, bool* finalizable) { // Get type from dex cache assuming it was populated by the verifier. mirror::Class* resolved_class = dex_cache->GetResolvedType(type_idx); @@ -1861,7 +1861,7 @@ class ResolveTypeVisitor : public CompilationVisitor { public: explicit ResolveTypeVisitor(const ParallelCompilationManager* manager) : manager_(manager) { } - virtual void Visit(size_t type_idx) OVERRIDE REQUIRES(!Locks::mutator_lock_) { + void Visit(size_t type_idx) OVERRIDE REQUIRES(!Locks::mutator_lock_) { // Class derived values are more complicated, they require the linker and loader. ScopedObjectAccess soa(Thread::Current()); ClassLinker* class_linker = manager_->GetClassLinker(); @@ -1872,7 +1872,10 @@ class ResolveTypeVisitor : public CompilationVisitor { Handle<mirror::DexCache> dex_cache(hs.NewHandle(class_linker->RegisterDexFile( dex_file, class_loader.Get()))); - mirror::Class* klass = class_linker->ResolveType(dex_file, type_idx, dex_cache, class_loader); + mirror::Class* klass = class_linker->ResolveType(dex_file, + dex::TypeIndex(type_idx), + dex_cache, + class_loader); if (klass == nullptr) { soa.Self()->AssertPendingException(); @@ -1952,9 +1955,9 @@ void CompilerDriver::Verify(jobject jclass_loader, for (const DexFile* dex_file : dex_files) { // Fetch the list of unverified classes and turn it into a set for faster // lookups. - const std::vector<uint16_t>& unverified_classes = + const std::vector<dex::TypeIndex>& unverified_classes = verifier_deps->GetUnverifiedClasses(*dex_file); - std::set<uint16_t> set(unverified_classes.begin(), unverified_classes.end()); + std::set<dex::TypeIndex> set(unverified_classes.begin(), unverified_classes.end()); for (uint32_t i = 0; i < dex_file->NumClassDefs(); ++i) { const DexFile::ClassDef& class_def = dex_file->GetClassDef(i); const char* descriptor = dex_file->GetClassDescriptor(class_def); diff --git a/compiler/driver/compiler_driver.h b/compiler/driver/compiler_driver.h index 1bd354658a..c7719fb63f 100644 --- a/compiler/driver/compiler_driver.h +++ b/compiler/driver/compiler_driver.h @@ -31,6 +31,7 @@ #include "class_reference.h" #include "compiler.h" #include "dex_file.h" +#include "dex_file_types.h" #include "driver/compiled_method_storage.h" #include "jit/offline_profiling_info.h" #include "invoke_type.h" @@ -188,14 +189,14 @@ class CompilerDriver { // Are runtime access checks necessary in the compiled code? bool CanAccessTypeWithoutChecks(uint32_t referrer_idx, Handle<mirror::DexCache> dex_cache, - uint32_t type_idx) + dex::TypeIndex type_idx) REQUIRES_SHARED(Locks::mutator_lock_); // Are runtime access and instantiable checks necessary in the code? // out_is_finalizable is set to whether the type is finalizable. bool CanAccessInstantiableTypeWithoutChecks(uint32_t referrer_idx, Handle<mirror::DexCache> dex_cache, - uint32_t type_idx, + dex::TypeIndex type_idx, bool* out_is_finalizable) REQUIRES_SHARED(Locks::mutator_lock_); @@ -207,7 +208,7 @@ class CompilerDriver { mirror::Class* ResolveClass( const ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache, - Handle<mirror::ClassLoader> class_loader, uint16_t type_index, + Handle<mirror::ClassLoader> class_loader, dex::TypeIndex type_index, const DexCompilationUnit* mUnit) REQUIRES_SHARED(Locks::mutator_lock_); @@ -234,9 +235,11 @@ class CompilerDriver { // Can we fast-path an SGET/SPUT access to a static field? If yes, compute the type index // of the declaring class in the referrer's dex file. - std::pair<bool, bool> IsFastStaticField( - mirror::DexCache* dex_cache, mirror::Class* referrer_class, - ArtField* resolved_field, uint16_t field_idx, uint32_t* storage_index) + std::pair<bool, bool> IsFastStaticField(mirror::DexCache* dex_cache, + mirror::Class* referrer_class, + ArtField* resolved_field, + uint16_t field_idx, + dex::TypeIndex* storage_index) REQUIRES_SHARED(Locks::mutator_lock_); // Return whether the declaring class of `resolved_method` is @@ -248,7 +251,7 @@ class CompilerDriver { mirror::Class* referrer_class, ArtMethod* resolved_method, uint16_t method_idx, - uint32_t* storage_index) + dex::TypeIndex* storage_index) REQUIRES_SHARED(Locks::mutator_lock_); // Resolve a method. Returns null on failure, including incompatible class change. @@ -395,7 +398,7 @@ class CompilerDriver { mirror::Class* referrer_class, ArtMember* resolved_member, uint16_t member_idx, - uint32_t* storage_index) + dex::TypeIndex* storage_index) REQUIRES_SHARED(Locks::mutator_lock_); // Can `referrer_class` access the resolved `member`? diff --git a/compiler/driver/compiler_driver_test.cc b/compiler/driver/compiler_driver_test.cc index 9679a796cb..f40c71283b 100644 --- a/compiler/driver/compiler_driver_test.cc +++ b/compiler/driver/compiler_driver_test.cc @@ -24,6 +24,7 @@ #include "class_linker-inl.h" #include "common_compiler_test.h" #include "dex_file.h" +#include "dex_file_types.h" #include "gc/heap.h" #include "mirror/class-inl.h" #include "mirror/class_loader.h" @@ -115,9 +116,9 @@ TEST_F(CompilerDriverTest, DISABLED_LARGE_CompileDexLibCore) { } EXPECT_EQ(dex.NumTypeIds(), dex_cache->NumResolvedTypes()); for (size_t i = 0; i < dex_cache->NumResolvedTypes(); i++) { - mirror::Class* type = dex_cache->GetResolvedType(i); + mirror::Class* type = dex_cache->GetResolvedType(dex::TypeIndex(i)); EXPECT_TRUE(type != nullptr) << "type_idx=" << i - << " " << dex.GetTypeDescriptor(dex.GetTypeId(i)); + << " " << dex.GetTypeDescriptor(dex.GetTypeId(dex::TypeIndex(i))); } EXPECT_EQ(dex.NumMethodIds(), dex_cache->NumResolvedMethods()); auto* cl = Runtime::Current()->GetClassLinker(); diff --git a/compiler/image_writer.cc b/compiler/image_writer.cc index d7b7403442..a706697496 100644 --- a/compiler/image_writer.cc +++ b/compiler/image_writer.cc @@ -32,6 +32,7 @@ #include "class_linker-inl.h" #include "compiled_method.h" #include "dex_file-inl.h" +#include "dex_file_types.h" #include "driver/compiler_driver.h" #include "elf_file.h" #include "elf_utils.h" @@ -890,9 +891,9 @@ void ImageWriter::PruneNonImageClasses() { } ObjPtr<mirror::DexCache> dex_cache = self->DecodeJObject(data.weak_root)->AsDexCache(); for (size_t i = 0; i < dex_cache->NumResolvedTypes(); i++) { - Class* klass = dex_cache->GetResolvedType(i); + Class* klass = dex_cache->GetResolvedType(dex::TypeIndex(i)); if (klass != nullptr && !KeepClass(klass)) { - dex_cache->SetResolvedType(i, nullptr); + dex_cache->SetResolvedType(dex::TypeIndex(i), nullptr); } } ArtMethod** resolved_methods = dex_cache->GetResolvedMethods(); diff --git a/compiler/optimizing/bounds_check_elimination_test.cc b/compiler/optimizing/bounds_check_elimination_test.cc index b7c24ff207..dfa150406d 100644 --- a/compiler/optimizing/bounds_check_elimination_test.cc +++ b/compiler/optimizing/bounds_check_elimination_test.cc @@ -70,9 +70,9 @@ TEST_F(BoundsCheckEliminationTest, NarrowingRangeArrayBoundsElimination) { graph_->AddBlock(entry); graph_->SetEntryBlock(entry); HInstruction* parameter1 = new (&allocator_) - HParameterValue(graph_->GetDexFile(), 0, 0, Primitive::kPrimNot); // array + HParameterValue(graph_->GetDexFile(), dex::TypeIndex(0), 0, Primitive::kPrimNot); // array HInstruction* parameter2 = new (&allocator_) - HParameterValue(graph_->GetDexFile(), 0, 0, Primitive::kPrimInt); // i + HParameterValue(graph_->GetDexFile(), dex::TypeIndex(0), 0, Primitive::kPrimInt); // i entry->AddInstruction(parameter1); entry->AddInstruction(parameter2); @@ -167,9 +167,9 @@ TEST_F(BoundsCheckEliminationTest, OverflowArrayBoundsElimination) { graph_->AddBlock(entry); graph_->SetEntryBlock(entry); HInstruction* parameter1 = new (&allocator_) - HParameterValue(graph_->GetDexFile(), 0, 0, Primitive::kPrimNot); // array + HParameterValue(graph_->GetDexFile(), dex::TypeIndex(0), 0, Primitive::kPrimNot); // array HInstruction* parameter2 = new (&allocator_) - HParameterValue(graph_->GetDexFile(), 0, 0, Primitive::kPrimInt); // i + HParameterValue(graph_->GetDexFile(), dex::TypeIndex(0), 0, Primitive::kPrimInt); // i entry->AddInstruction(parameter1); entry->AddInstruction(parameter2); @@ -231,9 +231,9 @@ TEST_F(BoundsCheckEliminationTest, UnderflowArrayBoundsElimination) { graph_->AddBlock(entry); graph_->SetEntryBlock(entry); HInstruction* parameter1 = new (&allocator_) - HParameterValue(graph_->GetDexFile(), 0, 0, Primitive::kPrimNot); // array + HParameterValue(graph_->GetDexFile(), dex::TypeIndex(0), 0, Primitive::kPrimNot); // array HInstruction* parameter2 = new (&allocator_) - HParameterValue(graph_->GetDexFile(), 0, 0, Primitive::kPrimInt); // i + HParameterValue(graph_->GetDexFile(), dex::TypeIndex(0), 0, Primitive::kPrimInt); // i entry->AddInstruction(parameter1); entry->AddInstruction(parameter2); @@ -295,7 +295,7 @@ TEST_F(BoundsCheckEliminationTest, ConstantArrayBoundsElimination) { graph_->AddBlock(entry); graph_->SetEntryBlock(entry); HInstruction* parameter = new (&allocator_) HParameterValue( - graph_->GetDexFile(), 0, 0, Primitive::kPrimNot); + graph_->GetDexFile(), dex::TypeIndex(0), 0, Primitive::kPrimNot); entry->AddInstruction(parameter); HInstruction* constant_5 = graph_->GetIntConstant(5); @@ -364,7 +364,7 @@ static HInstruction* BuildSSAGraph1(HGraph* graph, graph->AddBlock(entry); graph->SetEntryBlock(entry); HInstruction* parameter = new (allocator) HParameterValue( - graph->GetDexFile(), 0, 0, Primitive::kPrimNot); + graph->GetDexFile(), dex::TypeIndex(0), 0, Primitive::kPrimNot); entry->AddInstruction(parameter); HInstruction* constant_initial = graph->GetIntConstant(initial); @@ -479,7 +479,7 @@ static HInstruction* BuildSSAGraph2(HGraph *graph, graph->AddBlock(entry); graph->SetEntryBlock(entry); HInstruction* parameter = new (allocator) HParameterValue( - graph->GetDexFile(), 0, 0, Primitive::kPrimNot); + graph->GetDexFile(), dex::TypeIndex(0), 0, Primitive::kPrimNot); entry->AddInstruction(parameter); HInstruction* constant_initial = graph->GetIntConstant(initial); @@ -600,7 +600,7 @@ static HInstruction* BuildSSAGraph3(HGraph* graph, constant_10, graph->GetCurrentMethod(), 0, - Primitive::kPrimInt, + dex::TypeIndex(static_cast<uint16_t>(Primitive::kPrimInt)), graph->GetDexFile(), kQuickAllocArray); block->AddInstruction(new_array); @@ -692,7 +692,7 @@ static HInstruction* BuildSSAGraph4(HGraph* graph, graph->AddBlock(entry); graph->SetEntryBlock(entry); HInstruction* parameter = new (allocator) HParameterValue( - graph->GetDexFile(), 0, 0, Primitive::kPrimNot); + graph->GetDexFile(), dex::TypeIndex(0), 0, Primitive::kPrimNot); entry->AddInstruction(parameter); HInstruction* constant_initial = graph->GetIntConstant(initial); @@ -795,7 +795,7 @@ TEST_F(BoundsCheckEliminationTest, BubbleSortArrayBoundsElimination) { graph_->AddBlock(entry); graph_->SetEntryBlock(entry); HInstruction* parameter = new (&allocator_) HParameterValue( - graph_->GetDexFile(), 0, 0, Primitive::kPrimNot); + graph_->GetDexFile(), dex::TypeIndex(0), 0, Primitive::kPrimNot); entry->AddInstruction(parameter); HInstruction* constant_0 = graph_->GetIntConstant(0); diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc index a341086ac4..8a6b94e0ea 100644 --- a/compiler/optimizing/code_generator_arm.cc +++ b/compiler/optimizing/code_generator_arm.cc @@ -383,7 +383,7 @@ class LoadClassSlowPathARM : public SlowPathCodeARM { SaveLiveRegisters(codegen, locations); InvokeRuntimeCallingConvention calling_convention; - __ LoadImmediate(calling_convention.GetRegisterAt(0), cls_->GetTypeIndex()); + __ LoadImmediate(calling_convention.GetRegisterAt(0), cls_->GetTypeIndex().index_); QuickEntrypointEnum entrypoint = do_clinit_ ? kQuickInitializeStaticStorage : kQuickInitializeType; arm_codegen->InvokeRuntime(entrypoint, at_, dex_pc_, this); @@ -3953,7 +3953,7 @@ void LocationsBuilderARM::VisitNewArray(HNewArray* instruction) { void InstructionCodeGeneratorARM::VisitNewArray(HNewArray* instruction) { InvokeRuntimeCallingConvention calling_convention; - __ LoadImmediate(calling_convention.GetRegisterAt(0), instruction->GetTypeIndex()); + __ LoadImmediate(calling_convention.GetRegisterAt(0), instruction->GetTypeIndex().index_); // Note: if heap poisoning is enabled, the entry point takes cares // of poisoning the reference. codegen_->InvokeRuntime(instruction->GetEntrypoint(), instruction, instruction->GetDexPc()); @@ -5743,7 +5743,7 @@ void LocationsBuilderARM::VisitLoadClass(HLoadClass* cls) { void InstructionCodeGeneratorARM::VisitLoadClass(HLoadClass* cls) { LocationSummary* locations = cls->GetLocations(); if (cls->NeedsAccessCheck()) { - codegen_->MoveConstant(locations->GetTemp(0), cls->GetTypeIndex()); + codegen_->MoveConstant(locations->GetTemp(0), cls->GetTypeIndex().index_); codegen_->InvokeRuntime(kQuickInitializeTypeAndVerifyAccess, cls, cls->GetDexPc()); CheckEntrypointTypes<kQuickInitializeTypeAndVerifyAccess, void*, uint32_t>(); return; @@ -5830,7 +5830,7 @@ void InstructionCodeGeneratorARM::VisitLoadClass(HLoadClass* cls) { current_method, ArtMethod::DexCacheResolvedTypesOffset(kArmPointerSize).Int32Value()); // /* GcRoot<mirror::Class> */ out = out[type_index] - size_t offset = CodeGenerator::GetCacheOffset(cls->GetTypeIndex()); + size_t offset = CodeGenerator::GetCacheOffset(cls->GetTypeIndex().index_); GenerateGcRootFieldLoad(cls, out_loc, out, offset, read_barrier_option); generate_null_check = !cls->IsInDexCache(); } @@ -7324,8 +7324,8 @@ CodeGeneratorARM::PcRelativePatchInfo* CodeGeneratorARM::NewPcRelativeStringPatc } CodeGeneratorARM::PcRelativePatchInfo* CodeGeneratorARM::NewPcRelativeTypePatch( - const DexFile& dex_file, uint32_t type_index) { - return NewPcRelativePatch(dex_file, type_index, &pc_relative_type_patches_); + const DexFile& dex_file, dex::TypeIndex type_index) { + return NewPcRelativePatch(dex_file, type_index.index_, &pc_relative_type_patches_); } CodeGeneratorARM::PcRelativePatchInfo* CodeGeneratorARM::NewPcRelativeDexCacheArrayPatch( @@ -7347,7 +7347,7 @@ Literal* CodeGeneratorARM::DeduplicateBootImageStringLiteral(const DexFile& dex_ } Literal* CodeGeneratorARM::DeduplicateBootImageTypeLiteral(const DexFile& dex_file, - uint32_t type_index) { + dex::TypeIndex type_index) { return boot_image_type_patches_.GetOrCreate( TypeReference(&dex_file, type_index), [this]() { return __ NewLiteral<uint32_t>(/* placeholder */ 0u); }); @@ -7452,7 +7452,7 @@ void CodeGeneratorARM::EmitLinkerPatches(ArenaVector<LinkerPatch>* linker_patche uint32_t literal_offset = literal->GetLabel()->Position(); linker_patches->push_back(LinkerPatch::TypePatch(literal_offset, target_type.dex_file, - target_type.type_index)); + target_type.type_index.index_)); } EmitPcRelativeLinkerPatches<LinkerPatch::RelativeTypePatch>(pc_relative_type_patches_, linker_patches); diff --git a/compiler/optimizing/code_generator_arm.h b/compiler/optimizing/code_generator_arm.h index 8ace3dac08..a4ccb57c1f 100644 --- a/compiler/optimizing/code_generator_arm.h +++ b/compiler/optimizing/code_generator_arm.h @@ -19,6 +19,7 @@ #include "base/enums.h" #include "code_generator.h" +#include "dex_file_types.h" #include "driver/compiler_options.h" #include "nodes.h" #include "string_reference.h" @@ -481,11 +482,11 @@ class CodeGeneratorARM : public CodeGenerator { }; PcRelativePatchInfo* NewPcRelativeStringPatch(const DexFile& dex_file, uint32_t string_index); - PcRelativePatchInfo* NewPcRelativeTypePatch(const DexFile& dex_file, uint32_t type_index); + PcRelativePatchInfo* NewPcRelativeTypePatch(const DexFile& dex_file, dex::TypeIndex type_index); PcRelativePatchInfo* NewPcRelativeDexCacheArrayPatch(const DexFile& dex_file, uint32_t element_offset); Literal* DeduplicateBootImageStringLiteral(const DexFile& dex_file, uint32_t string_index); - Literal* DeduplicateBootImageTypeLiteral(const DexFile& dex_file, uint32_t type_index); + Literal* DeduplicateBootImageTypeLiteral(const DexFile& dex_file, dex::TypeIndex type_index); Literal* DeduplicateBootImageAddressLiteral(uint32_t address); Literal* DeduplicateDexCacheAddressLiteral(uint32_t address); Literal* DeduplicateJitStringLiteral(const DexFile& dex_file, uint32_t string_index); diff --git a/compiler/optimizing/code_generator_arm64.cc b/compiler/optimizing/code_generator_arm64.cc index c9e563b095..59e17841e4 100644 --- a/compiler/optimizing/code_generator_arm64.cc +++ b/compiler/optimizing/code_generator_arm64.cc @@ -288,7 +288,7 @@ class LoadClassSlowPathARM64 : public SlowPathCodeARM64 { SaveLiveRegisters(codegen, locations); InvokeRuntimeCallingConvention calling_convention; - __ Mov(calling_convention.GetRegisterAt(0).W(), cls_->GetTypeIndex()); + __ Mov(calling_convention.GetRegisterAt(0).W(), cls_->GetTypeIndex().index_); QuickEntrypointEnum entrypoint = do_clinit_ ? kQuickInitializeStaticStorage : kQuickInitializeType; arm64_codegen->InvokeRuntime(entrypoint, at_, dex_pc_, this); @@ -4102,9 +4102,9 @@ vixl::aarch64::Label* CodeGeneratorARM64::NewPcRelativeStringPatch( vixl::aarch64::Label* CodeGeneratorARM64::NewPcRelativeTypePatch( const DexFile& dex_file, - uint32_t type_index, + dex::TypeIndex type_index, vixl::aarch64::Label* adrp_label) { - return NewPcRelativePatch(dex_file, type_index, adrp_label, &pc_relative_type_patches_); + return NewPcRelativePatch(dex_file, type_index.index_, adrp_label, &pc_relative_type_patches_); } vixl::aarch64::Label* CodeGeneratorARM64::NewPcRelativeDexCacheArrayPatch( @@ -4136,7 +4136,7 @@ vixl::aarch64::Literal<uint32_t>* CodeGeneratorARM64::DeduplicateBootImageString } vixl::aarch64::Literal<uint32_t>* CodeGeneratorARM64::DeduplicateBootImageTypeLiteral( - const DexFile& dex_file, uint32_t type_index) { + const DexFile& dex_file, dex::TypeIndex type_index) { return boot_image_type_patches_.GetOrCreate( TypeReference(&dex_file, type_index), [this]() { return __ CreateLiteralDestroyedWithPool<uint32_t>(/* placeholder */ 0u); }); @@ -4257,7 +4257,7 @@ void CodeGeneratorARM64::EmitLinkerPatches(ArenaVector<LinkerPatch>* linker_patc vixl::aarch64::Literal<uint32_t>* literal = entry.second; linker_patches->push_back(LinkerPatch::TypePatch(literal->GetOffset(), target_type.dex_file, - target_type.type_index)); + target_type.type_index.index_)); } EmitPcRelativeLinkerPatches<LinkerPatch::RelativeTypePatch>(pc_relative_type_patches_, linker_patches); @@ -4381,7 +4381,7 @@ void LocationsBuilderARM64::VisitLoadClass(HLoadClass* cls) { void InstructionCodeGeneratorARM64::VisitLoadClass(HLoadClass* cls) { if (cls->NeedsAccessCheck()) { - codegen_->MoveConstant(cls->GetLocations()->GetTemp(0), cls->GetTypeIndex()); + codegen_->MoveConstant(cls->GetLocations()->GetTemp(0), cls->GetTypeIndex().index_); codegen_->InvokeRuntime(kQuickInitializeTypeAndVerifyAccess, cls, cls->GetDexPc()); CheckEntrypointTypes<kQuickInitializeTypeAndVerifyAccess, void*, uint32_t>(); return; @@ -4417,7 +4417,7 @@ void InstructionCodeGeneratorARM64::VisitLoadClass(HLoadClass* cls) { DCHECK_EQ(read_barrier_option, kWithoutReadBarrier); // Add ADRP with its PC-relative type patch. const DexFile& dex_file = cls->GetDexFile(); - uint32_t type_index = cls->GetTypeIndex(); + dex::TypeIndex type_index = cls->GetTypeIndex(); vixl::aarch64::Label* adrp_label = codegen_->NewPcRelativeTypePatch(dex_file, type_index); codegen_->EmitAdrpPlaceholder(adrp_label, out.X()); // Add ADD with its PC-relative type patch. @@ -4485,7 +4485,7 @@ void InstructionCodeGeneratorARM64::VisitLoadClass(HLoadClass* cls) { GenerateGcRootFieldLoad(cls, out_loc, out.X(), - CodeGenerator::GetCacheOffset(cls->GetTypeIndex()), + CodeGenerator::GetCacheOffset(cls->GetTypeIndex().index_), /* fixup_label */ nullptr, read_barrier_option); generate_null_check = !cls->IsInDexCache(); @@ -4775,7 +4775,7 @@ void InstructionCodeGeneratorARM64::VisitNewArray(HNewArray* instruction) { InvokeRuntimeCallingConvention calling_convention; Register type_index = RegisterFrom(locations->GetTemp(0), Primitive::kPrimInt); DCHECK(type_index.Is(w0)); - __ Mov(type_index, instruction->GetTypeIndex()); + __ Mov(type_index, instruction->GetTypeIndex().index_); // Note: if heap poisoning is enabled, the entry point takes cares // of poisoning the reference. codegen_->InvokeRuntime(instruction->GetEntrypoint(), instruction, instruction->GetDexPc()); diff --git a/compiler/optimizing/code_generator_arm64.h b/compiler/optimizing/code_generator_arm64.h index a2ab60709f..1545fd3860 100644 --- a/compiler/optimizing/code_generator_arm64.h +++ b/compiler/optimizing/code_generator_arm64.h @@ -20,6 +20,7 @@ #include "arch/arm64/quick_method_frame_info_arm64.h" #include "code_generator.h" #include "common_arm64.h" +#include "dex_file_types.h" #include "driver/compiler_options.h" #include "nodes.h" #include "parallel_move_resolver.h" @@ -547,7 +548,7 @@ class CodeGeneratorARM64 : public CodeGenerator { // ADRP (pass `adrp_label = null`) or the ADD (pass `adrp_label` pointing // to the associated ADRP patch label). vixl::aarch64::Label* NewPcRelativeTypePatch(const DexFile& dex_file, - uint32_t type_index, + dex::TypeIndex type_index, vixl::aarch64::Label* adrp_label = nullptr); // Add a new PC-relative dex cache array patch for an instruction and return @@ -562,7 +563,7 @@ class CodeGeneratorARM64 : public CodeGenerator { vixl::aarch64::Literal<uint32_t>* DeduplicateBootImageStringLiteral(const DexFile& dex_file, uint32_t string_index); vixl::aarch64::Literal<uint32_t>* DeduplicateBootImageTypeLiteral(const DexFile& dex_file, - uint32_t type_index); + dex::TypeIndex type_index); vixl::aarch64::Literal<uint32_t>* DeduplicateBootImageAddressLiteral(uint64_t address); vixl::aarch64::Literal<uint64_t>* DeduplicateDexCacheAddressLiteral(uint64_t address); vixl::aarch64::Literal<uint32_t>* DeduplicateJitStringLiteral(const DexFile& dex_file, diff --git a/compiler/optimizing/code_generator_arm_vixl.cc b/compiler/optimizing/code_generator_arm_vixl.cc index 61e6b4bc5b..b8d9a91311 100644 --- a/compiler/optimizing/code_generator_arm_vixl.cc +++ b/compiler/optimizing/code_generator_arm_vixl.cc @@ -398,7 +398,7 @@ class LoadClassSlowPathARMVIXL : public SlowPathCodeARMVIXL { SaveLiveRegisters(codegen, locations); InvokeRuntimeCallingConventionARMVIXL calling_convention; - __ Mov(calling_convention.GetRegisterAt(0), cls_->GetTypeIndex()); + __ Mov(calling_convention.GetRegisterAt(0), cls_->GetTypeIndex().index_); QuickEntrypointEnum entrypoint = do_clinit_ ? kQuickInitializeStaticStorage : kQuickInitializeType; arm_codegen->InvokeRuntime(entrypoint, at_, dex_pc_, this); @@ -3217,7 +3217,7 @@ void LocationsBuilderARMVIXL::VisitNewArray(HNewArray* instruction) { void InstructionCodeGeneratorARMVIXL::VisitNewArray(HNewArray* instruction) { InvokeRuntimeCallingConventionARMVIXL calling_convention; - __ Mov(calling_convention.GetRegisterAt(0), instruction->GetTypeIndex()); + __ Mov(calling_convention.GetRegisterAt(0), instruction->GetTypeIndex().index_); // Note: if heap poisoning is enabled, the entry point takes cares // of poisoning the reference. codegen_->InvokeRuntime(instruction->GetEntrypoint(), instruction, instruction->GetDexPc()); @@ -4968,7 +4968,7 @@ void LocationsBuilderARMVIXL::VisitLoadClass(HLoadClass* cls) { void InstructionCodeGeneratorARMVIXL::VisitLoadClass(HLoadClass* cls) { LocationSummary* locations = cls->GetLocations(); if (cls->NeedsAccessCheck()) { - codegen_->MoveConstant(locations->GetTemp(0), cls->GetTypeIndex()); + codegen_->MoveConstant(locations->GetTemp(0), cls->GetTypeIndex().index_); codegen_->InvokeRuntime(kQuickInitializeTypeAndVerifyAccess, cls, cls->GetDexPc()); CheckEntrypointTypes<kQuickInitializeTypeAndVerifyAccess, void*, uint32_t>(); return; @@ -5000,7 +5000,7 @@ void InstructionCodeGeneratorARMVIXL::VisitLoadClass(HLoadClass* cls) { ArtMethod::DexCacheResolvedTypesOffset(kArmPointerSize).Int32Value(); GetAssembler()->LoadFromOffset(kLoadWord, out, current_method, resolved_types_offset); // /* GcRoot<mirror::Class> */ out = out[type_index] - size_t offset = CodeGenerator::GetCacheOffset(cls->GetTypeIndex()); + size_t offset = CodeGenerator::GetCacheOffset(cls->GetTypeIndex().index_); GenerateGcRootFieldLoad(cls, out_loc, out, offset, kEmitCompilerReadBarrier); generate_null_check = !cls->IsInDexCache(); break; diff --git a/compiler/optimizing/code_generator_mips.cc b/compiler/optimizing/code_generator_mips.cc index fcbb8f03ad..8f94834333 100644 --- a/compiler/optimizing/code_generator_mips.cc +++ b/compiler/optimizing/code_generator_mips.cc @@ -224,7 +224,7 @@ class LoadClassSlowPathMIPS : public SlowPathCodeMIPS { SaveLiveRegisters(codegen, locations); InvokeRuntimeCallingConvention calling_convention; - __ LoadConst32(calling_convention.GetRegisterAt(0), cls_->GetTypeIndex()); + __ LoadConst32(calling_convention.GetRegisterAt(0), cls_->GetTypeIndex().index_); QuickEntrypointEnum entrypoint = do_clinit_ ? kQuickInitializeStaticStorage : kQuickInitializeType; @@ -1056,7 +1056,7 @@ void CodeGeneratorMIPS::EmitLinkerPatches(ArenaVector<LinkerPatch>* linker_patch uint32_t literal_offset = __ GetLabelLocation(literal->GetLabel()); linker_patches->push_back(LinkerPatch::TypePatch(literal_offset, target_type.dex_file, - target_type.type_index)); + target_type.type_index.index_)); } for (const auto& entry : boot_image_address_patches_) { DCHECK(GetCompilerOptions().GetIncludePatchInformation()); @@ -1073,8 +1073,8 @@ CodeGeneratorMIPS::PcRelativePatchInfo* CodeGeneratorMIPS::NewPcRelativeStringPa } CodeGeneratorMIPS::PcRelativePatchInfo* CodeGeneratorMIPS::NewPcRelativeTypePatch( - const DexFile& dex_file, uint32_t type_index) { - return NewPcRelativePatch(dex_file, type_index, &pc_relative_type_patches_); + const DexFile& dex_file, dex::TypeIndex type_index) { + return NewPcRelativePatch(dex_file, type_index.index_, &pc_relative_type_patches_); } CodeGeneratorMIPS::PcRelativePatchInfo* CodeGeneratorMIPS::NewPcRelativeDexCacheArrayPatch( @@ -1117,7 +1117,7 @@ Literal* CodeGeneratorMIPS::DeduplicateBootImageStringLiteral(const DexFile& dex } Literal* CodeGeneratorMIPS::DeduplicateBootImageTypeLiteral(const DexFile& dex_file, - uint32_t type_index) { + dex::TypeIndex type_index) { return boot_image_type_patches_.GetOrCreate( TypeReference(&dex_file, type_index), [this]() { return __ NewLiteral<uint32_t>(/* placeholder */ 0u); }); @@ -5539,7 +5539,7 @@ void LocationsBuilderMIPS::VisitLoadClass(HLoadClass* cls) { void InstructionCodeGeneratorMIPS::VisitLoadClass(HLoadClass* cls) { LocationSummary* locations = cls->GetLocations(); if (cls->NeedsAccessCheck()) { - codegen_->MoveConstant(locations->GetTemp(0), cls->GetTypeIndex()); + codegen_->MoveConstant(locations->GetTemp(0), cls->GetTypeIndex().index_); codegen_->InvokeRuntime(kQuickInitializeTypeAndVerifyAccess, cls, cls->GetDexPc()); CheckEntrypointTypes<kQuickInitializeTypeAndVerifyAccess, void*, uint32_t>(); return; @@ -5633,7 +5633,7 @@ void InstructionCodeGeneratorMIPS::VisitLoadClass(HLoadClass* cls) { base_or_current_method_reg, ArtMethod::DexCacheResolvedTypesOffset(kArmPointerSize).Int32Value()); // /* GcRoot<mirror::Class> */ out = out[type_index] - size_t offset = CodeGenerator::GetCacheOffset(cls->GetTypeIndex()); + size_t offset = CodeGenerator::GetCacheOffset(cls->GetTypeIndex().index_); GenerateGcRootFieldLoad(cls, out_loc, out, offset); generate_null_check = !cls->IsInDexCache(); } @@ -5975,7 +5975,7 @@ void InstructionCodeGeneratorMIPS::VisitNewArray(HNewArray* instruction) { Register current_method_register = calling_convention.GetRegisterAt(2); __ Lw(current_method_register, SP, kCurrentMethodStackOffset); // Move an uint16_t value to a register. - __ LoadConst32(calling_convention.GetRegisterAt(0), instruction->GetTypeIndex()); + __ LoadConst32(calling_convention.GetRegisterAt(0), instruction->GetTypeIndex().index_); codegen_->InvokeRuntime(instruction->GetEntrypoint(), instruction, instruction->GetDexPc()); CheckEntrypointTypes<kQuickAllocArrayWithAccessCheck, void*, uint32_t, int32_t, ArtMethod*>(); diff --git a/compiler/optimizing/code_generator_mips.h b/compiler/optimizing/code_generator_mips.h index e132819c24..e225d20094 100644 --- a/compiler/optimizing/code_generator_mips.h +++ b/compiler/optimizing/code_generator_mips.h @@ -449,11 +449,11 @@ class CodeGeneratorMIPS : public CodeGenerator { }; PcRelativePatchInfo* NewPcRelativeStringPatch(const DexFile& dex_file, uint32_t string_index); - PcRelativePatchInfo* NewPcRelativeTypePatch(const DexFile& dex_file, uint32_t type_index); + PcRelativePatchInfo* NewPcRelativeTypePatch(const DexFile& dex_file, dex::TypeIndex type_index); PcRelativePatchInfo* NewPcRelativeDexCacheArrayPatch(const DexFile& dex_file, uint32_t element_offset); Literal* DeduplicateBootImageStringLiteral(const DexFile& dex_file, uint32_t string_index); - Literal* DeduplicateBootImageTypeLiteral(const DexFile& dex_file, uint32_t type_index); + Literal* DeduplicateBootImageTypeLiteral(const DexFile& dex_file, dex::TypeIndex type_index); Literal* DeduplicateBootImageAddressLiteral(uint32_t address); void EmitPcRelativeAddressPlaceholder(PcRelativePatchInfo* info, Register out, Register base); diff --git a/compiler/optimizing/code_generator_mips64.cc b/compiler/optimizing/code_generator_mips64.cc index 1a54935a25..02b01c85e5 100644 --- a/compiler/optimizing/code_generator_mips64.cc +++ b/compiler/optimizing/code_generator_mips64.cc @@ -180,7 +180,7 @@ class LoadClassSlowPathMIPS64 : public SlowPathCodeMIPS64 { SaveLiveRegisters(codegen, locations); InvokeRuntimeCallingConvention calling_convention; - __ LoadConst32(calling_convention.GetRegisterAt(0), cls_->GetTypeIndex()); + __ LoadConst32(calling_convention.GetRegisterAt(0), cls_->GetTypeIndex().index_); QuickEntrypointEnum entrypoint = do_clinit_ ? kQuickInitializeStaticStorage : kQuickInitializeType; mips64_codegen->InvokeRuntime(entrypoint, at_, dex_pc_, this); @@ -3157,7 +3157,7 @@ void LocationsBuilderMIPS64::VisitLoadClass(HLoadClass* cls) { void InstructionCodeGeneratorMIPS64::VisitLoadClass(HLoadClass* cls) { LocationSummary* locations = cls->GetLocations(); if (cls->NeedsAccessCheck()) { - codegen_->MoveConstant(locations->GetTemp(0), cls->GetTypeIndex()); + codegen_->MoveConstant(locations->GetTemp(0), cls->GetTypeIndex().index_); codegen_->InvokeRuntime(kQuickInitializeTypeAndVerifyAccess, cls, cls->GetDexPc()); CheckEntrypointTypes<kQuickInitializeTypeAndVerifyAccess, void*, uint32_t>(); return; @@ -3174,7 +3174,7 @@ void InstructionCodeGeneratorMIPS64::VisitLoadClass(HLoadClass* cls) { __ LoadFromOffset(kLoadDoubleword, out, current_method, ArtMethod::DexCacheResolvedTypesOffset(kMips64PointerSize).Int32Value()); __ LoadFromOffset( - kLoadUnsignedWord, out, out, CodeGenerator::GetCacheOffset(cls->GetTypeIndex())); + kLoadUnsignedWord, out, out, CodeGenerator::GetCacheOffset(cls->GetTypeIndex().index_)); // TODO: We will need a read barrier here. if (!cls->IsInDexCache() || cls->MustGenerateClinitCheck()) { DCHECK(cls->CanCallRuntime()); @@ -3382,7 +3382,8 @@ void LocationsBuilderMIPS64::VisitNewArray(HNewArray* instruction) { void InstructionCodeGeneratorMIPS64::VisitNewArray(HNewArray* instruction) { LocationSummary* locations = instruction->GetLocations(); // Move an uint16_t value to a register. - __ LoadConst32(locations->GetTemp(0).AsRegister<GpuRegister>(), instruction->GetTypeIndex()); + __ LoadConst32(locations->GetTemp(0).AsRegister<GpuRegister>(), + instruction->GetTypeIndex().index_); codegen_->InvokeRuntime(instruction->GetEntrypoint(), instruction, instruction->GetDexPc()); CheckEntrypointTypes<kQuickAllocArrayWithAccessCheck, void*, uint32_t, int32_t, ArtMethod*>(); } diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc index 38494370ab..51e902a824 100644 --- a/compiler/optimizing/code_generator_x86.cc +++ b/compiler/optimizing/code_generator_x86.cc @@ -265,7 +265,7 @@ class LoadClassSlowPathX86 : public SlowPathCode { SaveLiveRegisters(codegen, locations); InvokeRuntimeCallingConvention calling_convention; - __ movl(calling_convention.GetRegisterAt(0), Immediate(cls_->GetTypeIndex())); + __ movl(calling_convention.GetRegisterAt(0), Immediate(cls_->GetTypeIndex().index_)); x86_codegen->InvokeRuntime(do_clinit_ ? kQuickInitializeStaticStorage : kQuickInitializeType, at_, dex_pc_, this); @@ -4168,7 +4168,7 @@ void LocationsBuilderX86::VisitNewArray(HNewArray* instruction) { void InstructionCodeGeneratorX86::VisitNewArray(HNewArray* instruction) { InvokeRuntimeCallingConvention calling_convention; - __ movl(calling_convention.GetRegisterAt(0), Immediate(instruction->GetTypeIndex())); + __ movl(calling_convention.GetRegisterAt(0), Immediate(instruction->GetTypeIndex().index_)); // Note: if heap poisoning is enabled, the entry point takes cares // of poisoning the reference. codegen_->InvokeRuntime(instruction->GetEntrypoint(), instruction, instruction->GetDexPc()); @@ -4612,7 +4612,7 @@ void CodeGeneratorX86::RecordBootStringPatch(HLoadString* load_string) { } void CodeGeneratorX86::RecordTypePatch(HLoadClass* load_class) { - type_patches_.emplace_back(load_class->GetDexFile(), load_class->GetTypeIndex()); + type_patches_.emplace_back(load_class->GetDexFile(), load_class->GetTypeIndex().index_); __ Bind(&type_patches_.back().label); } @@ -6060,7 +6060,7 @@ void LocationsBuilderX86::VisitLoadClass(HLoadClass* cls) { void InstructionCodeGeneratorX86::VisitLoadClass(HLoadClass* cls) { LocationSummary* locations = cls->GetLocations(); if (cls->NeedsAccessCheck()) { - codegen_->MoveConstant(locations->GetTemp(0), cls->GetTypeIndex()); + codegen_->MoveConstant(locations->GetTemp(0), cls->GetTypeIndex().index_); codegen_->InvokeRuntime(kQuickInitializeTypeAndVerifyAccess, cls, cls->GetDexPc()); CheckEntrypointTypes<kQuickInitializeTypeAndVerifyAccess, void*, uint32_t>(); return; @@ -6142,7 +6142,8 @@ void InstructionCodeGeneratorX86::VisitLoadClass(HLoadClass* cls) { // /* GcRoot<mirror::Class> */ out = out[type_index] GenerateGcRootFieldLoad(cls, out_loc, - Address(out, CodeGenerator::GetCacheOffset(cls->GetTypeIndex())), + Address(out, + CodeGenerator::GetCacheOffset(cls->GetTypeIndex().index_)), /* fixup_label */ nullptr, read_barrier_option); generate_null_check = !cls->IsInDexCache(); diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc index 02f549151c..34673138bf 100644 --- a/compiler/optimizing/code_generator_x86_64.cc +++ b/compiler/optimizing/code_generator_x86_64.cc @@ -246,7 +246,8 @@ class LoadClassSlowPathX86_64 : public SlowPathCode { SaveLiveRegisters(codegen, locations); InvokeRuntimeCallingConvention calling_convention; - __ movl(CpuRegister(calling_convention.GetRegisterAt(0)), Immediate(cls_->GetTypeIndex())); + __ movl(CpuRegister(calling_convention.GetRegisterAt(0)), + Immediate(cls_->GetTypeIndex().index_)); x86_64_codegen->InvokeRuntime(do_clinit_ ? kQuickInitializeStaticStorage : kQuickInitializeType, at_, dex_pc_, @@ -1110,7 +1111,7 @@ void CodeGeneratorX86_64::RecordBootStringPatch(HLoadString* load_string) { } void CodeGeneratorX86_64::RecordTypePatch(HLoadClass* load_class) { - type_patches_.emplace_back(load_class->GetDexFile(), load_class->GetTypeIndex()); + type_patches_.emplace_back(load_class->GetDexFile(), load_class->GetTypeIndex().index_); __ Bind(&type_patches_.back().label); } @@ -4098,7 +4099,7 @@ void LocationsBuilderX86_64::VisitNewArray(HNewArray* instruction) { void InstructionCodeGeneratorX86_64::VisitNewArray(HNewArray* instruction) { InvokeRuntimeCallingConvention calling_convention; codegen_->Load64BitValue(CpuRegister(calling_convention.GetRegisterAt(0)), - instruction->GetTypeIndex()); + instruction->GetTypeIndex().index_); // Note: if heap poisoning is enabled, the entry point takes cares // of poisoning the reference. codegen_->InvokeRuntime(instruction->GetEntrypoint(), instruction, instruction->GetDexPc()); @@ -5485,7 +5486,7 @@ void LocationsBuilderX86_64::VisitLoadClass(HLoadClass* cls) { void InstructionCodeGeneratorX86_64::VisitLoadClass(HLoadClass* cls) { LocationSummary* locations = cls->GetLocations(); if (cls->NeedsAccessCheck()) { - codegen_->MoveConstant(locations->GetTemp(0), cls->GetTypeIndex()); + codegen_->MoveConstant(locations->GetTemp(0), cls->GetTypeIndex().index_); codegen_->InvokeRuntime(kQuickInitializeTypeAndVerifyAccess, cls, cls->GetDexPc()); CheckEntrypointTypes<kQuickInitializeTypeAndVerifyAccess, void*, uint32_t>(); return; @@ -5568,7 +5569,7 @@ void InstructionCodeGeneratorX86_64::VisitLoadClass(HLoadClass* cls) { GenerateGcRootFieldLoad( cls, out_loc, - Address(out, CodeGenerator::GetCacheOffset(cls->GetTypeIndex())), + Address(out, CodeGenerator::GetCacheOffset(cls->GetTypeIndex().index_)), /* fixup_label */ nullptr, read_barrier_option); generate_null_check = !cls->IsInDexCache(); diff --git a/compiler/optimizing/constant_folding_test.cc b/compiler/optimizing/constant_folding_test.cc index 5fac3acb8a..7ef28ed910 100644 --- a/compiler/optimizing/constant_folding_test.cc +++ b/compiler/optimizing/constant_folding_test.cc @@ -756,7 +756,7 @@ TEST_F(ConstantFoldingTest, UnsignedComparisonsWithZero) { // Make various unsigned comparisons with zero against a parameter. HInstruction* parameter = new (&allocator_) HParameterValue( - graph_->GetDexFile(), 0, 0, Primitive::kPrimInt, true); + graph_->GetDexFile(), dex::TypeIndex(0), 0, Primitive::kPrimInt, true); entry_block->AddInstruction(parameter); entry_block->AddInstruction(new (&allocator_) HGoto()); diff --git a/compiler/optimizing/gvn_test.cc b/compiler/optimizing/gvn_test.cc index 6abf00e21a..437d35ccb7 100644 --- a/compiler/optimizing/gvn_test.cc +++ b/compiler/optimizing/gvn_test.cc @@ -35,7 +35,7 @@ TEST_F(GVNTest, LocalFieldElimination) { graph->AddBlock(entry); graph->SetEntryBlock(entry); HInstruction* parameter = new (&allocator) HParameterValue(graph->GetDexFile(), - 0, + dex::TypeIndex(0), 0, Primitive::kPrimNot); entry->AddInstruction(parameter); @@ -120,7 +120,7 @@ TEST_F(GVNTest, GlobalFieldElimination) { graph->AddBlock(entry); graph->SetEntryBlock(entry); HInstruction* parameter = new (&allocator) HParameterValue(graph->GetDexFile(), - 0, + dex::TypeIndex(0), 0, Primitive::kPrimNot); entry->AddInstruction(parameter); @@ -204,7 +204,7 @@ TEST_F(GVNTest, LoopFieldElimination) { graph->SetEntryBlock(entry); HInstruction* parameter = new (&allocator) HParameterValue(graph->GetDexFile(), - 0, + dex::TypeIndex(0), 0, Primitive::kPrimNot); entry->AddInstruction(parameter); @@ -352,7 +352,7 @@ TEST_F(GVNTest, LoopSideEffects) { inner_loop_exit->AddSuccessor(outer_loop_header); HInstruction* parameter = new (&allocator) HParameterValue(graph->GetDexFile(), - 0, + dex::TypeIndex(0), 0, Primitive::kPrimBoolean); entry->AddInstruction(parameter); diff --git a/compiler/optimizing/induction_var_analysis_test.cc b/compiler/optimizing/induction_var_analysis_test.cc index 031f1d74a8..3425b88260 100644 --- a/compiler/optimizing/induction_var_analysis_test.cc +++ b/compiler/optimizing/induction_var_analysis_test.cc @@ -80,7 +80,7 @@ class InductionVarAnalysisTest : public CommonCompilerTest { // Provide entry and exit instructions. parameter_ = new (&allocator_) HParameterValue( - graph_->GetDexFile(), 0, 0, Primitive::kPrimNot, true); + graph_->GetDexFile(), dex::TypeIndex(0), 0, Primitive::kPrimNot, true); entry_->AddInstruction(parameter_); constant0_ = graph_->GetIntConstant(0); constant1_ = graph_->GetIntConstant(1); diff --git a/compiler/optimizing/induction_var_range_test.cc b/compiler/optimizing/induction_var_range_test.cc index 8bbdd4acb7..4c99e3cb6e 100644 --- a/compiler/optimizing/induction_var_range_test.cc +++ b/compiler/optimizing/induction_var_range_test.cc @@ -62,9 +62,15 @@ class InductionVarRangeTest : public CommonCompilerTest { graph_->SetEntryBlock(entry_block_); graph_->SetExitBlock(exit_block_); // Two parameters. - x_ = new (&allocator_) HParameterValue(graph_->GetDexFile(), 0, 0, Primitive::kPrimInt); + x_ = new (&allocator_) HParameterValue(graph_->GetDexFile(), + dex::TypeIndex(0), + 0, + Primitive::kPrimInt); entry_block_->AddInstruction(x_); - y_ = new (&allocator_) HParameterValue(graph_->GetDexFile(), 0, 0, Primitive::kPrimInt); + y_ = new (&allocator_) HParameterValue(graph_->GetDexFile(), + dex::TypeIndex(0), + 0, + Primitive::kPrimInt); entry_block_->AddInstruction(y_); // Set arbitrary range analysis hint while testing private methods. SetHint(x_); @@ -572,7 +578,8 @@ TEST_F(InductionVarRangeTest, ArrayLengthAndHints) { HInstruction* new_array = new (&allocator_) HNewArray(x_, graph_->GetCurrentMethod(), - 0, Primitive::kPrimInt, + 0, + dex::TypeIndex(Primitive::kPrimInt), graph_->GetDexFile(), kQuickAllocArray); entry_block_->AddInstruction(new_array); diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc index 7fe54b9045..16a465a43d 100644 --- a/compiler/optimizing/inliner.cc +++ b/compiler/optimizing/inliner.cc @@ -197,15 +197,15 @@ static uint32_t FindMethodIndexIn(ArtMethod* method, } } -static uint32_t FindClassIndexIn(mirror::Class* cls, - const DexFile& dex_file, - Handle<mirror::DexCache> dex_cache) +static dex::TypeIndex FindClassIndexIn(mirror::Class* cls, + const DexFile& dex_file, + Handle<mirror::DexCache> dex_cache) REQUIRES_SHARED(Locks::mutator_lock_) { - uint32_t index = DexFile::kDexNoIndex; + dex::TypeIndex index; if (cls->GetDexCache() == nullptr) { DCHECK(cls->IsArrayClass()) << cls->PrettyClass(); index = cls->FindTypeIndexInOtherDexFile(dex_file); - } else if (cls->GetDexTypeIndex() == DexFile::kDexNoIndex16) { + } else if (!cls->GetDexTypeIndex().IsValid()) { DCHECK(cls->IsProxyClass()) << cls->PrettyClass(); // TODO: deal with proxy classes. } else if (IsSameDexFile(cls->GetDexFile(), dex_file)) { @@ -223,8 +223,8 @@ static uint32_t FindClassIndexIn(mirror::Class* cls, // We cannot guarantee the entry in the dex cache will resolve to the same class, // as there may be different class loaders. So only return the index if it's // the right class in the dex cache already. - if (index != DexFile::kDexNoIndex && dex_cache->GetResolvedType(index) != cls) { - index = DexFile::kDexNoIndex; + if (index.IsValid() && dex_cache->GetResolvedType(index) != cls) { + index = dex::TypeIndex::Invalid(); } } @@ -363,9 +363,9 @@ bool HInliner::TryInlineMonomorphicCall(HInvoke* invoke_instruction, << invoke_instruction->DebugName(); const DexFile& caller_dex_file = *caller_compilation_unit_.GetDexFile(); - uint32_t class_index = FindClassIndexIn( + dex::TypeIndex class_index = FindClassIndexIn( ic.GetMonomorphicType(), caller_dex_file, caller_compilation_unit_.GetDexCache()); - if (class_index == DexFile::kDexNoIndex) { + if (!class_index.IsValid()) { VLOG(compiler) << "Call to " << ArtMethod::PrettyMethod(resolved_method) << " from inline cache is not inlined because its class is not" << " accessible to the caller"; @@ -417,7 +417,7 @@ bool HInliner::TryInlineMonomorphicCall(HInvoke* invoke_instruction, HInstruction* HInliner::AddTypeGuard(HInstruction* receiver, HInstruction* cursor, HBasicBlock* bb_cursor, - uint32_t class_index, + dex::TypeIndex class_index, bool is_referrer, HInstruction* invoke_instruction, bool with_deoptimization) { @@ -489,10 +489,10 @@ bool HInliner::TryInlinePolymorphicCall(HInvoke* invoke_instruction, HInstruction* cursor = invoke_instruction->GetPrevious(); HBasicBlock* bb_cursor = invoke_instruction->GetBlock(); - uint32_t class_index = FindClassIndexIn( + dex::TypeIndex class_index = FindClassIndexIn( ic.GetTypeAt(i), caller_dex_file, caller_compilation_unit_.GetDexCache()); HInstruction* return_replacement = nullptr; - if (class_index == DexFile::kDexNoIndex || + if (!class_index.IsValid() || !TryBuildAndInline(invoke_instruction, method, &return_replacement)) { all_targets_inlined = false; } else { diff --git a/compiler/optimizing/inliner.h b/compiler/optimizing/inliner.h index a1dcd58a84..682393e697 100644 --- a/compiler/optimizing/inliner.h +++ b/compiler/optimizing/inliner.h @@ -17,6 +17,7 @@ #ifndef ART_COMPILER_OPTIMIZING_INLINER_H_ #define ART_COMPILER_OPTIMIZING_INLINER_H_ +#include "dex_file_types.h" #include "invoke_type.h" #include "optimization.h" @@ -150,7 +151,7 @@ class HInliner : public HOptimization { HInstruction* AddTypeGuard(HInstruction* receiver, HInstruction* cursor, HBasicBlock* bb_cursor, - uint32_t class_index, + dex::TypeIndex class_index, bool is_referrer, HInstruction* invoke_instruction, bool with_deoptimization) diff --git a/compiler/optimizing/instruction_builder.cc b/compiler/optimizing/instruction_builder.cc index b44137d138..40de5ce0cc 100644 --- a/compiler/optimizing/instruction_builder.cc +++ b/compiler/optimizing/instruction_builder.cc @@ -908,7 +908,7 @@ bool HInstructionBuilder::BuildInvoke(const Instruction& instruction, false /* is_unresolved */); } -bool HInstructionBuilder::BuildNewInstance(uint16_t type_index, uint32_t dex_pc) { +bool HInstructionBuilder::BuildNewInstance(dex::TypeIndex type_index, uint32_t dex_pc) { ScopedObjectAccess soa(Thread::Current()); StackHandleScope<1> hs(soa.Self()); Handle<mirror::DexCache> dex_cache = dex_compilation_unit_->GetDexCache(); @@ -1004,7 +1004,7 @@ HClinitCheck* HInstructionBuilder::ProcessClinitCheckForInvoke( Handle<mirror::Class> resolved_method_class(hs.NewHandle(resolved_method->GetDeclaringClass())); // The index at which the method's class is stored in the DexCache's type array. - uint32_t storage_index = DexFile::kDexNoIndex; + dex::TypeIndex storage_index; bool is_outer_class = (resolved_method->GetDeclaringClass() == outer_class.Get()); if (is_outer_class) { storage_index = outer_class->GetDexTypeIndex(); @@ -1021,7 +1021,7 @@ HClinitCheck* HInstructionBuilder::ProcessClinitCheckForInvoke( if (IsInitialized(resolved_method_class)) { *clinit_check_requirement = HInvokeStaticOrDirect::ClinitCheckRequirement::kNone; - } else if (storage_index != DexFile::kDexNoIndex) { + } else if (storage_index.IsValid()) { *clinit_check_requirement = HInvokeStaticOrDirect::ClinitCheckRequirement::kExplicit; HLoadClass* load_class = new (arena_) HLoadClass( graph_->GetCurrentMethod(), @@ -1297,7 +1297,7 @@ mirror::Class* HInstructionBuilder::GetCompilingClass() const { return GetClassFrom(compiler_driver_, *dex_compilation_unit_); } -bool HInstructionBuilder::IsOutermostCompilingClass(uint16_t type_index) const { +bool HInstructionBuilder::IsOutermostCompilingClass(dex::TypeIndex type_index) const { ScopedObjectAccess soa(Thread::Current()); StackHandleScope<3> hs(soa.Self()); Handle<mirror::DexCache> dex_cache = dex_compilation_unit_->GetDexCache(); @@ -1360,7 +1360,7 @@ bool HInstructionBuilder::BuildStaticFieldAccess(const Instruction& instruction, Handle<mirror::Class> outer_class(hs.NewHandle(GetOutermostCompilingClass())); // The index at which the field's class is stored in the DexCache's type array. - uint32_t storage_index; + dex::TypeIndex storage_index; bool is_outer_class = (outer_class.Get() == resolved_field->GetDeclaringClass()); if (is_outer_class) { storage_index = outer_class->GetDexTypeIndex(); @@ -1497,7 +1497,7 @@ void HInstructionBuilder::BuildArrayAccess(const Instruction& instruction, } void HInstructionBuilder::BuildFilledNewArray(uint32_t dex_pc, - uint32_t type_index, + dex::TypeIndex type_index, uint32_t number_of_vreg_arguments, bool is_range, uint32_t* args, @@ -1644,7 +1644,7 @@ static TypeCheckKind ComputeTypeCheckKind(Handle<mirror::Class> cls) void HInstructionBuilder::BuildTypeCheck(const Instruction& instruction, uint8_t destination, uint8_t reference, - uint16_t type_index, + dex::TypeIndex type_index, uint32_t dex_pc) { ScopedObjectAccess soa(Thread::Current()); StackHandleScope<1> hs(soa.Self()); @@ -1684,14 +1684,14 @@ void HInstructionBuilder::BuildTypeCheck(const Instruction& instruction, } } -bool HInstructionBuilder::NeedsAccessCheck(uint32_t type_index, +bool HInstructionBuilder::NeedsAccessCheck(dex::TypeIndex type_index, Handle<mirror::DexCache> dex_cache, bool* finalizable) const { return !compiler_driver_->CanAccessInstantiableTypeWithoutChecks( dex_compilation_unit_->GetDexMethodIndex(), dex_cache, type_index, finalizable); } -bool HInstructionBuilder::NeedsAccessCheck(uint32_t type_index, bool* finalizable) const { +bool HInstructionBuilder::NeedsAccessCheck(dex::TypeIndex type_index, bool* finalizable) const { ScopedObjectAccess soa(Thread::Current()); Handle<mirror::DexCache> dex_cache = dex_compilation_unit_->GetDexCache(); return NeedsAccessCheck(type_index, dex_cache, finalizable); @@ -2449,7 +2449,7 @@ bool HInstructionBuilder::ProcessDexInstruction(const Instruction& instruction, } case Instruction::NEW_INSTANCE: { - if (!BuildNewInstance(instruction.VRegB_21c(), dex_pc)) { + if (!BuildNewInstance(dex::TypeIndex(instruction.VRegB_21c()), dex_pc)) { return false; } UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction()); @@ -2457,7 +2457,7 @@ bool HInstructionBuilder::ProcessDexInstruction(const Instruction& instruction, } case Instruction::NEW_ARRAY: { - uint16_t type_index = instruction.VRegC_22c(); + dex::TypeIndex type_index(instruction.VRegC_22c()); HInstruction* length = LoadLocal(instruction.VRegB_22c(), Primitive::kPrimInt); bool finalizable; QuickEntrypointEnum entrypoint = NeedsAccessCheck(type_index, &finalizable) @@ -2475,7 +2475,7 @@ bool HInstructionBuilder::ProcessDexInstruction(const Instruction& instruction, case Instruction::FILLED_NEW_ARRAY: { uint32_t number_of_vreg_arguments = instruction.VRegA_35c(); - uint32_t type_index = instruction.VRegB_35c(); + dex::TypeIndex type_index(instruction.VRegB_35c()); uint32_t args[5]; instruction.GetVarArgs(args); BuildFilledNewArray(dex_pc, type_index, number_of_vreg_arguments, false, args, 0); @@ -2484,7 +2484,7 @@ bool HInstructionBuilder::ProcessDexInstruction(const Instruction& instruction, case Instruction::FILLED_NEW_ARRAY_RANGE: { uint32_t number_of_vreg_arguments = instruction.VRegA_3rc(); - uint32_t type_index = instruction.VRegB_3rc(); + dex::TypeIndex type_index(instruction.VRegB_3rc()); uint32_t register_index = instruction.VRegC_3rc(); BuildFilledNewArray( dex_pc, type_index, number_of_vreg_arguments, true, nullptr, register_index); @@ -2641,7 +2641,7 @@ bool HInstructionBuilder::ProcessDexInstruction(const Instruction& instruction, } case Instruction::CONST_CLASS: { - uint16_t type_index = instruction.VRegB_21c(); + dex::TypeIndex type_index(instruction.VRegB_21c()); // `CanAccessTypeWithoutChecks` will tell whether the method being // built is trying to access its own class, so that the generated // code can optimize for this case. However, the optimization does not @@ -2682,14 +2682,14 @@ bool HInstructionBuilder::ProcessDexInstruction(const Instruction& instruction, case Instruction::INSTANCE_OF: { uint8_t destination = instruction.VRegA_22c(); uint8_t reference = instruction.VRegB_22c(); - uint16_t type_index = instruction.VRegC_22c(); + dex::TypeIndex type_index(instruction.VRegC_22c()); BuildTypeCheck(instruction, destination, reference, type_index, dex_pc); break; } case Instruction::CHECK_CAST: { uint8_t reference = instruction.VRegA_21c(); - uint16_t type_index = instruction.VRegB_21c(); + dex::TypeIndex type_index(instruction.VRegB_21c()); BuildTypeCheck(instruction, -1, reference, type_index, dex_pc); break; } diff --git a/compiler/optimizing/instruction_builder.h b/compiler/optimizing/instruction_builder.h index aa34ddd1d1..f29e522040 100644 --- a/compiler/optimizing/instruction_builder.h +++ b/compiler/optimizing/instruction_builder.h @@ -20,6 +20,7 @@ #include "base/arena_containers.h" #include "base/arena_object.h" #include "block_builder.h" +#include "dex_file_types.h" #include "driver/compiler_driver.h" #include "driver/compiler_driver-inl.h" #include "driver/dex_compilation_unit.h" @@ -100,11 +101,11 @@ class HInstructionBuilder : public ValueObject { // Returns whether the current method needs access check for the type. // Output parameter finalizable is set to whether the type is finalizable. - bool NeedsAccessCheck(uint32_t type_index, + bool NeedsAccessCheck(dex::TypeIndex type_index, Handle<mirror::DexCache> dex_cache, /*out*/bool* finalizable) const REQUIRES_SHARED(Locks::mutator_lock_); - bool NeedsAccessCheck(uint32_t type_index, /*out*/bool* finalizable) const; + bool NeedsAccessCheck(dex::TypeIndex type_index, /*out*/bool* finalizable) const; template<typename T> void Unop_12x(const Instruction& instruction, Primitive::Type type, uint32_t dex_pc); @@ -176,7 +177,7 @@ class HInstructionBuilder : public ValueObject { // Builds a new array node and the instructions that fill it. void BuildFilledNewArray(uint32_t dex_pc, - uint32_t type_index, + dex::TypeIndex type_index, uint32_t number_of_vreg_arguments, bool is_range, uint32_t* args, @@ -205,7 +206,7 @@ class HInstructionBuilder : public ValueObject { void BuildTypeCheck(const Instruction& instruction, uint8_t destination, uint8_t reference, - uint16_t type_index, + dex::TypeIndex type_index, uint32_t dex_pc); // Builds an instruction sequence for a switch statement. @@ -218,7 +219,7 @@ class HInstructionBuilder : public ValueObject { mirror::Class* GetCompilingClass() const; // Returns whether `type_index` points to the outer-most compiling method's class. - bool IsOutermostCompilingClass(uint16_t type_index) const; + bool IsOutermostCompilingClass(dex::TypeIndex type_index) const; void PotentiallySimplifyFakeString(uint16_t original_dex_register, uint32_t dex_pc, @@ -258,7 +259,7 @@ class HInstructionBuilder : public ValueObject { REQUIRES_SHARED(Locks::mutator_lock_); // Build a HNewInstance instruction. - bool BuildNewInstance(uint16_t type_index, uint32_t dex_pc); + bool BuildNewInstance(dex::TypeIndex type_index, uint32_t dex_pc); // Return whether the compiler can assume `cls` is initialized. bool IsInitialized(Handle<mirror::Class> cls) const diff --git a/compiler/optimizing/licm_test.cc b/compiler/optimizing/licm_test.cc index 2a62643465..8c34dc6a86 100644 --- a/compiler/optimizing/licm_test.cc +++ b/compiler/optimizing/licm_test.cc @@ -63,7 +63,10 @@ class LICMTest : public CommonCompilerTest { return_->AddSuccessor(exit_); // Provide boiler-plate instructions. - parameter_ = new (&allocator_) HParameterValue(graph_->GetDexFile(), 0, 0, Primitive::kPrimNot); + parameter_ = new (&allocator_) HParameterValue(graph_->GetDexFile(), + dex::TypeIndex(0), + 0, + Primitive::kPrimNot); entry_->AddInstruction(parameter_); int_constant_ = graph_->GetIntConstant(42); float_constant_ = graph_->GetFloatConstant(42.0f); diff --git a/compiler/optimizing/loop_optimization_test.cc b/compiler/optimizing/loop_optimization_test.cc index 7805a69a06..9a6b4935b2 100644 --- a/compiler/optimizing/loop_optimization_test.cc +++ b/compiler/optimizing/loop_optimization_test.cc @@ -48,7 +48,10 @@ class LoopOptimizationTest : public CommonCompilerTest { graph_->AddBlock(exit_block_); graph_->SetEntryBlock(entry_block_); graph_->SetExitBlock(exit_block_); - parameter_ = new (&allocator_) HParameterValue(graph_->GetDexFile(), 0, 0, Primitive::kPrimInt); + parameter_ = new (&allocator_) HParameterValue(graph_->GetDexFile(), + dex::TypeIndex(0), + 0, + Primitive::kPrimInt); entry_block_->AddInstruction(parameter_); return_block_->AddInstruction(new (&allocator_) HReturnVoid()); exit_block_->AddInstruction(new (&allocator_) HExit()); diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index 215ed54a4a..eebc49c991 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -29,6 +29,7 @@ #include "base/stl_util.h" #include "base/transform_array_ref.h" #include "dex_file.h" +#include "dex_file_types.h" #include "entrypoints/quick/quick_entrypoints_enum.h" #include "handle.h" #include "handle_scope.h" @@ -800,7 +801,7 @@ class TryCatchInformation : public ArenaObject<kArenaAllocTryCatchInfo> { } // Catch block information constructor. - TryCatchInformation(uint16_t catch_type_index, const DexFile& dex_file) + TryCatchInformation(dex::TypeIndex catch_type_index, const DexFile& dex_file) : try_entry_(nullptr), catch_dex_file_(&dex_file), catch_type_index_(catch_type_index) {} @@ -816,10 +817,10 @@ class TryCatchInformation : public ArenaObject<kArenaAllocTryCatchInfo> { bool IsCatchAllTypeIndex() const { DCHECK(IsCatchBlock()); - return catch_type_index_ == DexFile::kDexNoIndex16; + return !catch_type_index_.IsValid(); } - uint16_t GetCatchTypeIndex() const { + dex::TypeIndex GetCatchTypeIndex() const { DCHECK(IsCatchBlock()); return catch_type_index_; } @@ -836,7 +837,7 @@ class TryCatchInformation : public ArenaObject<kArenaAllocTryCatchInfo> { // Exception type information. Only set for catch blocks. const DexFile* catch_dex_file_; - const uint16_t catch_type_index_; + const dex::TypeIndex catch_type_index_; }; static constexpr size_t kNoLifetime = -1; @@ -3671,7 +3672,7 @@ class HNewInstance FINAL : public HExpression<2> { HNewInstance(HInstruction* cls, HCurrentMethod* current_method, uint32_t dex_pc, - uint16_t type_index, + dex::TypeIndex type_index, const DexFile& dex_file, bool needs_access_check, bool finalizable, @@ -3686,7 +3687,7 @@ class HNewInstance FINAL : public HExpression<2> { SetRawInputAt(1, current_method); } - uint16_t GetTypeIndex() const { return type_index_; } + dex::TypeIndex GetTypeIndex() const { return type_index_; } const DexFile& GetDexFile() const { return dex_file_; } // Calls runtime so needs an environment. @@ -3719,7 +3720,7 @@ class HNewInstance FINAL : public HExpression<2> { static_assert(kNumberOfNewInstancePackedBits <= kMaxNumberOfPackedBits, "Too many packed fields."); - const uint16_t type_index_; + const dex::TypeIndex type_index_; const DexFile& dex_file_; QuickEntrypointEnum entrypoint_; @@ -4265,7 +4266,7 @@ class HNewArray FINAL : public HExpression<2> { HNewArray(HInstruction* length, HCurrentMethod* current_method, uint32_t dex_pc, - uint16_t type_index, + dex::TypeIndex type_index, const DexFile& dex_file, QuickEntrypointEnum entrypoint) : HExpression(Primitive::kPrimNot, SideEffects::CanTriggerGC(), dex_pc), @@ -4276,7 +4277,7 @@ class HNewArray FINAL : public HExpression<2> { SetRawInputAt(1, current_method); } - uint16_t GetTypeIndex() const { return type_index_; } + dex::TypeIndex GetTypeIndex() const { return type_index_; } const DexFile& GetDexFile() const { return dex_file_; } // Calls runtime so needs an environment. @@ -4292,7 +4293,7 @@ class HNewArray FINAL : public HExpression<2> { DECLARE_INSTRUCTION(NewArray); private: - const uint16_t type_index_; + const dex::TypeIndex type_index_; const DexFile& dex_file_; const QuickEntrypointEnum entrypoint_; @@ -4829,7 +4830,7 @@ class HRor FINAL : public HBinaryOperation { class HParameterValue FINAL : public HExpression<0> { public: HParameterValue(const DexFile& dex_file, - uint16_t type_index, + dex::TypeIndex type_index, uint8_t index, Primitive::Type parameter_type, bool is_this = false) @@ -4842,7 +4843,7 @@ class HParameterValue FINAL : public HExpression<0> { } const DexFile& GetDexFile() const { return dex_file_; } - uint16_t GetTypeIndex() const { return type_index_; } + dex::TypeIndex GetTypeIndex() const { return type_index_; } uint8_t GetIndex() const { return index_; } bool IsThis() const { return GetPackedFlag<kFlagIsThis>(); } @@ -4860,7 +4861,7 @@ class HParameterValue FINAL : public HExpression<0> { "Too many packed fields."); const DexFile& dex_file_; - const uint16_t type_index_; + const dex::TypeIndex type_index_; // The index of this parameter in the parameters list. Must be less // than HGraph::number_of_in_vregs_. const uint8_t index_; @@ -5455,7 +5456,7 @@ class HLoadClass FINAL : public HInstruction { }; HLoadClass(HCurrentMethod* current_method, - uint16_t type_index, + dex::TypeIndex type_index, const DexFile& dex_file, bool is_referrers_class, uint32_t dex_pc, @@ -5487,7 +5488,7 @@ class HLoadClass FINAL : public HInstruction { void SetLoadKindWithTypeReference(LoadKind load_kind, const DexFile& dex_file, - uint32_t type_index) { + dex::TypeIndex type_index) { DCHECK(HasTypeReference(load_kind)); DCHECK(IsSameDexFile(dex_file_, dex_file)); DCHECK_EQ(type_index_, type_index); @@ -5511,7 +5512,7 @@ class HLoadClass FINAL : public HInstruction { bool InstructionDataEquals(const HInstruction* other) const; - size_t ComputeHashCode() const OVERRIDE { return type_index_; } + size_t ComputeHashCode() const OVERRIDE { return type_index_.index_; } bool CanBeNull() const OVERRIDE { return false; } @@ -5547,7 +5548,7 @@ class HLoadClass FINAL : public HInstruction { loaded_class_rti_ = rti; } - uint32_t GetTypeIndex() const { return type_index_; } + dex::TypeIndex GetTypeIndex() const { return type_index_; } const DexFile& GetDexFile() const { return dex_file_; } uint32_t GetDexCacheElementOffset() const; @@ -5630,7 +5631,7 @@ class HLoadClass FINAL : public HInstruction { // for PC-relative loads, i.e. kDexCachePcRelative or kBootImageLinkTimePcRelative. HUserRecord<HInstruction*> special_input_; - const uint16_t type_index_; + const dex::TypeIndex type_index_; const DexFile& dex_file_; union { diff --git a/compiler/optimizing/nodes_test.cc b/compiler/optimizing/nodes_test.cc index d4e2a58103..5d9a6528ca 100644 --- a/compiler/optimizing/nodes_test.cc +++ b/compiler/optimizing/nodes_test.cc @@ -35,7 +35,7 @@ TEST(Node, RemoveInstruction) { graph->AddBlock(entry); graph->SetEntryBlock(entry); HInstruction* parameter = new (&allocator) HParameterValue( - graph->GetDexFile(), 0, 0, Primitive::kPrimNot); + graph->GetDexFile(), dex::TypeIndex(0), 0, Primitive::kPrimNot); entry->AddInstruction(parameter); entry->AddInstruction(new (&allocator) HGoto()); @@ -78,9 +78,9 @@ TEST(Node, InsertInstruction) { graph->AddBlock(entry); graph->SetEntryBlock(entry); HInstruction* parameter1 = new (&allocator) HParameterValue( - graph->GetDexFile(), 0, 0, Primitive::kPrimNot); + graph->GetDexFile(), dex::TypeIndex(0), 0, Primitive::kPrimNot); HInstruction* parameter2 = new (&allocator) HParameterValue( - graph->GetDexFile(), 0, 0, Primitive::kPrimNot); + graph->GetDexFile(), dex::TypeIndex(0), 0, Primitive::kPrimNot); entry->AddInstruction(parameter1); entry->AddInstruction(parameter2); entry->AddInstruction(new (&allocator) HExit()); @@ -106,7 +106,7 @@ TEST(Node, AddInstruction) { graph->AddBlock(entry); graph->SetEntryBlock(entry); HInstruction* parameter = new (&allocator) HParameterValue( - graph->GetDexFile(), 0, 0, Primitive::kPrimNot); + graph->GetDexFile(), dex::TypeIndex(0), 0, Primitive::kPrimNot); entry->AddInstruction(parameter); ASSERT_FALSE(parameter->HasUses()); @@ -127,7 +127,7 @@ TEST(Node, ParentEnvironment) { graph->AddBlock(entry); graph->SetEntryBlock(entry); HInstruction* parameter1 = new (&allocator) HParameterValue( - graph->GetDexFile(), 0, 0, Primitive::kPrimNot); + graph->GetDexFile(), dex::TypeIndex(0), 0, Primitive::kPrimNot); HInstruction* with_environment = new (&allocator) HNullCheck(parameter1, 0); entry->AddInstruction(parameter1); entry->AddInstruction(with_environment); diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc index 85519c96e4..604d99c682 100644 --- a/compiler/optimizing/optimizing_compiler.cc +++ b/compiler/optimizing/optimizing_compiler.cc @@ -61,6 +61,7 @@ #include "debug/method_debug_info.h" #include "dex/verification_results.h" #include "dex/verified_method.h" +#include "dex_file_types.h" #include "driver/compiler_driver-inl.h" #include "driver/compiler_options.h" #include "driver/dex_compilation_unit.h" @@ -948,7 +949,7 @@ CodeGenerator* OptimizingCompiler::TryCompile(ArenaAllocator* arena, graph->SetArtMethod(method); ScopedObjectAccess soa(Thread::Current()); interpreter_metadata = method->GetQuickenedInfo(class_linker->GetImagePointerSize()); - uint16_t type_index = method->GetDeclaringClass()->GetDexTypeIndex(); + dex::TypeIndex type_index = method->GetDeclaringClass()->GetDexTypeIndex(); // Update the dex cache if the type is not in it yet. Note that under AOT, // the verifier must have set it, but under JIT, there's no guarantee, as we diff --git a/compiler/optimizing/prepare_for_register_allocation.cc b/compiler/optimizing/prepare_for_register_allocation.cc index 0db60882db..f9ac3a0f72 100644 --- a/compiler/optimizing/prepare_for_register_allocation.cc +++ b/compiler/optimizing/prepare_for_register_allocation.cc @@ -143,7 +143,7 @@ void PrepareForRegisterAllocation::VisitNewInstance(HNewInstance* instruction) { // - or the load class has only one use. if (instruction->IsFinalizable() || has_only_one_use || load_class->NeedsAccessCheck()) { instruction->SetEntrypoint(kQuickAllocObject); - instruction->ReplaceInput(GetGraph()->GetIntConstant(load_class->GetTypeIndex()), 0); + instruction->ReplaceInput(GetGraph()->GetIntConstant(load_class->GetTypeIndex().index_), 0); if (has_only_one_use) { // We've just removed the only use of the HLoadClass. Since we don't run DCE after this pass, // do it manually if possible. diff --git a/compiler/optimizing/reference_type_propagation.cc b/compiler/optimizing/reference_type_propagation.cc index d588deaace..c191c6651f 100644 --- a/compiler/optimizing/reference_type_propagation.cc +++ b/compiler/optimizing/reference_type_propagation.cc @@ -96,7 +96,7 @@ class ReferenceTypePropagation::RTPVisitor : public HGraphDelegateVisitor { void VisitBoundType(HBoundType* instr) OVERRIDE; void VisitNullCheck(HNullCheck* instr) OVERRIDE; void UpdateReferenceTypeInfo(HInstruction* instr, - uint16_t type_idx, + dex::TypeIndex type_idx, const DexFile& dex_file, bool is_exact); @@ -463,7 +463,7 @@ void ReferenceTypePropagation::RTPVisitor::SetClassAsTypeInfo(HInstruction* inst } void ReferenceTypePropagation::RTPVisitor::UpdateReferenceTypeInfo(HInstruction* instr, - uint16_t type_idx, + dex::TypeIndex type_idx, const DexFile& dex_file, bool is_exact) { DCHECK_EQ(instr->GetType(), Primitive::kPrimNot); @@ -484,7 +484,7 @@ void ReferenceTypePropagation::RTPVisitor::VisitNewArray(HNewArray* instr) { static mirror::Class* GetClassFromDexCache(Thread* self, const DexFile& dex_file, - uint16_t type_idx, + dex::TypeIndex type_idx, Handle<mirror::DexCache> hint_dex_cache) REQUIRES_SHARED(Locks::mutator_lock_) { mirror::DexCache* dex_cache = FindDexCacheWithHint(self, dex_file, hint_dex_cache); diff --git a/compiler/optimizing/register_allocator_test.cc b/compiler/optimizing/register_allocator_test.cc index 55ea99e592..559f40923b 100644 --- a/compiler/optimizing/register_allocator_test.cc +++ b/compiler/optimizing/register_allocator_test.cc @@ -20,6 +20,7 @@ #include "code_generator.h" #include "code_generator_x86.h" #include "dex_file.h" +#include "dex_file_types.h" #include "dex_instruction.h" #include "driver/compiler_options.h" #include "nodes.h" @@ -495,7 +496,7 @@ static HGraph* BuildIfElseWithPhi(ArenaAllocator* allocator, graph->AddBlock(entry); graph->SetEntryBlock(entry); HInstruction* parameter = new (allocator) HParameterValue( - graph->GetDexFile(), 0, 0, Primitive::kPrimNot); + graph->GetDexFile(), dex::TypeIndex(0), 0, Primitive::kPrimNot); entry->AddInstruction(parameter); HBasicBlock* block = new (allocator) HBasicBlock(graph); @@ -658,7 +659,7 @@ static HGraph* BuildFieldReturn(ArenaAllocator* allocator, graph->AddBlock(entry); graph->SetEntryBlock(entry); HInstruction* parameter = new (allocator) HParameterValue( - graph->GetDexFile(), 0, 0, Primitive::kPrimNot); + graph->GetDexFile(), dex::TypeIndex(0), 0, Primitive::kPrimNot); entry->AddInstruction(parameter); HBasicBlock* block = new (allocator) HBasicBlock(graph); @@ -742,7 +743,7 @@ static HGraph* BuildTwoSubs(ArenaAllocator* allocator, graph->AddBlock(entry); graph->SetEntryBlock(entry); HInstruction* parameter = new (allocator) HParameterValue( - graph->GetDexFile(), 0, 0, Primitive::kPrimInt); + graph->GetDexFile(), dex::TypeIndex(0), 0, Primitive::kPrimInt); entry->AddInstruction(parameter); HInstruction* constant1 = graph->GetIntConstant(1); @@ -821,9 +822,9 @@ static HGraph* BuildDiv(ArenaAllocator* allocator, graph->AddBlock(entry); graph->SetEntryBlock(entry); HInstruction* first = new (allocator) HParameterValue( - graph->GetDexFile(), 0, 0, Primitive::kPrimInt); + graph->GetDexFile(), dex::TypeIndex(0), 0, Primitive::kPrimInt); HInstruction* second = new (allocator) HParameterValue( - graph->GetDexFile(), 0, 0, Primitive::kPrimInt); + graph->GetDexFile(), dex::TypeIndex(0), 0, Primitive::kPrimInt); entry->AddInstruction(first); entry->AddInstruction(second); @@ -883,13 +884,13 @@ TEST_F(RegisterAllocatorTest, SpillInactive) { graph->AddBlock(entry); graph->SetEntryBlock(entry); HInstruction* one = new (&allocator) HParameterValue( - graph->GetDexFile(), 0, 0, Primitive::kPrimInt); + graph->GetDexFile(), dex::TypeIndex(0), 0, Primitive::kPrimInt); HInstruction* two = new (&allocator) HParameterValue( - graph->GetDexFile(), 0, 0, Primitive::kPrimInt); + graph->GetDexFile(), dex::TypeIndex(0), 0, Primitive::kPrimInt); HInstruction* three = new (&allocator) HParameterValue( - graph->GetDexFile(), 0, 0, Primitive::kPrimInt); + graph->GetDexFile(), dex::TypeIndex(0), 0, Primitive::kPrimInt); HInstruction* four = new (&allocator) HParameterValue( - graph->GetDexFile(), 0, 0, Primitive::kPrimInt); + graph->GetDexFile(), dex::TypeIndex(0), 0, Primitive::kPrimInt); entry->AddInstruction(one); entry->AddInstruction(two); entry->AddInstruction(three); diff --git a/compiler/optimizing/sharpening.cc b/compiler/optimizing/sharpening.cc index 15254edcab..a127708ab0 100644 --- a/compiler/optimizing/sharpening.cc +++ b/compiler/optimizing/sharpening.cc @@ -147,7 +147,7 @@ void HSharpening::ProcessLoadClass(HLoadClass* load_class) { DCHECK(!load_class->IsInBootImage()) << "HLoadClass should not be optimized before sharpening."; const DexFile& dex_file = load_class->GetDexFile(); - uint32_t type_index = load_class->GetTypeIndex(); + dex::TypeIndex type_index = load_class->GetTypeIndex(); bool is_in_dex_cache = false; bool is_in_boot_image = false; @@ -197,7 +197,7 @@ void HSharpening::ProcessLoadClass(HLoadClass* load_class) { // inlined frames are used correctly for OOM stack trace. // TODO: Write a test for this. Bug: 29416588 desired_load_kind = HLoadClass::LoadKind::kDexCacheAddress; - void* dex_cache_element_address = &dex_cache->GetResolvedTypes()[type_index]; + void* dex_cache_element_address = &dex_cache->GetResolvedTypes()[type_index.index_]; address = reinterpret_cast64<uint64_t>(dex_cache_element_address); } // AOT app compilation. Check if the class is in the boot image. diff --git a/compiler/utils/test_dex_file_builder_test.cc b/compiler/utils/test_dex_file_builder_test.cc index da4ac798c7..922f8b1dfa 100644 --- a/compiler/utils/test_dex_file_builder_test.cc +++ b/compiler/utils/test_dex_file_builder_test.cc @@ -62,7 +62,8 @@ TEST(TestDexFileBuilderTest, SimpleTest) { }; ASSERT_EQ(arraysize(expected_types), dex_file->NumTypeIds()); for (size_t i = 0; i != arraysize(expected_types); ++i) { - EXPECT_STREQ(expected_types[i], dex_file->GetTypeDescriptor(dex_file->GetTypeId(i))) << i; + EXPECT_STREQ(expected_types[i], + dex_file->GetTypeDescriptor(dex_file->GetTypeId(dex::TypeIndex(i)))) << i; } ASSERT_EQ(1u, dex_file->NumFieldIds()); diff --git a/compiler/utils/type_reference.h b/compiler/utils/type_reference.h index d0c1656836..a0fa1a4a63 100644 --- a/compiler/utils/type_reference.h +++ b/compiler/utils/type_reference.h @@ -20,6 +20,7 @@ #include <stdint.h> #include "base/logging.h" +#include "dex_file_types.h" #include "string_reference.h" namespace art { @@ -28,10 +29,10 @@ class DexFile; // A type is located by its DexFile and the string_ids_ table index into that DexFile. struct TypeReference { - TypeReference(const DexFile* file, uint32_t index) : dex_file(file), type_index(index) { } + TypeReference(const DexFile* file, dex::TypeIndex index) : dex_file(file), type_index(index) { } const DexFile* dex_file; - uint32_t type_index; + dex::TypeIndex type_index; }; // Compare the actual referenced type names. Used for type reference deduplication. diff --git a/compiler/verifier_deps_test.cc b/compiler/verifier_deps_test.cc index 6b690aab40..03d3f4e290 100644 --- a/compiler/verifier_deps_test.cc +++ b/compiler/verifier_deps_test.cc @@ -23,6 +23,7 @@ #include "compiler/driver/compiler_driver.h" #include "compiler_callbacks.h" #include "dex_file.h" +#include "dex_file_types.h" #include "handle_scope-inl.h" #include "verifier/method_verifier-inl.h" #include "mirror/class_loader.h" @@ -207,8 +208,8 @@ class VerifierDepsTest : public CommonCompilerTest { hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader_))); MutableHandle<mirror::Class> cls(hs.NewHandle<mirror::Class>(nullptr)); for (const DexFile* dex_file : dex_files_) { - const std::vector<uint16_t>& unverified_classes = deps.GetUnverifiedClasses(*dex_file); - std::set<uint16_t> set(unverified_classes.begin(), unverified_classes.end()); + const std::vector<dex::TypeIndex>& unverified_classes = deps.GetUnverifiedClasses(*dex_file); + std::set<dex::TypeIndex> set(unverified_classes.begin(), unverified_classes.end()); for (uint32_t i = 0; i < dex_file->NumClassDefs(); ++i) { const DexFile::ClassDef& class_def = dex_file->GetClassDef(i); const char* descriptor = dex_file->GetClassDescriptor(class_def); @@ -228,10 +229,10 @@ class VerifierDepsTest : public CommonCompilerTest { bool HasUnverifiedClass(const std::string& cls) { const DexFile::TypeId* type_id = primary_dex_file_->FindTypeId(cls.c_str()); DCHECK(type_id != nullptr); - uint16_t index = primary_dex_file_->GetIndexForTypeId(*type_id); + dex::TypeIndex index = primary_dex_file_->GetIndexForTypeId(*type_id); MutexLock mu(Thread::Current(), *Locks::verifier_deps_lock_); for (const auto& dex_dep : verifier_deps_->dex_deps_) { - for (uint16_t entry : dex_dep.second->unverified_classes_) { + for (dex::TypeIndex entry : dex_dep.second->unverified_classes_) { if (index == entry) { return true; } diff --git a/dexdump/dexdump.cc b/dexdump/dexdump.cc index 30de28eaee..03d6227ae2 100644 --- a/dexdump/dexdump.cc +++ b/dexdump/dexdump.cc @@ -45,6 +45,7 @@ #include "base/stringprintf.h" #include "dexdump_cfg.h" #include "dex_file-inl.h" +#include "dex_file_types.h" #include "dex_instruction-inl.h" namespace art { @@ -482,7 +483,7 @@ static void dumpEncodedValue(const DexFile* pDexFile, const u1** data, u1 type, } case DexFile::kDexAnnotationType: { const u4 str_idx = static_cast<u4>(readVarWidth(data, arg, false)); - fputs(pDexFile->StringByTypeIdx(str_idx), gOutFile); + fputs(pDexFile->StringByTypeIdx(dex::TypeIndex(str_idx)), gOutFile); break; } case DexFile::kDexAnnotationField: @@ -511,7 +512,7 @@ static void dumpEncodedValue(const DexFile* pDexFile, const u1** data, u1 type, } case DexFile::kDexAnnotationAnnotation: { const u4 type_idx = DecodeUnsignedLeb128(data); - fputs(pDexFile->StringByTypeIdx(type_idx), gOutFile); + fputs(pDexFile->StringByTypeIdx(dex::TypeIndex(type_idx)), gOutFile); // Decode and display all name=value pairs. const u4 size = DecodeUnsignedLeb128(data); for (u4 i = 0; i < size; i++) { @@ -592,10 +593,10 @@ static void dumpClassDef(const DexFile* pDexFile, int idx) { // General class information. const DexFile::ClassDef& pClassDef = pDexFile->GetClassDef(idx); fprintf(gOutFile, "Class #%d header:\n", idx); - fprintf(gOutFile, "class_idx : %d\n", pClassDef.class_idx_); + fprintf(gOutFile, "class_idx : %d\n", pClassDef.class_idx_.index_); fprintf(gOutFile, "access_flags : %d (0x%04x)\n", pClassDef.access_flags_, pClassDef.access_flags_); - fprintf(gOutFile, "superclass_idx : %d\n", pClassDef.superclass_idx_); + fprintf(gOutFile, "superclass_idx : %d\n", pClassDef.superclass_idx_.index_); fprintf(gOutFile, "interfaces_off : %d (0x%06x)\n", pClassDef.interfaces_off_, pClassDef.interfaces_off_); fprintf(gOutFile, "source_file_idx : %d\n", pClassDef.source_file_idx_); @@ -747,9 +748,8 @@ static void dumpCatches(const DexFile* pDexFile, const DexFile::CodeItem* pCode) const u4 end = start + pTry->insn_count_; fprintf(gOutFile, " 0x%04x - 0x%04x\n", start, end); for (CatchHandlerIterator it(*pCode, *pTry); it.HasNext(); it.Next()) { - const u2 tidx = it.GetHandlerTypeIndex(); - const char* descriptor = - (tidx == DexFile::kDexNoIndex16) ? "<any>" : pDexFile->StringByTypeIdx(tidx); + const dex::TypeIndex tidx = it.GetHandlerTypeIndex(); + const char* descriptor = (!tidx.IsValid()) ? "<any>" : pDexFile->StringByTypeIdx(tidx); fprintf(gOutFile, " %s -> 0x%04x\n", descriptor, it.GetHandlerAddress()); } // for } // for @@ -834,7 +834,7 @@ static std::unique_ptr<char[]> indexString(const DexFile* pDexFile, break; case Instruction::kIndexTypeRef: if (index < pDexFile->GetHeader().type_ids_size_) { - const char* tp = pDexFile->StringByTypeIdx(index); + const char* tp = pDexFile->StringByTypeIdx(dex::TypeIndex(index)); outSize = snprintf(buf.get(), bufSize, "%s // type@%0*x", tp, width, index); } else { outSize = snprintf(buf.get(), bufSize, "<type?> // type@%0*x", width, index); @@ -1461,7 +1461,7 @@ static void dumpClass(const DexFile* pDexFile, int idx, char** pLastPackage) { // General class information. char* accessStr = createAccessFlagStr(pClassDef.access_flags_, kAccessForClass); const char* superclassDescriptor; - if (pClassDef.superclass_idx_ == DexFile::kDexNoIndex16) { + if (!pClassDef.superclass_idx_.IsValid()) { superclassDescriptor = nullptr; } else { superclassDescriptor = pDexFile->StringByTypeIdx(pClassDef.superclass_idx_); diff --git a/dexlayout/dex_ir.cc b/dexlayout/dex_ir.cc index c3c763fee8..67f3e09567 100644 --- a/dexlayout/dex_ir.cc +++ b/dexlayout/dex_ir.cc @@ -319,7 +319,7 @@ void Collections::CreateStringId(const DexFile& dex_file, uint32_t i) { } void Collections::CreateTypeId(const DexFile& dex_file, uint32_t i) { - const DexFile::TypeId& disk_type_id = dex_file.GetTypeId(i); + const DexFile::TypeId& disk_type_id = dex_file.GetTypeId(dex::TypeIndex(i)); TypeId* type_id = new TypeId(GetStringId(disk_type_id.descriptor_idx_)); type_ids_.AddIndexedItem(type_id, TypeIdsOffset() + i * TypeId::ItemSize(), i); } @@ -330,22 +330,22 @@ void Collections::CreateProtoId(const DexFile& dex_file, uint32_t i) { TypeList* parameter_type_list = CreateTypeList(type_list, disk_proto_id.parameters_off_); ProtoId* proto_id = new ProtoId(GetStringId(disk_proto_id.shorty_idx_), - GetTypeId(disk_proto_id.return_type_idx_), + GetTypeId(disk_proto_id.return_type_idx_.index_), parameter_type_list); proto_ids_.AddIndexedItem(proto_id, ProtoIdsOffset() + i * ProtoId::ItemSize(), i); } void Collections::CreateFieldId(const DexFile& dex_file, uint32_t i) { const DexFile::FieldId& disk_field_id = dex_file.GetFieldId(i); - FieldId* field_id = new FieldId(GetTypeId(disk_field_id.class_idx_), - GetTypeId(disk_field_id.type_idx_), + FieldId* field_id = new FieldId(GetTypeId(disk_field_id.class_idx_.index_), + GetTypeId(disk_field_id.type_idx_.index_), GetStringId(disk_field_id.name_idx_)); field_ids_.AddIndexedItem(field_id, FieldIdsOffset() + i * FieldId::ItemSize(), i); } void Collections::CreateMethodId(const DexFile& dex_file, uint32_t i) { const DexFile::MethodId& disk_method_id = dex_file.GetMethodId(i); - MethodId* method_id = new MethodId(GetTypeId(disk_method_id.class_idx_), + MethodId* method_id = new MethodId(GetTypeId(disk_method_id.class_idx_.index_), GetProtoId(disk_method_id.proto_idx_), GetStringId(disk_method_id.name_idx_)); method_ids_.AddIndexedItem(method_id, MethodIdsOffset() + i * MethodId::ItemSize(), i); @@ -353,9 +353,9 @@ void Collections::CreateMethodId(const DexFile& dex_file, uint32_t i) { void Collections::CreateClassDef(const DexFile& dex_file, uint32_t i) { const DexFile::ClassDef& disk_class_def = dex_file.GetClassDef(i); - const TypeId* class_type = GetTypeId(disk_class_def.class_idx_); + const TypeId* class_type = GetTypeId(disk_class_def.class_idx_.index_); uint32_t access_flags = disk_class_def.access_flags_; - const TypeId* superclass = GetTypeIdOrNullPtr(disk_class_def.superclass_idx_); + const TypeId* superclass = GetTypeIdOrNullPtr(disk_class_def.superclass_idx_.index_); const DexFile::TypeList* type_list = dex_file.GetInterfacesList(disk_class_def); TypeList* interfaces_type_list = CreateTypeList(type_list, disk_class_def.interfaces_off_); @@ -393,7 +393,7 @@ TypeList* Collections::CreateTypeList(const DexFile::TypeList* dex_type_list, ui TypeIdVector* type_vector = new TypeIdVector(); uint32_t size = dex_type_list->Size(); for (uint32_t index = 0; index < size; ++index) { - type_vector->push_back(GetTypeId(dex_type_list->GetTypeItem(index).type_idx_)); + type_vector->push_back(GetTypeId(dex_type_list->GetTypeItem(index).type_idx_.index_)); } TypeList* new_type_list = new TypeList(type_vector); type_lists_.AddItem(new_type_list, offset); @@ -597,8 +597,8 @@ CodeItem* Collections::CreateCodeItem(const DexFile& dex_file, bool catch_all = false; TypeAddrPairVector* addr_pairs = new TypeAddrPairVector(); for (CatchHandlerIterator it(disk_code_item, *disk_try_item); it.HasNext(); it.Next()) { - const uint16_t type_index = it.GetHandlerTypeIndex(); - const TypeId* type_id = GetTypeIdOrNullPtr(type_index); + const dex::TypeIndex type_index = it.GetHandlerTypeIndex(); + const TypeId* type_id = GetTypeIdOrNullPtr(type_index.index_); catch_all |= type_id == nullptr; addr_pairs->push_back(std::unique_ptr<const TypeAddrPair>( new TypeAddrPair(type_id, it.GetHandlerAddress()))); diff --git a/dexlayout/dex_visualize.cc b/dexlayout/dex_visualize.cc index 7c556599ad..05ad98fe02 100644 --- a/dexlayout/dex_visualize.cc +++ b/dexlayout/dex_visualize.cc @@ -350,7 +350,7 @@ void VisualizeDexLayout(dex_ir::Header* header, const DexFile* dex_file, size_t const uint32_t class_defs_size = header->GetCollections().ClassDefsSize(); for (uint32_t class_index = 0; class_index < class_defs_size; class_index++) { dex_ir::ClassDef* class_def = header->GetCollections().GetClassDef(class_index); - uint16_t type_idx = class_def->ClassType()->GetIndex(); + dex::TypeIndex type_idx(class_def->ClassType()->GetIndex()); if (profile_info_ != nullptr && !profile_info_->ContainsClass(*dex_file, type_idx)) { continue; } diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc index 4c01c147c0..3ad0f1e8ce 100644 --- a/oatdump/oatdump.cc +++ b/oatdump/oatdump.cc @@ -794,7 +794,7 @@ class OatDumper { uint32_t oat_class_offset = oat_dex_file.GetOatClassOffset(class_def_index); const OatFile::OatClass oat_class = oat_dex_file.GetOatClass(class_def_index); os << StringPrintf("%zd: %s (offset=0x%08x) (type_idx=%d)", - class_def_index, descriptor, oat_class_offset, class_def.class_idx_) + class_def_index, descriptor, oat_class_offset, class_def.class_idx_.index_) << " (" << oat_class.GetStatus() << ")" << " (" << oat_class.GetType() << ")\n"; // TODO: include bitmap here if type is kOatClassSomeCompiled? diff --git a/profman/profile_assistant_test.cc b/profman/profile_assistant_test.cc index cd0aa6fd7d..776c31a662 100644 --- a/profman/profile_assistant_test.cc +++ b/profman/profile_assistant_test.cc @@ -42,7 +42,7 @@ class ProfileAssistantTest : public CommonRuntimeTest { ASSERT_TRUE(info->AddMethodIndex(dex_location2, dex_location_checksum2, i)); } for (uint16_t i = 0; i < number_of_classes; i++) { - ASSERT_TRUE(info->AddClassIndex(dex_location1, dex_location_checksum1, i)); + ASSERT_TRUE(info->AddClassIndex(dex_location1, dex_location_checksum1, dex::TypeIndex(i))); } ASSERT_TRUE(info->Save(GetFd(profile))); diff --git a/runtime/arch/stub_test.cc b/runtime/arch/stub_test.cc index bbf9a8b93c..6665897c9d 100644 --- a/runtime/arch/stub_test.cc +++ b/runtime/arch/stub_test.cc @@ -1063,7 +1063,7 @@ TEST_F(StubTest, AllocObject) { EXPECT_FALSE(self->IsExceptionPending()); { // Use an arbitrary method from c to use as referrer - size_t result = Invoke3(static_cast<size_t>(c->GetDexTypeIndex()), // type_idx + size_t result = Invoke3(static_cast<size_t>(c->GetDexTypeIndex().index_), // type_idx // arbitrary reinterpret_cast<size_t>(c->GetVirtualMethod(0, kRuntimePointerSize)), 0U, @@ -1197,7 +1197,7 @@ TEST_F(StubTest, AllocObjectArray) { if ((false)) { // Use an arbitrary method from c to use as referrer size_t result = Invoke3( - static_cast<size_t>(c->GetDexTypeIndex()), // type_idx + static_cast<size_t>(c->GetDexTypeIndex().index_), // type_idx 10U, // arbitrary reinterpret_cast<size_t>(c_obj->GetVirtualMethod(0, kRuntimePointerSize)), diff --git a/runtime/art_field.cc b/runtime/art_field.cc index b46b058b16..25b8ed295b 100644 --- a/runtime/art_field.cc +++ b/runtime/art_field.cc @@ -48,7 +48,7 @@ ObjPtr<mirror::Class> ArtField::ProxyFindSystemClass(const char* descriptor) { return Runtime::Current()->GetClassLinker()->FindSystemClass(Thread::Current(), descriptor); } -ObjPtr<mirror::Class> ArtField::ResolveGetType(uint32_t type_idx) { +ObjPtr<mirror::Class> ArtField::ResolveGetType(dex::TypeIndex type_idx) { return Runtime::Current()->GetClassLinker()->ResolveType(type_idx, this); } diff --git a/runtime/art_field.h b/runtime/art_field.h index 7c2f490706..cacb32450b 100644 --- a/runtime/art_field.h +++ b/runtime/art_field.h @@ -19,6 +19,7 @@ #include <jni.h> +#include "dex_file_types.h" #include "gc_root.h" #include "modifiers.h" #include "obj_ptr.h" @@ -216,7 +217,8 @@ class ArtField FINAL { private: ObjPtr<mirror::Class> ProxyFindSystemClass(const char* descriptor) REQUIRES_SHARED(Locks::mutator_lock_); - ObjPtr<mirror::Class> ResolveGetType(uint32_t type_idx) REQUIRES_SHARED(Locks::mutator_lock_); + ObjPtr<mirror::Class> ResolveGetType(dex::TypeIndex type_idx) + REQUIRES_SHARED(Locks::mutator_lock_); ObjPtr<mirror::String> ResolveGetStringName(Thread* self, const DexFile& dex_file, uint32_t string_idx, diff --git a/runtime/art_method-inl.h b/runtime/art_method-inl.h index a652178130..2dfdc16ac0 100644 --- a/runtime/art_method-inl.h +++ b/runtime/art_method-inl.h @@ -183,17 +183,17 @@ inline GcRoot<mirror::Class>* ArtMethod::GetDexCacheResolvedTypes(PointerSize po } template <bool kWithCheck> -inline mirror::Class* ArtMethod::GetDexCacheResolvedType(uint32_t type_index, +inline mirror::Class* ArtMethod::GetDexCacheResolvedType(dex::TypeIndex type_index, PointerSize pointer_size) { if (kWithCheck) { mirror::DexCache* dex_cache = GetInterfaceMethodIfProxy(pointer_size)->GetDeclaringClass()->GetDexCache(); - if (UNLIKELY(type_index >= dex_cache->NumResolvedTypes())) { - ThrowArrayIndexOutOfBoundsException(type_index, dex_cache->NumResolvedTypes()); + if (UNLIKELY(type_index.index_ >= dex_cache->NumResolvedTypes())) { + ThrowArrayIndexOutOfBoundsException(type_index.index_, dex_cache->NumResolvedTypes()); return nullptr; } } - mirror::Class* klass = GetDexCacheResolvedTypes(pointer_size)[type_index].Read(); + mirror::Class* klass = GetDexCacheResolvedTypes(pointer_size)[type_index.index_].Read(); return (klass != nullptr && !klass->IsErroneous()) ? klass : nullptr; } @@ -210,7 +210,7 @@ inline bool ArtMethod::HasSameDexCacheResolvedTypes(ArtMethod* other, PointerSiz return GetDexCacheResolvedTypes(pointer_size) == other->GetDexCacheResolvedTypes(pointer_size); } -inline mirror::Class* ArtMethod::GetClassFromTypeIndex(uint16_t type_idx, +inline mirror::Class* ArtMethod::GetClassFromTypeIndex(dex::TypeIndex type_idx, bool resolve, PointerSize pointer_size) { mirror::Class* type = GetDexCacheResolvedType(type_idx, pointer_size); @@ -336,7 +336,7 @@ inline const DexFile::CodeItem* ArtMethod::GetCodeItem() { return GetDeclaringClass()->GetDexFile().GetCodeItem(GetCodeItemOffset()); } -inline bool ArtMethod::IsResolvedTypeIdx(uint16_t type_idx, PointerSize pointer_size) { +inline bool ArtMethod::IsResolvedTypeIdx(dex::TypeIndex type_idx, PointerSize pointer_size) { DCHECK(!IsProxyMethod()); return GetDexCacheResolvedType(type_idx, pointer_size) != nullptr; } @@ -383,11 +383,10 @@ inline const char* ArtMethod::GetReturnTypeDescriptor() { const DexFile* dex_file = GetDexFile(); const DexFile::MethodId& method_id = dex_file->GetMethodId(GetDexMethodIndex()); const DexFile::ProtoId& proto_id = dex_file->GetMethodPrototype(method_id); - uint16_t return_type_idx = proto_id.return_type_idx_; - return dex_file->GetTypeDescriptor(dex_file->GetTypeId(return_type_idx)); + return dex_file->GetTypeDescriptor(dex_file->GetTypeId(proto_id.return_type_idx_)); } -inline const char* ArtMethod::GetTypeDescriptorFromTypeIdx(uint16_t type_idx) { +inline const char* ArtMethod::GetTypeDescriptorFromTypeIdx(dex::TypeIndex type_idx) { DCHECK(!IsProxyMethod()); const DexFile* dex_file = GetDexFile(); return dex_file->GetTypeDescriptor(dex_file->GetTypeId(type_idx)); @@ -440,7 +439,7 @@ inline mirror::Class* ArtMethod::GetReturnType(bool resolve, PointerSize pointer const DexFile* dex_file = GetDexFile(); const DexFile::MethodId& method_id = dex_file->GetMethodId(GetDexMethodIndex()); const DexFile::ProtoId& proto_id = dex_file->GetMethodPrototype(method_id); - uint16_t return_type_idx = proto_id.return_type_idx_; + dex::TypeIndex return_type_idx = proto_id.return_type_idx_; mirror::Class* type = GetDexCacheResolvedType(return_type_idx, pointer_size); if (type == nullptr && resolve) { type = Runtime::Current()->GetClassLinker()->ResolveType(return_type_idx, this); diff --git a/runtime/art_method.cc b/runtime/art_method.cc index c550a1b6bd..1c8376637c 100644 --- a/runtime/art_method.cc +++ b/runtime/art_method.cc @@ -199,9 +199,9 @@ uint32_t ArtMethod::FindCatchBlock(Handle<mirror::Class> exception_type, // Iterate over the catch handlers associated with dex_pc. PointerSize pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize(); for (CatchHandlerIterator it(*code_item, dex_pc); it.HasNext(); it.Next()) { - uint16_t iter_type_idx = it.GetHandlerTypeIndex(); + dex::TypeIndex iter_type_idx = it.GetHandlerTypeIndex(); // Catch all case - if (iter_type_idx == DexFile::kDexNoIndex16) { + if (!iter_type_idx.IsValid()) { found_dex_pc = it.GetHandlerAddress(); break; } diff --git a/runtime/art_method.h b/runtime/art_method.h index b31999f5b4..0e1d7e7303 100644 --- a/runtime/art_method.h +++ b/runtime/art_method.h @@ -343,7 +343,7 @@ class ArtMethod FINAL { REQUIRES_SHARED(Locks::mutator_lock_); template <bool kWithCheck = true> - mirror::Class* GetDexCacheResolvedType(uint32_t type_idx, PointerSize pointer_size) + mirror::Class* GetDexCacheResolvedType(dex::TypeIndex type_idx, PointerSize pointer_size) REQUIRES_SHARED(Locks::mutator_lock_); void SetDexCacheResolvedTypes(GcRoot<mirror::Class>* new_dex_cache_types, PointerSize pointer_size) @@ -355,7 +355,9 @@ class ArtMethod FINAL { REQUIRES_SHARED(Locks::mutator_lock_); // Get the Class* from the type index into this method's dex cache. - mirror::Class* GetClassFromTypeIndex(uint16_t type_idx, bool resolve, PointerSize pointer_size) + mirror::Class* GetClassFromTypeIndex(dex::TypeIndex type_idx, + bool resolve, + PointerSize pointer_size) REQUIRES_SHARED(Locks::mutator_lock_); // Returns true if this method has the same name and signature of the other method. @@ -527,7 +529,7 @@ class ArtMethod FINAL { const DexFile::CodeItem* GetCodeItem() REQUIRES_SHARED(Locks::mutator_lock_); - bool IsResolvedTypeIdx(uint16_t type_idx, PointerSize pointer_size) + bool IsResolvedTypeIdx(dex::TypeIndex type_idx, PointerSize pointer_size) REQUIRES_SHARED(Locks::mutator_lock_); int32_t GetLineNumFromDexPC(uint32_t dex_pc) REQUIRES_SHARED(Locks::mutator_lock_); @@ -544,7 +546,7 @@ class ArtMethod FINAL { const char* GetReturnTypeDescriptor() REQUIRES_SHARED(Locks::mutator_lock_); - const char* GetTypeDescriptorFromTypeIdx(uint16_t type_idx) + const char* GetTypeDescriptorFromTypeIdx(dex::TypeIndex type_idx) REQUIRES_SHARED(Locks::mutator_lock_); // May cause thread suspension due to GetClassFromTypeIdx calling ResolveType this caused a large diff --git a/runtime/class_linker-inl.h b/runtime/class_linker-inl.h index 7359243fc2..81adaeb00a 100644 --- a/runtime/class_linker-inl.h +++ b/runtime/class_linker-inl.h @@ -86,7 +86,7 @@ inline mirror::String* ClassLinker::ResolveString(uint32_t string_idx, ArtMethod return string.Ptr(); } -inline mirror::Class* ClassLinker::ResolveType(uint16_t type_idx, ArtMethod* referrer) { +inline mirror::Class* ClassLinker::ResolveType(dex::TypeIndex type_idx, ArtMethod* referrer) { Thread::PoisonObjectPointersIfDebug(); ObjPtr<mirror::Class> resolved_type = referrer->GetDexCacheResolvedType(type_idx, image_pointer_size_); @@ -103,7 +103,7 @@ inline mirror::Class* ClassLinker::ResolveType(uint16_t type_idx, ArtMethod* ref return resolved_type.Ptr(); } -inline mirror::Class* ClassLinker::ResolveType(uint16_t type_idx, ArtField* referrer) { +inline mirror::Class* ClassLinker::ResolveType(dex::TypeIndex type_idx, ArtField* referrer) { Thread::PoisonObjectPointersIfDebug(); ObjPtr<mirror::Class> declaring_class = referrer->GetDeclaringClass(); ObjPtr<mirror::DexCache> dex_cache_ptr = declaring_class->GetDexCache(); diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index 4905514221..f552a83192 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -730,10 +730,12 @@ bool ClassLinker::InitWithoutImage(std::vector<std::unique_ptr<const DexFile>> b const DexFile& dex_file = java_lang_Object->GetDexFile(); const DexFile::TypeId* void_type_id = dex_file.FindTypeId("V"); CHECK(void_type_id != nullptr); - uint16_t void_type_idx = dex_file.GetIndexForTypeId(*void_type_id); + dex::TypeIndex void_type_idx = dex_file.GetIndexForTypeId(*void_type_id); // Now we resolve void type so the dex cache contains it. We use java.lang.Object class // as referrer so the used dex cache is core's one. - ObjPtr<mirror::Class> resolved_type = ResolveType(dex_file, void_type_idx, java_lang_Object.Get()); + ObjPtr<mirror::Class> resolved_type = ResolveType(dex_file, + void_type_idx, + java_lang_Object.Get()); CHECK_EQ(resolved_type, GetClassRoot(kPrimitiveVoid)); self->AssertNoPendingException(); } @@ -4090,7 +4092,7 @@ void ClassLinker::ResolveMethodExceptionHandlerTypes(ArtMethod* method) { for (; iterator.HasNext(); iterator.Next()) { // Ensure exception types are resolved so that they don't need resolution to be delivered, // unresolved exception types will be ignored by exception delivery - if (iterator.GetHandlerTypeIndex() != DexFile::kDexNoIndex16) { + if (iterator.GetHandlerTypeIndex().IsValid()) { ObjPtr<mirror::Class> exception_type = ResolveType(iterator.GetHandlerTypeIndex(), method); if (exception_type == nullptr) { DCHECK(Thread::Current()->IsExceptionPending()); @@ -4756,7 +4758,7 @@ static void ThrowSignatureCheckResolveReturnTypeException(Handle<mirror::Class> const DexFile* dex_file = m->GetDexFile(); const DexFile::MethodId& method_id = dex_file->GetMethodId(m->GetDexMethodIndex()); const DexFile::ProtoId& proto_id = dex_file->GetMethodPrototype(method_id); - uint16_t return_type_idx = proto_id.return_type_idx_; + dex::TypeIndex return_type_idx = proto_id.return_type_idx_; std::string return_type = dex_file->PrettyType(return_type_idx); std::string class_loader = mirror::Object::PrettyTypeOf(m->GetDeclaringClass()->GetClassLoader()); ThrowWrappedLinkageError(klass.Get(), @@ -4774,7 +4776,7 @@ static void ThrowSignatureCheckResolveArgException(Handle<mirror::Class> klass, ArtMethod* method, ArtMethod* m, uint32_t index, - uint32_t arg_type_idx) + dex::TypeIndex arg_type_idx) REQUIRES_SHARED(Locks::mutator_lock_) { DCHECK(Thread::Current()->IsExceptionPending()); DCHECK(!m->IsProxyMethod()); @@ -4864,7 +4866,7 @@ static bool HasSameSignatureWithDifferentClassLoaders(Thread* self, } for (uint32_t i = 0; i < num_types; ++i) { StackHandleScope<1> hs(self); - uint32_t param_type_idx = types1->GetTypeItem(i).type_idx_; + dex::TypeIndex param_type_idx = types1->GetTypeItem(i).type_idx_; Handle<mirror::Class> param_type(hs.NewHandle( method1->GetClassFromTypeIndex(param_type_idx, true /* resolve */, pointer_size))); if (UNLIKELY(param_type.Get() == nullptr)) { @@ -4872,7 +4874,7 @@ static bool HasSameSignatureWithDifferentClassLoaders(Thread* self, method1, i, param_type_idx); return false; } - uint32_t other_param_type_idx = types2->GetTypeItem(i).type_idx_; + dex::TypeIndex other_param_type_idx = types2->GetTypeItem(i).type_idx_; ObjPtr<mirror::Class> other_param_type = method2->GetClassFromTypeIndex(other_param_type_idx, true /* resolve */, pointer_size); if (UNLIKELY(other_param_type == nullptr)) { @@ -5356,8 +5358,8 @@ static bool CheckSuperClassChange(Handle<mirror::Class> klass, bool ClassLinker::LoadSuperAndInterfaces(Handle<mirror::Class> klass, const DexFile& dex_file) { CHECK_EQ(mirror::Class::kStatusIdx, klass->GetStatus()); const DexFile::ClassDef& class_def = dex_file.GetClassDef(klass->GetDexClassDefIndex()); - uint16_t super_class_idx = class_def.superclass_idx_; - if (super_class_idx != DexFile::kDexNoIndex16) { + dex::TypeIndex super_class_idx = class_def.superclass_idx_; + if (super_class_idx.IsValid()) { // Check that a class does not inherit from itself directly. // // TODO: This is a cheap check to detect the straightforward case @@ -5394,7 +5396,7 @@ bool ClassLinker::LoadSuperAndInterfaces(Handle<mirror::Class> klass, const DexF const DexFile::TypeList* interfaces = dex_file.GetInterfacesList(class_def); if (interfaces != nullptr) { for (size_t i = 0; i < interfaces->Size(); i++) { - uint16_t idx = interfaces->GetTypeItem(i).type_idx_; + dex::TypeIndex idx = interfaces->GetTypeItem(i).type_idx_; ObjPtr<mirror::Class> interface = ResolveType(dex_file, idx, klass.Get()); if (interface == nullptr) { DCHECK(Thread::Current()->IsExceptionPending()); @@ -7510,7 +7512,7 @@ mirror::String* ClassLinker::LookupString(const DexFile& dex_file, } ObjPtr<mirror::Class> ClassLinker::LookupResolvedType(const DexFile& dex_file, - uint16_t type_idx, + dex::TypeIndex type_idx, ObjPtr<mirror::DexCache> dex_cache, ObjPtr<mirror::ClassLoader> class_loader) { ObjPtr<mirror::Class> type = dex_cache->GetResolvedType(type_idx); @@ -7536,7 +7538,7 @@ ObjPtr<mirror::Class> ClassLinker::LookupResolvedType(const DexFile& dex_file, } mirror::Class* ClassLinker::ResolveType(const DexFile& dex_file, - uint16_t type_idx, + dex::TypeIndex type_idx, ObjPtr<mirror::Class> referrer) { StackHandleScope<2> hs(Thread::Current()); Handle<mirror::DexCache> dex_cache(hs.NewHandle(referrer->GetDexCache())); @@ -7545,7 +7547,7 @@ mirror::Class* ClassLinker::ResolveType(const DexFile& dex_file, } mirror::Class* ClassLinker::ResolveType(const DexFile& dex_file, - uint16_t type_idx, + dex::TypeIndex type_idx, Handle<mirror::DexCache> dex_cache, Handle<mirror::ClassLoader> class_loader) { DCHECK(dex_cache.Get() != nullptr); @@ -7939,7 +7941,7 @@ mirror::MethodType* ClassLinker::ResolveMethodType(const DexFile& dex_file, int32_t i = 0; MutableHandle<mirror::Class> param_class = hs.NewHandle<mirror::Class>(nullptr); for (; it.HasNext(); it.Next()) { - const uint16_t type_idx = it.GetTypeIdx(); + const dex::TypeIndex type_idx = it.GetTypeIdx(); param_class.Assign(ResolveType(dex_file, type_idx, dex_cache, class_loader)); if (param_class.Get() == nullptr) { DCHECK(self->IsExceptionPending()); @@ -8350,10 +8352,10 @@ std::set<DexCacheResolvedClasses> ClassLinker::GetResolvedClasses(bool ignore_bo dex_file->GetBaseLocation(), dex_file->GetLocationChecksum()); size_t num_resolved = 0; - std::unordered_set<uint16_t> class_set; + std::unordered_set<dex::TypeIndex> class_set; CHECK_EQ(num_types, dex_cache->NumResolvedTypes()); for (size_t i = 0; i < num_types; ++i) { - ObjPtr<mirror::Class> klass = dex_cache->GetResolvedType(i); + ObjPtr<mirror::Class> klass = dex_cache->GetResolvedType(dex::TypeIndex(i)); // Filter out null class loader since that is the boot class loader. if (klass == nullptr || (ignore_boot_classes && klass->GetClassLoader() == nullptr)) { continue; @@ -8418,7 +8420,7 @@ std::unordered_set<std::string> ClassLinker::GetClassDescriptorsForProfileKeys( VLOG(profiler) << "Found opened dex file for " << dex_file->GetLocation() << " with " << info.GetClasses().size() << " classes"; DCHECK_EQ(dex_file->GetLocationChecksum(), info.GetLocationChecksum()); - for (uint16_t type_idx : info.GetClasses()) { + for (dex::TypeIndex type_idx : info.GetClasses()) { const DexFile::TypeId& type_id = dex_file->GetTypeId(type_idx); const char* descriptor = dex_file->GetTypeDescriptor(type_id); ret.insert(descriptor); diff --git a/runtime/class_linker.h b/runtime/class_linker.h index 1d29e319d5..95634484fc 100644 --- a/runtime/class_linker.h +++ b/runtime/class_linker.h @@ -32,6 +32,7 @@ #include "class_table.h" #include "dex_cache_resolved_classes.h" #include "dex_file.h" +#include "dex_file_types.h" #include "gc_root.h" #include "jni.h" #include "mirror/class.h" @@ -255,7 +256,7 @@ class ClassLinker { // result in the DexCache. The referrer is used to identify the // target DexCache and ClassLoader to use for resolution. mirror::Class* ResolveType(const DexFile& dex_file, - uint16_t type_idx, + dex::TypeIndex type_idx, ObjPtr<mirror::Class> referrer) REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!dex_lock_, !Roles::uninterruptible_); @@ -263,18 +264,18 @@ class ClassLinker { // Resolve a Type with the given index from the DexFile, storing the // result in the DexCache. The referrer is used to identify the // target DexCache and ClassLoader to use for resolution. - mirror::Class* ResolveType(uint16_t type_idx, ArtMethod* referrer) + mirror::Class* ResolveType(dex::TypeIndex type_idx, ArtMethod* referrer) REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!dex_lock_, !Roles::uninterruptible_); - mirror::Class* ResolveType(uint16_t type_idx, ArtField* referrer) + mirror::Class* ResolveType(dex::TypeIndex type_idx, ArtField* referrer) REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!dex_lock_, !Roles::uninterruptible_); // Look up a resolved type with the given ID from the DexFile. The ClassLoader is used to search // for the type, since it may be referenced from but not contained within the given DexFile. ObjPtr<mirror::Class> LookupResolvedType(const DexFile& dex_file, - uint16_t type_idx, + dex::TypeIndex type_idx, ObjPtr<mirror::DexCache> dex_cache, ObjPtr<mirror::ClassLoader> class_loader) REQUIRES_SHARED(Locks::mutator_lock_); @@ -284,7 +285,7 @@ class ClassLinker { // type, since it may be referenced from but not contained within // the given DexFile. mirror::Class* ResolveType(const DexFile& dex_file, - uint16_t type_idx, + dex::TypeIndex type_idx, Handle<mirror::DexCache> dex_cache, Handle<mirror::ClassLoader> class_loader) REQUIRES_SHARED(Locks::mutator_lock_) diff --git a/runtime/class_linker_test.cc b/runtime/class_linker_test.cc index 44590ba327..9e17be2518 100644 --- a/runtime/class_linker_test.cc +++ b/runtime/class_linker_test.cc @@ -25,6 +25,7 @@ #include "class_linker-inl.h" #include "common_runtime_test.h" #include "dex_file.h" +#include "dex_file_types.h" #include "experimental_flags.h" #include "entrypoints/entrypoint_utils-inl.h" #include "gc/heap.h" @@ -429,7 +430,7 @@ class ClassLinkerTest : public CommonRuntimeTest { } // Verify all the types referenced by this file for (size_t i = 0; i < dex.NumTypeIds(); i++) { - const DexFile::TypeId& type_id = dex.GetTypeId(i); + const DexFile::TypeId& type_id = dex.GetTypeId(dex::TypeIndex(i)); const char* descriptor = dex.GetTypeDescriptor(type_id); AssertDexFileClass(class_loader, descriptor); } @@ -891,7 +892,7 @@ TEST_F(ClassLinkerTest, LookupResolvedType) { hs.NewHandle(soa.Decode<mirror::ClassLoader>(LoadDex("MyClass")))); AssertNonExistentClass("LMyClass;"); ObjPtr<mirror::Class> klass = class_linker_->FindClass(soa.Self(), "LMyClass;", class_loader); - uint32_t type_idx = klass->GetClassDef()->class_idx_; + dex::TypeIndex type_idx = klass->GetClassDef()->class_idx_; ObjPtr<mirror::DexCache> dex_cache = klass->GetDexCache(); const DexFile& dex_file = klass->GetDexFile(); EXPECT_OBJ_PTR_EQ(dex_cache->GetResolvedType(type_idx), klass); @@ -1154,7 +1155,7 @@ TEST_F(ClassLinkerTest, ResolveVerifyAndClinit) { ArtMethod* getS0 = klass->FindDirectMethod("getS0", "()Ljava/lang/Object;", kRuntimePointerSize); const DexFile::TypeId* type_id = dex_file->FindTypeId("LStaticsFromCode;"); ASSERT_TRUE(type_id != nullptr); - uint32_t type_idx = dex_file->GetIndexForTypeId(*type_id); + dex::TypeIndex type_idx = dex_file->GetIndexForTypeId(*type_id); mirror::Class* uninit = ResolveVerifyAndClinit(type_idx, clinit, soa.Self(), true, false); EXPECT_TRUE(uninit != nullptr); EXPECT_FALSE(uninit->IsInitialized()); diff --git a/runtime/dex_cache_resolved_classes.h b/runtime/dex_cache_resolved_classes.h index 0febbedf03..f53ca4acb6 100644 --- a/runtime/dex_cache_resolved_classes.h +++ b/runtime/dex_cache_resolved_classes.h @@ -21,6 +21,8 @@ #include <unordered_set> #include <vector> +#include "dex_file_types.h" + namespace art { // Data structure for passing around which classes belonging to a dex cache / dex file are resolved. @@ -59,7 +61,7 @@ class DexCacheResolvedClasses { return location_checksum_; } - const std::unordered_set<uint16_t>& GetClasses() const { + const std::unordered_set<dex::TypeIndex>& GetClasses() const { return classes_; } @@ -68,7 +70,7 @@ class DexCacheResolvedClasses { const std::string base_location_; const uint32_t location_checksum_; // Array of resolved class def indexes. - mutable std::unordered_set<uint16_t> classes_; + mutable std::unordered_set<dex::TypeIndex> classes_; }; inline bool operator<(const DexCacheResolvedClasses& a, const DexCacheResolvedClasses& b) { diff --git a/runtime/dex_file-inl.h b/runtime/dex_file-inl.h index 621b2c5f21..77a63c11ed 100644 --- a/runtime/dex_file-inl.h +++ b/runtime/dex_file-inl.h @@ -58,12 +58,12 @@ inline const char* DexFile::StringDataByIdx(uint32_t idx) const { return StringDataAndUtf16LengthByIdx(idx, &unicode_length); } -inline const char* DexFile::StringByTypeIdx(uint32_t idx, uint32_t* unicode_length) const { +inline const char* DexFile::StringByTypeIdx(dex::TypeIndex idx, uint32_t* unicode_length) const { const TypeId& type_id = GetTypeId(idx); return StringDataAndUtf16LengthByIdx(type_id.descriptor_idx_, unicode_length); } -inline const char* DexFile::StringByTypeIdx(uint32_t idx) const { +inline const char* DexFile::StringByTypeIdx(dex::TypeIndex idx) const { const TypeId& type_id = GetTypeId(idx); return StringDataByIdx(type_id.descriptor_idx_); } diff --git a/runtime/dex_file.cc b/runtime/dex_file.cc index 2ef7509b68..cc544fd51c 100644 --- a/runtime/dex_file.cc +++ b/runtime/dex_file.cc @@ -26,6 +26,7 @@ #include <memory> #include <sstream> +#include <type_traits> #include "base/enums.h" #include "base/file_magic.h" @@ -44,6 +45,9 @@ namespace art { +static_assert(sizeof(dex::TypeIndex) == sizeof(uint16_t), "TypeIndex size is wrong"); +static_assert(std::is_trivially_copyable<dex::TypeIndex>::value, "TypeIndex not trivial"); + static constexpr OatDexFile* kNoOatDexFile = nullptr; const char* DexFile::kClassesDex = "classes.dex"; @@ -550,7 +554,7 @@ uint32_t DexFile::Header::GetVersion() const { return atoi(version); } -const DexFile::ClassDef* DexFile::FindClassDef(uint16_t type_idx) const { +const DexFile::ClassDef* DexFile::FindClassDef(dex::TypeIndex type_idx) const { size_t num_class_defs = NumClassDefs(); // Fast path for rare no class defs case. if (num_class_defs == 0) { @@ -597,9 +601,9 @@ const DexFile::FieldId* DexFile::FindFieldId(const DexFile::TypeId& declaring_kl const DexFile::StringId& name, const DexFile::TypeId& type) const { // Binary search MethodIds knowing that they are sorted by class_idx, name_idx then proto_idx - const uint16_t class_idx = GetIndexForTypeId(declaring_klass); + const dex::TypeIndex class_idx = GetIndexForTypeId(declaring_klass); const uint32_t name_idx = GetIndexForStringId(name); - const uint16_t type_idx = GetIndexForTypeId(type); + const dex::TypeIndex type_idx = GetIndexForTypeId(type); int32_t lo = 0; int32_t hi = NumFieldIds() - 1; while (hi >= lo) { @@ -632,7 +636,7 @@ const DexFile::MethodId* DexFile::FindMethodId(const DexFile::TypeId& declaring_ const DexFile::StringId& name, const DexFile::ProtoId& signature) const { // Binary search MethodIds knowing that they are sorted by class_idx, name_idx then proto_idx - const uint16_t class_idx = GetIndexForTypeId(declaring_klass); + const dex::TypeIndex class_idx = GetIndexForTypeId(declaring_klass); const uint32_t name_idx = GetIndexForStringId(name); const uint16_t proto_idx = GetIndexForProtoId(signature); int32_t lo = 0; @@ -687,7 +691,7 @@ const DexFile::TypeId* DexFile::FindTypeId(const char* string) const { int32_t hi = NumTypeIds() - 1; while (hi >= lo) { int32_t mid = (hi + lo) / 2; - const TypeId& type_id = GetTypeId(mid); + const TypeId& type_id = GetTypeId(dex::TypeIndex(mid)); const DexFile::StringId& str_id = GetStringId(type_id.descriptor_idx_); const char* str = GetStringData(str_id); int compare = CompareModifiedUtf8ToModifiedUtf8AsUtf16CodePointValues(string, str); @@ -726,7 +730,7 @@ const DexFile::TypeId* DexFile::FindTypeId(uint32_t string_idx) const { int32_t hi = NumTypeIds() - 1; while (hi >= lo) { int32_t mid = (hi + lo) / 2; - const TypeId& type_id = GetTypeId(mid); + const TypeId& type_id = GetTypeId(dex::TypeIndex(mid)); if (string_idx > type_id.descriptor_idx_) { lo = mid + 1; } else if (string_idx < type_id.descriptor_idx_) { @@ -738,20 +742,20 @@ const DexFile::TypeId* DexFile::FindTypeId(uint32_t string_idx) const { return nullptr; } -const DexFile::ProtoId* DexFile::FindProtoId(uint16_t return_type_idx, - const uint16_t* signature_type_idxs, +const DexFile::ProtoId* DexFile::FindProtoId(dex::TypeIndex return_type_idx, + const dex::TypeIndex* signature_type_idxs, uint32_t signature_length) const { int32_t lo = 0; int32_t hi = NumProtoIds() - 1; while (hi >= lo) { int32_t mid = (hi + lo) / 2; const DexFile::ProtoId& proto = GetProtoId(mid); - int compare = return_type_idx - proto.return_type_idx_; + int compare = return_type_idx.index_ - proto.return_type_idx_.index_; if (compare == 0) { DexFileParameterIterator it(*this, proto); size_t i = 0; while (it.HasNext() && i < signature_length && compare == 0) { - compare = signature_type_idxs[i] - it.GetTypeIdx(); + compare = signature_type_idxs[i].index_ - it.GetTypeIdx().index_; it.Next(); i++; } @@ -775,8 +779,9 @@ const DexFile::ProtoId* DexFile::FindProtoId(uint16_t return_type_idx, } // Given a signature place the type ids into the given vector -bool DexFile::CreateTypeList(const StringPiece& signature, uint16_t* return_type_idx, - std::vector<uint16_t>* param_type_idxs) const { +bool DexFile::CreateTypeList(const StringPiece& signature, + dex::TypeIndex* return_type_idx, + std::vector<dex::TypeIndex>* param_type_idxs) const { if (signature[0] != '(') { return false; } @@ -813,7 +818,7 @@ bool DexFile::CreateTypeList(const StringPiece& signature, uint16_t* return_type if (type_id == nullptr) { return false; } - uint16_t type_idx = GetIndexForTypeId(*type_id); + dex::TypeIndex type_idx = GetIndexForTypeId(*type_id); if (!process_return) { param_type_idxs->push_back(type_idx); } else { @@ -825,8 +830,8 @@ bool DexFile::CreateTypeList(const StringPiece& signature, uint16_t* return_type } const Signature DexFile::CreateSignature(const StringPiece& signature) const { - uint16_t return_type_idx; - std::vector<uint16_t> param_type_indices; + dex::TypeIndex return_type_idx; + std::vector<dex::TypeIndex> param_type_indices; bool success = CreateTypeList(signature, &return_type_idx, ¶m_type_indices); if (!success) { return Signature::NoSignature(); @@ -971,7 +976,8 @@ bool DexFile::DecodeDebugLocalInfo(const CodeItem* code_item, bool is_static, ui } local_in_reg[reg].name_ = StringDataByIdx(name_idx); - local_in_reg[reg].descriptor_ = StringByTypeIdx(descriptor_idx); + local_in_reg[reg].descriptor_ = + StringByTypeIdx(dex::TypeIndex(dchecked_integral_cast<uint16_t>(descriptor_idx)));; local_in_reg[reg].signature_ = StringDataByIdx(signature_idx); local_in_reg[reg].start_address_ = address; local_in_reg[reg].reg_ = reg; @@ -1225,9 +1231,9 @@ std::string DexFile::PrettyField(uint32_t field_idx, bool with_type) const { return result; } -std::string DexFile::PrettyType(uint32_t type_idx) const { - if (type_idx >= NumTypeIds()) { - return StringPrintf("<<invalid-type-idx-%d>>", type_idx); +std::string DexFile::PrettyType(dex::TypeIndex type_idx) const { + if (type_idx.index_ >= NumTypeIds()) { + return StringPrintf("<<invalid-type-idx-%d>>", type_idx.index_); } const DexFile::TypeId& type_id = GetTypeId(type_idx); return PrettyDescriptor(GetTypeDescriptor(type_id)); @@ -1457,14 +1463,14 @@ void CatchHandlerIterator::Init(const uint8_t* handler_data) { void CatchHandlerIterator::Next() { if (remaining_count_ > 0) { - handler_.type_idx_ = DecodeUnsignedLeb128(¤t_data_); + handler_.type_idx_ = dex::TypeIndex(DecodeUnsignedLeb128(¤t_data_)); handler_.address_ = DecodeUnsignedLeb128(¤t_data_); remaining_count_--; return; } if (catch_all_) { - handler_.type_idx_ = DexFile::kDexNoIndex16; + handler_.type_idx_ = dex::TypeIndex(DexFile::kDexNoIndex16); handler_.address_ = DecodeUnsignedLeb128(¤t_data_); catch_all_ = false; return; @@ -1474,4 +1480,13 @@ void CatchHandlerIterator::Next() { remaining_count_ = -1; } +namespace dex { + +std::ostream& operator<<(std::ostream& os, const TypeIndex& index) { + os << "TypeIndex[" << index.index_ << "]"; + return os; +} + +} // namespace dex + } // namespace art diff --git a/runtime/dex_file.h b/runtime/dex_file.h index da9fa505f2..0a2b48bea9 100644 --- a/runtime/dex_file.h +++ b/runtime/dex_file.h @@ -23,6 +23,7 @@ #include "base/logging.h" #include "base/value_object.h" +#include "dex_file_types.h" #include "globals.h" #include "invoke_type.h" #include "jni.h" @@ -159,17 +160,28 @@ class DexFile { // Raw field_id_item. struct FieldId { - uint16_t class_idx_; // index into type_ids_ array for defining class - uint16_t type_idx_; // index into type_ids_ array for field type + dex::TypeIndex class_idx_; // index into type_ids_ array for defining class + dex::TypeIndex type_idx_; // index into type_ids_ array for field type uint32_t name_idx_; // index into string_ids_ array for field name private: DISALLOW_COPY_AND_ASSIGN(FieldId); }; + // Raw proto_id_item. + struct ProtoId { + uint32_t shorty_idx_; // index into string_ids array for shorty descriptor + dex::TypeIndex return_type_idx_; // index into type_ids array for return type + uint16_t pad_; // padding = 0 + uint32_t parameters_off_; // file offset to type_list for parameter types + + private: + DISALLOW_COPY_AND_ASSIGN(ProtoId); + }; + // Raw method_id_item. struct MethodId { - uint16_t class_idx_; // index into type_ids_ array for defining class + dex::TypeIndex class_idx_; // index into type_ids_ array for defining class uint16_t proto_idx_; // index into proto_ids_ array for method prototype uint32_t name_idx_; // index into string_ids_ array for method name @@ -177,23 +189,12 @@ class DexFile { DISALLOW_COPY_AND_ASSIGN(MethodId); }; - // Raw proto_id_item. - struct ProtoId { - uint32_t shorty_idx_; // index into string_ids array for shorty descriptor - uint16_t return_type_idx_; // index into type_ids array for return type - uint16_t pad_; // padding = 0 - uint32_t parameters_off_; // file offset to type_list for parameter types - - private: - DISALLOW_COPY_AND_ASSIGN(ProtoId); - }; - // Raw class_def_item. struct ClassDef { - uint16_t class_idx_; // index into type_ids_ array for this class + dex::TypeIndex class_idx_; // index into type_ids_ array for this class uint16_t pad1_; // padding = 0 uint32_t access_flags_; - uint16_t superclass_idx_; // index into type_ids_ array for superclass + dex::TypeIndex superclass_idx_; // index into type_ids_ array for superclass uint16_t pad2_; // padding = 0 uint32_t interfaces_off_; // file offset to TypeList uint32_t source_file_idx_; // index into string_ids_ for source file name @@ -225,7 +226,7 @@ class DexFile { // Raw type_item. struct TypeItem { - uint16_t type_idx_; // index into type_ids section + dex::TypeIndex type_idx_; // index into type_ids section private: DISALLOW_COPY_AND_ASSIGN(TypeItem); @@ -540,23 +541,23 @@ class DexFile { } // Returns the TypeId at the specified index. - const TypeId& GetTypeId(uint32_t idx) const { - DCHECK_LT(idx, NumTypeIds()) << GetLocation(); - return type_ids_[idx]; + const TypeId& GetTypeId(dex::TypeIndex idx) const { + DCHECK_LT(idx.index_, NumTypeIds()) << GetLocation(); + return type_ids_[idx.index_]; } - uint16_t GetIndexForTypeId(const TypeId& type_id) const { + dex::TypeIndex GetIndexForTypeId(const TypeId& type_id) const { CHECK_GE(&type_id, type_ids_) << GetLocation(); CHECK_LT(&type_id, type_ids_ + header_->type_ids_size_) << GetLocation(); size_t result = &type_id - type_ids_; DCHECK_LT(result, 65536U) << GetLocation(); - return static_cast<uint16_t>(result); + return dex::TypeIndex(static_cast<uint16_t>(result)); } // Get the descriptor string associated with a given type index. - const char* StringByTypeIdx(uint32_t idx, uint32_t* unicode_length) const; + const char* StringByTypeIdx(dex::TypeIndex idx, uint32_t* unicode_length) const; - const char* StringByTypeIdx(uint32_t idx) const; + const char* StringByTypeIdx(dex::TypeIndex idx) const; // Returns the type descriptor string of a type id. const char* GetTypeDescriptor(const TypeId& type_id) const; @@ -671,7 +672,7 @@ class DexFile { const char* GetClassDescriptor(const ClassDef& class_def) const; // Looks up a class definition by its type index. - const ClassDef* FindClassDef(uint16_t type_idx) const; + const ClassDef* FindClassDef(dex::TypeIndex type_idx) const; const TypeList* GetInterfacesList(const ClassDef& class_def) const { if (class_def.interfaces_off_ == 0) { @@ -711,7 +712,7 @@ class DexFile { } // Returns the ProtoId at the specified index. - const ProtoId& GetProtoId(uint32_t idx) const { + const ProtoId& GetProtoId(uint16_t idx) const { DCHECK_LT(idx, NumProtoIds()) << GetLocation(); return proto_ids_[idx]; } @@ -723,16 +724,18 @@ class DexFile { } // Looks up a proto id for a given return type and signature type list - const ProtoId* FindProtoId(uint16_t return_type_idx, - const uint16_t* signature_type_idxs, uint32_t signature_length) const; - const ProtoId* FindProtoId(uint16_t return_type_idx, - const std::vector<uint16_t>& signature_type_idxs) const { + const ProtoId* FindProtoId(dex::TypeIndex return_type_idx, + const dex::TypeIndex* signature_type_idxs, + uint32_t signature_length) const; + const ProtoId* FindProtoId(dex::TypeIndex return_type_idx, + const std::vector<dex::TypeIndex>& signature_type_idxs) const { return FindProtoId(return_type_idx, &signature_type_idxs[0], signature_type_idxs.size()); } // Given a signature place the type ids into the given vector, returns true on success - bool CreateTypeList(const StringPiece& signature, uint16_t* return_type_idx, - std::vector<uint16_t>* param_type_idxs) const; + bool CreateTypeList(const StringPiece& signature, + dex::TypeIndex* return_type_idx, + std::vector<dex::TypeIndex>* param_type_idxs) const; // Create a Signature from the given string signature or return Signature::NoSignature if not // possible. @@ -1021,7 +1024,7 @@ class DexFile { // Returns a human-readable form of the field at an index. std::string PrettyField(uint32_t field_idx, bool with_type = true) const; // Returns a human-readable form of the type at an index. - std::string PrettyType(uint32_t type_idx) const; + std::string PrettyType(dex::TypeIndex type_idx) const; private: static std::unique_ptr<const DexFile> OpenFile(int fd, @@ -1165,11 +1168,11 @@ class DexFileParameterIterator { bool HasNext() const { return pos_ < size_; } size_t Size() const { return size_; } void Next() { ++pos_; } - uint16_t GetTypeIdx() { + dex::TypeIndex GetTypeIdx() { return type_list_->GetTypeItem(pos_).type_idx_; } const char* GetDescriptor() { - return dex_file_.StringByTypeIdx(GetTypeIdx()); + return dex_file_.StringByTypeIdx(dex::TypeIndex(GetTypeIdx())); } private: const DexFile& dex_file_; @@ -1455,7 +1458,7 @@ class CatchHandlerIterator { Init(handler_data); } - uint16_t GetHandlerTypeIndex() const { + dex::TypeIndex GetHandlerTypeIndex() const { return handler_.type_idx_; } uint32_t GetHandlerAddress() const { @@ -1476,7 +1479,7 @@ class CatchHandlerIterator { void Init(const uint8_t* handler_data); struct CatchHandlerItem { - uint16_t type_idx_; // type index of the caught exception type + dex::TypeIndex type_idx_; // type index of the caught exception type uint32_t address_; // handler address } handler_; const uint8_t* current_data_; // the current handler in dex file. diff --git a/runtime/dex_file_annotations.cc b/runtime/dex_file_annotations.cc index 835f456c9b..3fe2c409ca 100644 --- a/runtime/dex_file_annotations.cc +++ b/runtime/dex_file_annotations.cc @@ -90,7 +90,7 @@ const DexFile::AnnotationItem* SearchAnnotationSet(const DexFile& dex_file, const uint8_t* annotation = annotation_item->annotation_; uint32_t type_index = DecodeUnsignedLeb128(&annotation); - if (strcmp(descriptor, dex_file.StringByTypeIdx(type_index)) == 0) { + if (strcmp(descriptor, dex_file.StringByTypeIdx(dex::TypeIndex(type_index))) == 0) { result = annotation_item; break; } @@ -246,7 +246,7 @@ mirror::Object* ProcessEncodedAnnotation(Handle<mirror::Class> klass, const uint StackHandleScope<2> hs(self); ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); Handle<mirror::Class> annotation_class(hs.NewHandle( - class_linker->ResolveType(klass->GetDexFile(), type_index, klass.Get()))); + class_linker->ResolveType(klass->GetDexFile(), dex::TypeIndex(type_index), klass.Get()))); if (annotation_class.Get() == nullptr) { LOG(INFO) << "Unable to resolve " << klass->PrettyClass() << " annotation class " << type_index; DCHECK(Thread::Current()->IsExceptionPending()); @@ -370,13 +370,14 @@ bool ProcessAnnotationValue(Handle<mirror::Class> klass, if (result_style == DexFile::kAllRaw) { annotation_value->value_.SetI(index); } else { + dex::TypeIndex type_index(index); element_object = Runtime::Current()->GetClassLinker()->ResolveType( - klass->GetDexFile(), index, klass.Get()); + klass->GetDexFile(), type_index, klass.Get()); set_object = true; if (element_object == nullptr) { CHECK(self->IsExceptionPending()); if (result_style == DexFile::kAllObjects) { - const char* msg = dex_file.StringByTypeIdx(index); + const char* msg = dex_file.StringByTypeIdx(type_index); self->ThrowNewWrappedException("Ljava/lang/TypeNotPresentException;", msg); element_object = self->GetException(); self->ClearException(); @@ -665,7 +666,7 @@ const DexFile::AnnotationItem* GetAnnotationItemFromAnnotationSet( const uint8_t* annotation = annotation_item->annotation_; uint32_t type_index = DecodeUnsignedLeb128(&annotation); mirror::Class* resolved_class = Runtime::Current()->GetClassLinker()->ResolveType( - klass->GetDexFile(), type_index, klass.Get()); + klass->GetDexFile(), dex::TypeIndex(type_index), klass.Get()); if (resolved_class == nullptr) { std::string temp; LOG(WARNING) << StringPrintf("Unable to resolve %s annotation class %d", @@ -1345,7 +1346,9 @@ void RuntimeEncodedStaticFieldValueIterator::ReadValueToField(ArtField* field) c break; } case kType: { - mirror::Class* resolved = linker_->ResolveType(dex_file_, jval_.i, *dex_cache_, + mirror::Class* resolved = linker_->ResolveType(dex_file_, + dex::TypeIndex(jval_.i), + *dex_cache_, *class_loader_); field->SetObject<kTransactionActive>(field->GetDeclaringClass(), resolved); break; diff --git a/runtime/dex_file_test.cc b/runtime/dex_file_test.cc index 8e1501ff16..f94d07b252 100644 --- a/runtime/dex_file_test.cc +++ b/runtime/dex_file_test.cc @@ -415,14 +415,14 @@ TEST_F(DexFileTest, FindStringId) { TEST_F(DexFileTest, FindTypeId) { for (size_t i = 0; i < java_lang_dex_file_->NumTypeIds(); i++) { - const char* type_str = java_lang_dex_file_->StringByTypeIdx(i); + const char* type_str = java_lang_dex_file_->StringByTypeIdx(dex::TypeIndex(i)); const DexFile::StringId* type_str_id = java_lang_dex_file_->FindStringId(type_str); ASSERT_TRUE(type_str_id != nullptr); uint32_t type_str_idx = java_lang_dex_file_->GetIndexForStringId(*type_str_id); const DexFile::TypeId* type_id = java_lang_dex_file_->FindTypeId(type_str_idx); ASSERT_EQ(type_id, java_lang_dex_file_->FindTypeId(type_str)); ASSERT_TRUE(type_id != nullptr); - EXPECT_EQ(java_lang_dex_file_->GetIndexForTypeId(*type_id), i); + EXPECT_EQ(java_lang_dex_file_->GetIndexForTypeId(*type_id).index_, i); } } @@ -430,7 +430,7 @@ TEST_F(DexFileTest, FindProtoId) { for (size_t i = 0; i < java_lang_dex_file_->NumProtoIds(); i++) { const DexFile::ProtoId& to_find = java_lang_dex_file_->GetProtoId(i); const DexFile::TypeList* to_find_tl = java_lang_dex_file_->GetProtoParameters(to_find); - std::vector<uint16_t> to_find_types; + std::vector<dex::TypeIndex> to_find_types; if (to_find_tl != nullptr) { for (size_t j = 0; j < to_find_tl->Size(); j++) { to_find_types.push_back(to_find_tl->GetTypeItem(j).type_idx_); diff --git a/runtime/dex_file_types.h b/runtime/dex_file_types.h new file mode 100644 index 0000000000..c6d95a1d19 --- /dev/null +++ b/runtime/dex_file_types.h @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ART_RUNTIME_DEX_FILE_TYPES_H_ +#define ART_RUNTIME_DEX_FILE_TYPES_H_ + +#include <limits> +#include <ostream> + +namespace art { +namespace dex { + +class TypeIndex { + public: + uint16_t index_; + + TypeIndex() : index_(std::numeric_limits<decltype(index_)>::max()) {} + explicit TypeIndex(uint16_t idx) : index_(idx) {} + + bool IsValid() const { + return index_ != std::numeric_limits<decltype(index_)>::max(); + } + static TypeIndex Invalid() { + return TypeIndex(std::numeric_limits<decltype(index_)>::max()); + } + + bool operator==(const TypeIndex& other) const { + return index_ == other.index_; + } + bool operator!=(const TypeIndex& other) const { + return index_ != other.index_; + } + bool operator<(const TypeIndex& other) const { + return index_ < other.index_; + } + bool operator<=(const TypeIndex& other) const { + return index_ <= other.index_; + } + bool operator>(const TypeIndex& other) const { + return index_ > other.index_; + } + bool operator>=(const TypeIndex& other) const { + return index_ >= other.index_; + } +}; +std::ostream& operator<<(std::ostream& os, const TypeIndex& index); + +} // namespace dex +} // namespace art + +namespace std { + +template<> struct hash<art::dex::TypeIndex> { + size_t operator()(const art::dex::TypeIndex& index) const { + return hash<uint16_t>()(index.index_); + } +}; + +} // namespace std + +#endif // ART_RUNTIME_DEX_FILE_TYPES_H_ diff --git a/runtime/dex_file_verifier.cc b/runtime/dex_file_verifier.cc index be25803f59..68e9f73927 100644 --- a/runtime/dex_file_verifier.cc +++ b/runtime/dex_file_verifier.cc @@ -76,8 +76,9 @@ const char* DexFileVerifier::CheckLoadStringByIdx(uint32_t idx, const char* erro return dex_file_->StringDataByIdx(idx); } -const char* DexFileVerifier::CheckLoadStringByTypeIdx(uint32_t type_idx, const char* error_string) { - if (UNLIKELY(!CheckIndex(type_idx, dex_file_->NumTypeIds(), error_string))) { +const char* DexFileVerifier::CheckLoadStringByTypeIdx(dex::TypeIndex type_idx, + const char* error_string) { + if (UNLIKELY(!CheckIndex(type_idx.index_, dex_file_->NumTypeIds(), error_string))) { return nullptr; } const DexFile::TypeId& type_id = dex_file_->GetTypeId(type_idx); @@ -525,7 +526,7 @@ bool DexFileVerifier::CheckAndGetHandlerOffsets(const DexFile::CodeItem* code_it bool DexFileVerifier::CheckClassDataItemField(uint32_t idx, uint32_t access_flags, uint32_t class_access_flags, - uint16_t class_type_index, + dex::TypeIndex class_type_index, bool expect_static) { // Check for overflow. if (!CheckIndex(idx, header_->field_ids_size_, "class_data_item field_idx")) { @@ -533,13 +534,13 @@ bool DexFileVerifier::CheckClassDataItemField(uint32_t idx, } // Check that it's the right class. - uint16_t my_class_index = + dex::TypeIndex my_class_index = (reinterpret_cast<const DexFile::FieldId*>(begin_ + header_->field_ids_off_) + idx)-> class_idx_; if (class_type_index != my_class_index) { ErrorStringPrintf("Field's class index unexpected, %" PRIu16 "vs %" PRIu16, - my_class_index, - class_type_index); + my_class_index.index_, + class_type_index.index_); return false; } @@ -563,7 +564,7 @@ bool DexFileVerifier::CheckClassDataItemField(uint32_t idx, bool DexFileVerifier::CheckClassDataItemMethod(uint32_t idx, uint32_t access_flags, uint32_t class_access_flags, - uint16_t class_type_index, + dex::TypeIndex class_type_index, uint32_t code_offset, std::unordered_set<uint32_t>* direct_method_indexes, bool expect_direct) { @@ -574,13 +575,13 @@ bool DexFileVerifier::CheckClassDataItemMethod(uint32_t idx, } // Check that it's the right class. - uint16_t my_class_index = + dex::TypeIndex my_class_index = (reinterpret_cast<const DexFile::MethodId*>(begin_ + header_->method_ids_off_) + idx)-> class_idx_; if (class_type_index != my_class_index) { ErrorStringPrintf("Method's class index unexpected, %" PRIu16 "vs %" PRIu16, - my_class_index, - class_type_index); + my_class_index.index_, + class_type_index.index_); return false; } @@ -789,7 +790,7 @@ bool DexFileVerifier::CheckEncodedAnnotation() { bool DexFileVerifier::FindClassFlags(uint32_t index, bool is_field, - uint16_t* class_type_index, + dex::TypeIndex* class_type_index, uint32_t* class_access_flags) { DCHECK(class_type_index != nullptr); DCHECK(class_access_flags != nullptr); @@ -811,7 +812,7 @@ bool DexFileVerifier::FindClassFlags(uint32_t index, } // Check if that is valid. - if (*class_type_index >= header_->type_ids_size_) { + if (class_type_index->index_ >= header_->type_ids_size_) { return false; } @@ -836,7 +837,7 @@ bool DexFileVerifier::CheckOrderAndGetClassFlags(bool is_field, uint32_t curr_index, uint32_t prev_index, bool* have_class, - uint16_t* class_type_index, + dex::TypeIndex* class_type_index, uint32_t* class_access_flags) { if (curr_index < prev_index) { ErrorStringPrintf("out-of-order %s indexes %" PRIu32 " and %" PRIu32, @@ -862,7 +863,7 @@ bool DexFileVerifier::CheckOrderAndGetClassFlags(bool is_field, template <bool kStatic> bool DexFileVerifier::CheckIntraClassDataItemFields(ClassDataItemIterator* it, bool* have_class, - uint16_t* class_type_index, + dex::TypeIndex* class_type_index, uint32_t* class_access_flags) { DCHECK(it != nullptr); // These calls use the raw access flags to check whether the whole dex field is valid. @@ -897,7 +898,7 @@ bool DexFileVerifier::CheckIntraClassDataItemMethods( ClassDataItemIterator* it, std::unordered_set<uint32_t>* direct_method_indexes, bool* have_class, - uint16_t* class_type_index, + dex::TypeIndex* class_type_index, uint32_t* class_access_flags) { uint32_t prev_index = 0; for (; kDirect ? it->HasNextDirectMethod() : it->HasNextVirtualMethod(); it->Next()) { @@ -935,7 +936,7 @@ bool DexFileVerifier::CheckIntraClassDataItem() { // So we need to explicitly search with the first item we find (either field or method), and then, // as the lookup is expensive, cache the result. bool have_class = false; - uint16_t class_type_index; + dex::TypeIndex class_type_index; uint32_t class_access_flags; // Check fields. @@ -1682,26 +1683,27 @@ bool DexFileVerifier::CheckOffsetToTypeMap(size_t offset, uint16_t type) { return true; } -uint16_t DexFileVerifier::FindFirstClassDataDefiner(const uint8_t* ptr, bool* success) { +dex::TypeIndex DexFileVerifier::FindFirstClassDataDefiner(const uint8_t* ptr, bool* success) { ClassDataItemIterator it(*dex_file_, ptr); *success = true; if (it.HasNextStaticField() || it.HasNextInstanceField()) { LOAD_FIELD(field, it.GetMemberIndex(), "first_class_data_definer field_id", - *success = false; return DexFile::kDexNoIndex16) + *success = false; return dex::TypeIndex(DexFile::kDexNoIndex16)) return field->class_idx_; } if (it.HasNextDirectMethod() || it.HasNextVirtualMethod()) { LOAD_METHOD(method, it.GetMemberIndex(), "first_class_data_definer method_id", - *success = false; return DexFile::kDexNoIndex16) + *success = false; return dex::TypeIndex(DexFile::kDexNoIndex16)) return method->class_idx_; } - return DexFile::kDexNoIndex16; + return dex::TypeIndex(DexFile::kDexNoIndex16); } -uint16_t DexFileVerifier::FindFirstAnnotationsDirectoryDefiner(const uint8_t* ptr, bool* success) { +dex::TypeIndex DexFileVerifier::FindFirstAnnotationsDirectoryDefiner(const uint8_t* ptr, + bool* success) { const DexFile::AnnotationsDirectoryItem* item = reinterpret_cast<const DexFile::AnnotationsDirectoryItem*>(ptr); *success = true; @@ -1709,25 +1711,25 @@ uint16_t DexFileVerifier::FindFirstAnnotationsDirectoryDefiner(const uint8_t* pt if (item->fields_size_ != 0) { DexFile::FieldAnnotationsItem* field_items = (DexFile::FieldAnnotationsItem*) (item + 1); LOAD_FIELD(field, field_items[0].field_idx_, "first_annotations_dir_definer field_id", - *success = false; return DexFile::kDexNoIndex16) + *success = false; return dex::TypeIndex(DexFile::kDexNoIndex16)) return field->class_idx_; } if (item->methods_size_ != 0) { DexFile::MethodAnnotationsItem* method_items = (DexFile::MethodAnnotationsItem*) (item + 1); LOAD_METHOD(method, method_items[0].method_idx_, "first_annotations_dir_definer method id", - *success = false; return DexFile::kDexNoIndex16) + *success = false; return dex::TypeIndex(DexFile::kDexNoIndex16)) return method->class_idx_; } if (item->parameters_size_ != 0) { DexFile::ParameterAnnotationsItem* parameter_items = (DexFile::ParameterAnnotationsItem*) (item + 1); LOAD_METHOD(method, parameter_items[0].method_idx_, "first_annotations_dir_definer method id", - *success = false; return DexFile::kDexNoIndex16) + *success = false; return dex::TypeIndex(DexFile::kDexNoIndex16)) return method->class_idx_; } - return DexFile::kDexNoIndex16; + return dex::TypeIndex(DexFile::kDexNoIndex16); } bool DexFileVerifier::CheckInterStringIdItem() { @@ -1797,7 +1799,8 @@ bool DexFileVerifier::CheckInterProtoIdItem() { DexFileParameterIterator it(*dex_file_, *item); while (it.HasNext() && *shorty != '\0') { - if (!CheckIndex(it.GetTypeIdx(), dex_file_->NumTypeIds(), + if (!CheckIndex(it.GetTypeIdx().index_, + dex_file_->NumTypeIds(), "inter_proto_id_item shorty type_idx")) { return false; } @@ -1824,10 +1827,10 @@ bool DexFileVerifier::CheckInterProtoIdItem() { DexFileParameterIterator prev_it(*dex_file_, *prev); while (curr_it.HasNext() && prev_it.HasNext()) { - uint16_t prev_idx = prev_it.GetTypeIdx(); - uint16_t curr_idx = curr_it.GetTypeIdx(); - DCHECK_NE(prev_idx, DexFile::kDexNoIndex16); - DCHECK_NE(curr_idx, DexFile::kDexNoIndex16); + dex::TypeIndex prev_idx = prev_it.GetTypeIdx(); + dex::TypeIndex curr_idx = curr_it.GetTypeIdx(); + DCHECK_NE(prev_idx, dex::TypeIndex(DexFile::kDexNoIndex16)); + DCHECK_NE(curr_idx, dex::TypeIndex(DexFile::kDexNoIndex16)); if (prev_idx < curr_idx) { break; @@ -1951,7 +1954,7 @@ bool DexFileVerifier::CheckInterClassDefItem() { // Check for duplicate class def. if (defined_classes_.find(item->class_idx_) != defined_classes_.end()) { - ErrorStringPrintf("Redefinition of class with type idx: '%d'", item->class_idx_); + ErrorStringPrintf("Redefinition of class with type idx: '%d'", item->class_idx_.index_); return false; } defined_classes_.insert(item->class_idx_); @@ -1985,12 +1988,13 @@ bool DexFileVerifier::CheckInterClassDefItem() { return false; } - if (item->superclass_idx_ != DexFile::kDexNoIndex16) { + if (item->superclass_idx_.IsValid()) { if (header_->GetVersion() >= DexFile::kClassDefinitionOrderEnforcedVersion) { // Check that a class does not inherit from itself directly (by having // the same type idx as its super class). if (UNLIKELY(item->superclass_idx_ == item->class_idx_)) { - ErrorStringPrintf("Class with same type idx as its superclass: '%d'", item->class_idx_); + ErrorStringPrintf("Class with same type idx as its superclass: '%d'", + item->class_idx_.index_); return false; } @@ -2004,8 +2008,8 @@ bool DexFileVerifier::CheckInterClassDefItem() { ErrorStringPrintf("Invalid class definition ordering:" " class with type idx: '%d' defined before" " superclass with type idx: '%d'", - item->class_idx_, - item->superclass_idx_); + item->class_idx_.index_, + item->superclass_idx_.index_); return false; } } @@ -2029,7 +2033,7 @@ bool DexFileVerifier::CheckInterClassDefItem() { // same type idx as one of its immediate implemented interfaces). if (UNLIKELY(interfaces->GetTypeItem(i).type_idx_ == item->class_idx_)) { ErrorStringPrintf("Class with same type idx as implemented interface: '%d'", - item->class_idx_); + item->class_idx_.index_); return false; } @@ -2044,8 +2048,8 @@ bool DexFileVerifier::CheckInterClassDefItem() { ErrorStringPrintf("Invalid class definition ordering:" " class with type idx: '%d' defined before" " implemented interface with type idx: '%d'", - item->class_idx_, - interfaces->GetTypeItem(i).type_idx_); + item->class_idx_.index_, + interfaces->GetTypeItem(i).type_idx_.index_); return false; } } @@ -2065,9 +2069,9 @@ bool DexFileVerifier::CheckInterClassDefItem() { * practice the number of interfaces implemented by any given class is low. */ for (uint32_t i = 1; i < size; i++) { - uint32_t idx1 = interfaces->GetTypeItem(i).type_idx_; + dex::TypeIndex idx1 = interfaces->GetTypeItem(i).type_idx_; for (uint32_t j =0; j < i; j++) { - uint32_t idx2 = interfaces->GetTypeItem(j).type_idx_; + dex::TypeIndex idx2 = interfaces->GetTypeItem(j).type_idx_; if (UNLIKELY(idx1 == idx2)) { ErrorStringPrintf("Duplicate interface: '%s'", dex_file_->StringByTypeIdx(idx1)); return false; @@ -2080,11 +2084,12 @@ bool DexFileVerifier::CheckInterClassDefItem() { if (item->class_data_off_ != 0) { const uint8_t* data = begin_ + item->class_data_off_; bool success; - uint16_t data_definer = FindFirstClassDataDefiner(data, &success); + dex::TypeIndex data_definer = FindFirstClassDataDefiner(data, &success); if (!success) { return false; } - if (UNLIKELY((data_definer != item->class_idx_) && (data_definer != DexFile::kDexNoIndex16))) { + if (UNLIKELY((data_definer != item->class_idx_) && + (data_definer != dex::TypeIndex(DexFile::kDexNoIndex16)))) { ErrorStringPrintf("Invalid class_data_item"); return false; } @@ -2099,12 +2104,12 @@ bool DexFileVerifier::CheckInterClassDefItem() { } const uint8_t* data = begin_ + item->annotations_off_; bool success; - uint16_t annotations_definer = FindFirstAnnotationsDirectoryDefiner(data, &success); + dex::TypeIndex annotations_definer = FindFirstAnnotationsDirectoryDefiner(data, &success); if (!success) { return false; } if (UNLIKELY((annotations_definer != item->class_idx_) && - (annotations_definer != DexFile::kDexNoIndex16))) { + (annotations_definer != dex::TypeIndex(DexFile::kDexNoIndex16)))) { ErrorStringPrintf("Invalid annotations_directory_item"); return false; } @@ -2165,7 +2170,7 @@ bool DexFileVerifier::CheckInterAnnotationSetItem() { bool DexFileVerifier::CheckInterClassDataItem() { ClassDataItemIterator it(*dex_file_, ptr_); bool success; - uint16_t defining_class = FindFirstClassDataDefiner(ptr_, &success); + dex::TypeIndex defining_class = FindFirstClassDataDefiner(ptr_, &success); if (!success) { return false; } @@ -2197,7 +2202,7 @@ bool DexFileVerifier::CheckInterAnnotationsDirectoryItem() { const DexFile::AnnotationsDirectoryItem* item = reinterpret_cast<const DexFile::AnnotationsDirectoryItem*>(ptr_); bool success; - uint16_t defining_class = FindFirstAnnotationsDirectoryDefiner(ptr_, &success); + dex::TypeIndex defining_class = FindFirstAnnotationsDirectoryDefiner(ptr_, &success); if (!success) { return false; } @@ -2471,15 +2476,15 @@ static std::string GetStringOrError(const uint8_t* const begin, static std::string GetClassOrError(const uint8_t* const begin, const DexFile::Header* const header, - uint32_t class_idx) { + dex::TypeIndex class_idx) { // The `class_idx` is either `FieldId::class_idx_` or `MethodId::class_idx_` and // it has already been checked in `DexFileVerifier::CheckClassDataItemField()` // or `DexFileVerifier::CheckClassDataItemMethod()`, respectively, to match // a valid defining class. - CHECK_LT(class_idx, header->type_ids_size_); + CHECK_LT(class_idx.index_, header->type_ids_size_); const DexFile::TypeId* type_id = - reinterpret_cast<const DexFile::TypeId*>(begin + header->type_ids_off_) + class_idx; + reinterpret_cast<const DexFile::TypeId*>(begin + header->type_ids_off_) + class_idx.index_; // Assume that the data is OK at this point. Type id offsets have been checked at this point. diff --git a/runtime/dex_file_verifier.h b/runtime/dex_file_verifier.h index 133e4326bc..19a89de2f5 100644 --- a/runtime/dex_file_verifier.h +++ b/runtime/dex_file_verifier.h @@ -20,6 +20,7 @@ #include <unordered_set> #include "dex_file.h" +#include "dex_file_types.h" #include "safe_map.h" namespace art { @@ -76,12 +77,12 @@ class DexFileVerifier { bool CheckClassDataItemField(uint32_t idx, uint32_t access_flags, uint32_t class_access_flags, - uint16_t class_type_index, + dex::TypeIndex class_type_index, bool expect_static); bool CheckClassDataItemMethod(uint32_t idx, uint32_t access_flags, uint32_t class_access_flags, - uint16_t class_type_index, + dex::TypeIndex class_type_index, uint32_t code_offset, std::unordered_set<uint32_t>* direct_method_indexes, bool expect_direct); @@ -90,7 +91,7 @@ class DexFileVerifier { uint32_t curr_index, uint32_t prev_index, bool* have_class, - uint16_t* class_type_index, + dex::TypeIndex* class_type_index, uint32_t* class_access_flags); bool CheckPadding(size_t offset, uint32_t aligned_offset); @@ -104,7 +105,7 @@ class DexFileVerifier { template <bool kStatic> bool CheckIntraClassDataItemFields(ClassDataItemIterator* it, bool* have_class, - uint16_t* class_type_index, + dex::TypeIndex* class_type_index, uint32_t* class_access_flags); // Check all methods of the given type from the given iterator. Load the class data from the first // method, if necessary (and return it), or use the given values. @@ -112,7 +113,7 @@ class DexFileVerifier { bool CheckIntraClassDataItemMethods(ClassDataItemIterator* it, std::unordered_set<uint32_t>* direct_method_indexes, bool* have_class, - uint16_t* class_type_index, + dex::TypeIndex* class_type_index, uint32_t* class_access_flags); bool CheckIntraCodeItem(); @@ -130,8 +131,8 @@ class DexFileVerifier { // Note: as sometimes kDexNoIndex16, being 0xFFFF, is a valid return value, we need an // additional out parameter to signal any errors loading an index. - uint16_t FindFirstClassDataDefiner(const uint8_t* ptr, bool* success); - uint16_t FindFirstAnnotationsDirectoryDefiner(const uint8_t* ptr, bool* success); + dex::TypeIndex FindFirstClassDataDefiner(const uint8_t* ptr, bool* success); + dex::TypeIndex FindFirstAnnotationsDirectoryDefiner(const uint8_t* ptr, bool* success); bool CheckInterStringIdItem(); bool CheckInterTypeIdItem(); @@ -150,7 +151,7 @@ class DexFileVerifier { // Load a string by (type) index. Checks whether the index is in bounds, printing the error if // not. If there is an error, null is returned. const char* CheckLoadStringByIdx(uint32_t idx, const char* error_fmt); - const char* CheckLoadStringByTypeIdx(uint32_t type_idx, const char* error_fmt); + const char* CheckLoadStringByTypeIdx(dex::TypeIndex type_idx, const char* error_fmt); // Load a field/method Id by index. Checks whether the index is in bounds, printing the error if // not. If there is an error, null is returned. @@ -168,7 +169,7 @@ class DexFileVerifier { // linear search. The output values should thus be cached by the caller. bool FindClassFlags(uint32_t index, bool is_field, - uint16_t* class_type_index, + dex::TypeIndex* class_type_index, uint32_t* class_access_flags); // Check validity of the given access flags, interpreted for a field in the context of a class diff --git a/runtime/dex_file_verifier_test.cc b/runtime/dex_file_verifier_test.cc index 3801c228c0..0e0929f21f 100644 --- a/runtime/dex_file_verifier_test.cc +++ b/runtime/dex_file_verifier_test.cc @@ -26,6 +26,7 @@ #include "base/macros.h" #include "common_runtime_test.h" #include "dex_file-inl.h" +#include "dex_file_types.h" #include "leb128.h" #include "scoped_thread_state_change-inl.h" #include "thread-inl.h" @@ -155,7 +156,7 @@ TEST_F(DexFileVerifierTest, MethodId) { "method_id_class_idx", [](DexFile* dex_file) { DexFile::MethodId* method_id = const_cast<DexFile::MethodId*>(&dex_file->GetMethodId(0)); - method_id->class_idx_ = 0xFF; + method_id->class_idx_ = dex::TypeIndex(0xFF); }, "could not find declaring class for direct method index 0"); diff --git a/runtime/dex_instruction.cc b/runtime/dex_instruction.cc index c766b54c0a..751bd51dab 100644 --- a/runtime/dex_instruction.cc +++ b/runtime/dex_instruction.cc @@ -208,9 +208,9 @@ std::string Instruction::DumpString(const DexFile* file) const { case CONST_CLASS: case NEW_INSTANCE: if (file != nullptr) { - uint32_t type_idx = VRegB_21c(); - os << opcode << " v" << static_cast<int>(VRegA_21c()) << ", " << file->PrettyType(type_idx) - << " // type@" << type_idx; + dex::TypeIndex type_idx(VRegB_21c()); + os << opcode << " v" << static_cast<int>(VRegA_21c()) << ", " + << file->PrettyType(type_idx) << " // type@" << type_idx; break; } FALLTHROUGH_INTENDED; @@ -302,17 +302,19 @@ std::string Instruction::DumpString(const DexFile* file) const { FALLTHROUGH_INTENDED; case INSTANCE_OF: if (file != nullptr) { - uint32_t type_idx = VRegC_22c(); - os << opcode << " v" << static_cast<int>(VRegA_22c()) << ", v" << static_cast<int>(VRegB_22c()) << ", " - << file->PrettyType(type_idx) << " // type@" << type_idx; + dex::TypeIndex type_idx(VRegC_22c()); + os << opcode << " v" << static_cast<int>(VRegA_22c()) << ", v" + << static_cast<int>(VRegB_22c()) << ", " << file->PrettyType(type_idx) + << " // type@" << type_idx.index_; break; } FALLTHROUGH_INTENDED; case NEW_ARRAY: if (file != nullptr) { - uint32_t type_idx = VRegC_22c(); - os << opcode << " v" << static_cast<int>(VRegA_22c()) << ", v" << static_cast<int>(VRegB_22c()) << ", " - << file->PrettyType(type_idx) << " // type@" << type_idx; + dex::TypeIndex type_idx(VRegC_22c()); + os << opcode << " v" << static_cast<int>(VRegA_22c()) << ", v" + << static_cast<int>(VRegB_22c()) << ", " << file->PrettyType(type_idx) + << " // type@" << type_idx.index_; break; } FALLTHROUGH_INTENDED; diff --git a/runtime/entrypoints/entrypoint_utils-inl.h b/runtime/entrypoints/entrypoint_utils-inl.h index ed60f598d1..ac52f4e287 100644 --- a/runtime/entrypoints/entrypoint_utils-inl.h +++ b/runtime/entrypoints/entrypoint_utils-inl.h @@ -129,7 +129,7 @@ inline ArtMethod* GetCalleeSaveMethodCaller(Thread* self, Runtime::CalleeSaveTyp template <const bool kAccessCheck> ALWAYS_INLINE -inline mirror::Class* CheckObjectAlloc(uint32_t type_idx, +inline mirror::Class* CheckObjectAlloc(dex::TypeIndex type_idx, ArtMethod* method, Thread* self, bool* slow_path) { @@ -219,7 +219,7 @@ inline mirror::Class* CheckClassInitializedForObjectAlloc(mirror::Class* klass, // check. template <bool kAccessCheck, bool kInstrumented> ALWAYS_INLINE -inline mirror::Object* AllocObjectFromCode(uint32_t type_idx, +inline mirror::Object* AllocObjectFromCode(dex::TypeIndex type_idx, ArtMethod* method, Thread* self, gc::AllocatorType allocator_type) { @@ -275,7 +275,7 @@ inline mirror::Object* AllocObjectFromCodeInitialized(mirror::Class* klass, template <bool kAccessCheck> ALWAYS_INLINE -inline mirror::Class* CheckArrayAlloc(uint32_t type_idx, +inline mirror::Class* CheckArrayAlloc(dex::TypeIndex type_idx, int32_t component_count, ArtMethod* method, bool* slow_path) { @@ -313,7 +313,7 @@ inline mirror::Class* CheckArrayAlloc(uint32_t type_idx, // check. template <bool kAccessCheck, bool kInstrumented> ALWAYS_INLINE -inline mirror::Array* AllocArrayFromCode(uint32_t type_idx, +inline mirror::Array* AllocArrayFromCode(dex::TypeIndex type_idx, int32_t component_count, ArtMethod* method, Thread* self, @@ -562,7 +562,7 @@ inline ArtMethod* FindMethodFromCode(uint32_t method_idx, StackHandleScope<2> hs2(self); HandleWrapperObjPtr<mirror::Object> h_this(hs2.NewHandleWrapper(this_object)); Handle<mirror::Class> h_referring_class(hs2.NewHandle(referrer->GetDeclaringClass())); - const uint16_t method_type_idx = + const dex::TypeIndex method_type_idx = h_referring_class->GetDexFile().GetMethodId(method_idx).class_idx_; mirror::Class* method_reference_class = class_linker->ResolveType(method_type_idx, referrer); if (UNLIKELY(method_reference_class == nullptr)) { @@ -758,7 +758,8 @@ inline ArtMethod* FindMethodFast(uint32_t method_idx, return resolved_method; } else if (type == kSuper) { // TODO This lookup is rather slow. - uint16_t method_type_idx = referring_class->GetDexFile().GetMethodId(method_idx).class_idx_; + dex::TypeIndex method_type_idx = + referring_class->GetDexFile().GetMethodId(method_idx).class_idx_; mirror::Class* method_reference_class = referring_class->GetDexCache()->GetResolvedType(method_type_idx); if (method_reference_class == nullptr) { @@ -788,8 +789,11 @@ inline ArtMethod* FindMethodFast(uint32_t method_idx, } } -inline mirror::Class* ResolveVerifyAndClinit(uint32_t type_idx, ArtMethod* referrer, Thread* self, - bool can_run_clinit, bool verify_access) { +inline mirror::Class* ResolveVerifyAndClinit(dex::TypeIndex type_idx, + ArtMethod* referrer, + Thread* self, + bool can_run_clinit, + bool verify_access) { ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); mirror::Class* klass = class_linker->ResolveType(type_idx, referrer); if (UNLIKELY(klass == nullptr)) { diff --git a/runtime/entrypoints/entrypoint_utils.cc b/runtime/entrypoints/entrypoint_utils.cc index 1ccb4b004c..5390165ecd 100644 --- a/runtime/entrypoints/entrypoint_utils.cc +++ b/runtime/entrypoints/entrypoint_utils.cc @@ -38,7 +38,7 @@ namespace art { -static inline mirror::Class* CheckFilledNewArrayAlloc(uint32_t type_idx, +static inline mirror::Class* CheckFilledNewArrayAlloc(dex::TypeIndex type_idx, int32_t component_count, ArtMethod* referrer, Thread* self, @@ -82,10 +82,12 @@ static inline mirror::Class* CheckFilledNewArrayAlloc(uint32_t type_idx, } // Helper function to allocate array for FILLED_NEW_ARRAY. -mirror::Array* CheckAndAllocArrayFromCode(uint32_t type_idx, int32_t component_count, - ArtMethod* referrer, Thread* self, +mirror::Array* CheckAndAllocArrayFromCode(dex::TypeIndex type_idx, + int32_t component_count, + ArtMethod* referrer, + Thread* self, bool access_check, - gc::AllocatorType /* allocator_type */) { + gc::AllocatorType allocator_type ATTRIBUTE_UNUSED) { mirror::Class* klass = CheckFilledNewArrayAlloc(type_idx, component_count, referrer, self, access_check); if (UNLIKELY(klass == nullptr)) { @@ -101,12 +103,13 @@ mirror::Array* CheckAndAllocArrayFromCode(uint32_t type_idx, int32_t component_c } // Helper function to allocate array for FILLED_NEW_ARRAY. -mirror::Array* CheckAndAllocArrayFromCodeInstrumented(uint32_t type_idx, - int32_t component_count, - ArtMethod* referrer, - Thread* self, - bool access_check, - gc::AllocatorType /* allocator_type */) { +mirror::Array* CheckAndAllocArrayFromCodeInstrumented( + dex::TypeIndex type_idx, + int32_t component_count, + ArtMethod* referrer, + Thread* self, + bool access_check, + gc::AllocatorType allocator_type ATTRIBUTE_UNUSED) { mirror::Class* klass = CheckFilledNewArrayAlloc(type_idx, component_count, referrer, self, access_check); if (UNLIKELY(klass == nullptr)) { diff --git a/runtime/entrypoints/entrypoint_utils.h b/runtime/entrypoints/entrypoint_utils.h index bcddfb0508..d87dc674bc 100644 --- a/runtime/entrypoints/entrypoint_utils.h +++ b/runtime/entrypoints/entrypoint_utils.h @@ -23,6 +23,7 @@ #include "base/macros.h" #include "base/mutex.h" #include "dex_instruction.h" +#include "dex_file_types.h" #include "gc/allocator_type.h" #include "handle.h" #include "invoke_type.h" @@ -45,7 +46,7 @@ class ScopedObjectAccessAlreadyRunnable; class Thread; template <const bool kAccessCheck> -ALWAYS_INLINE inline mirror::Class* CheckObjectAlloc(uint32_t type_idx, +ALWAYS_INLINE inline mirror::Class* CheckObjectAlloc(dex::TypeIndex type_idx, ArtMethod* method, Thread* self, bool* slow_path) @@ -63,7 +64,7 @@ ALWAYS_INLINE inline mirror::Class* CheckClassInitializedForObjectAlloc(mirror:: // When verification/compiler hasn't been able to verify access, optionally perform an access // check. template <bool kAccessCheck, bool kInstrumented> -ALWAYS_INLINE inline mirror::Object* AllocObjectFromCode(uint32_t type_idx, +ALWAYS_INLINE inline mirror::Object* AllocObjectFromCode(dex::TypeIndex type_idx, ArtMethod* method, Thread* self, gc::AllocatorType allocator_type) @@ -89,7 +90,7 @@ ALWAYS_INLINE inline mirror::Object* AllocObjectFromCodeInitialized( template <bool kAccessCheck> -ALWAYS_INLINE inline mirror::Class* CheckArrayAlloc(uint32_t type_idx, +ALWAYS_INLINE inline mirror::Class* CheckArrayAlloc(dex::TypeIndex type_idx, int32_t component_count, ArtMethod* method, bool* slow_path) @@ -101,7 +102,7 @@ ALWAYS_INLINE inline mirror::Class* CheckArrayAlloc(uint32_t type_idx, // When verification/compiler hasn't been able to verify access, optionally perform an access // check. template <bool kAccessCheck, bool kInstrumented> -ALWAYS_INLINE inline mirror::Array* AllocArrayFromCode(uint32_t type_idx, +ALWAYS_INLINE inline mirror::Array* AllocArrayFromCode(dex::TypeIndex type_idx, int32_t component_count, ArtMethod* method, Thread* self, @@ -118,19 +119,21 @@ ALWAYS_INLINE inline mirror::Array* AllocArrayFromCodeResolved(mirror::Class* kl REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); -extern mirror::Array* CheckAndAllocArrayFromCode(uint32_t type_idx, int32_t component_count, - ArtMethod* method, Thread* self, - bool access_check, - gc::AllocatorType allocator_type) +mirror::Array* CheckAndAllocArrayFromCode(dex::TypeIndex type_idx, + int32_t component_count, + ArtMethod* method, + Thread* self, + bool access_check, + gc::AllocatorType allocator_type) REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); -extern mirror::Array* CheckAndAllocArrayFromCodeInstrumented(uint32_t type_idx, - int32_t component_count, - ArtMethod* method, - Thread* self, - bool access_check, - gc::AllocatorType allocator_type) +mirror::Array* CheckAndAllocArrayFromCodeInstrumented(dex::TypeIndex type_idx, + int32_t component_count, + ArtMethod* method, + Thread* self, + bool access_check, + gc::AllocatorType allocator_type) REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); @@ -177,7 +180,7 @@ inline ArtMethod* FindMethodFast(uint32_t method_idx, InvokeType type) REQUIRES_SHARED(Locks::mutator_lock_); -inline mirror::Class* ResolveVerifyAndClinit(uint32_t type_idx, +inline mirror::Class* ResolveVerifyAndClinit(dex::TypeIndex type_idx, ArtMethod* referrer, Thread* self, bool can_run_clinit, diff --git a/runtime/entrypoints/quick/quick_alloc_entrypoints.cc b/runtime/entrypoints/quick/quick_alloc_entrypoints.cc index 515fcbf6e6..397655a895 100644 --- a/runtime/entrypoints/quick/quick_alloc_entrypoints.cc +++ b/runtime/entrypoints/quick/quick_alloc_entrypoints.cc @@ -19,6 +19,7 @@ #include "art_method-inl.h" #include "base/enums.h" #include "callee_save_frame.h" +#include "dex_file_types.h" #include "entrypoints/entrypoint_utils-inl.h" #include "mirror/class-inl.h" #include "mirror/object_array-inl.h" @@ -34,7 +35,8 @@ extern "C" mirror::Object* artAllocObjectFromCode ##suffix##suffix2( \ REQUIRES_SHARED(Locks::mutator_lock_) { \ ScopedQuickEntrypointChecks sqec(self); \ if (kUseTlabFastPath && !(instrumented_bool) && (allocator_type) == gc::kAllocatorTypeTLAB) { \ - mirror::Class* klass = method->GetDexCacheResolvedType<false>(type_idx, kRuntimePointerSize); \ + mirror::Class* klass = method->GetDexCacheResolvedType<false>(dex::TypeIndex(type_idx), \ + kRuntimePointerSize); \ if (LIKELY(klass != nullptr && klass->IsInitialized() && !klass->IsFinalizable())) { \ size_t byte_count = klass->GetObjectSize(); \ byte_count = RoundUp(byte_count, gc::space::BumpPointerSpace::kAlignment); \ @@ -51,7 +53,10 @@ extern "C" mirror::Object* artAllocObjectFromCode ##suffix##suffix2( \ } \ } \ } \ - return AllocObjectFromCode<false, instrumented_bool>(type_idx, method, self, allocator_type); \ + return AllocObjectFromCode<false, instrumented_bool>(dex::TypeIndex(type_idx), \ + method, \ + self, \ + allocator_type); \ } \ extern "C" mirror::Object* artAllocObjectFromCodeResolved##suffix##suffix2( \ mirror::Class* klass, ArtMethod* method ATTRIBUTE_UNUSED, Thread* self) \ @@ -101,13 +106,19 @@ extern "C" mirror::Object* artAllocObjectFromCodeWithAccessCheck##suffix##suffix uint32_t type_idx, ArtMethod* method, Thread* self) \ REQUIRES_SHARED(Locks::mutator_lock_) { \ ScopedQuickEntrypointChecks sqec(self); \ - return AllocObjectFromCode<true, instrumented_bool>(type_idx, method, self, allocator_type); \ + return AllocObjectFromCode<true, instrumented_bool>(dex::TypeIndex(type_idx), \ + method, \ + self, \ + allocator_type); \ } \ extern "C" mirror::Array* artAllocArrayFromCode##suffix##suffix2( \ uint32_t type_idx, int32_t component_count, ArtMethod* method, Thread* self) \ REQUIRES_SHARED(Locks::mutator_lock_) { \ ScopedQuickEntrypointChecks sqec(self); \ - return AllocArrayFromCode<false, instrumented_bool>(type_idx, component_count, method, self, \ + return AllocArrayFromCode<false, instrumented_bool>(dex::TypeIndex(type_idx), \ + component_count, \ + method, \ + self, \ allocator_type); \ } \ extern "C" mirror::Array* artAllocArrayFromCodeResolved##suffix##suffix2( \ @@ -121,7 +132,10 @@ extern "C" mirror::Array* artAllocArrayFromCodeWithAccessCheck##suffix##suffix2( uint32_t type_idx, int32_t component_count, ArtMethod* method, Thread* self) \ REQUIRES_SHARED(Locks::mutator_lock_) { \ ScopedQuickEntrypointChecks sqec(self); \ - return AllocArrayFromCode<true, instrumented_bool>(type_idx, component_count, method, self, \ + return AllocArrayFromCode<true, instrumented_bool>(dex::TypeIndex(type_idx), \ + component_count, \ + method, \ + self, \ allocator_type); \ } \ extern "C" mirror::Array* artCheckAndAllocArrayFromCode##suffix##suffix2( \ @@ -129,9 +143,19 @@ extern "C" mirror::Array* artCheckAndAllocArrayFromCode##suffix##suffix2( \ REQUIRES_SHARED(Locks::mutator_lock_) { \ ScopedQuickEntrypointChecks sqec(self); \ if (!(instrumented_bool)) { \ - return CheckAndAllocArrayFromCode(type_idx, component_count, method, self, false, allocator_type); \ + return CheckAndAllocArrayFromCode(dex::TypeIndex(type_idx), \ + component_count, \ + method, \ + self, \ + false, \ + allocator_type); \ } else { \ - return CheckAndAllocArrayFromCodeInstrumented(type_idx, component_count, method, self, false, allocator_type); \ + return CheckAndAllocArrayFromCodeInstrumented(dex::TypeIndex(type_idx), \ + component_count, \ + method, \ + self, \ + false, \ + allocator_type); \ } \ } \ extern "C" mirror::Array* artCheckAndAllocArrayFromCodeWithAccessCheck##suffix##suffix2( \ @@ -139,9 +163,19 @@ extern "C" mirror::Array* artCheckAndAllocArrayFromCodeWithAccessCheck##suffix## REQUIRES_SHARED(Locks::mutator_lock_) { \ ScopedQuickEntrypointChecks sqec(self); \ if (!(instrumented_bool)) { \ - return CheckAndAllocArrayFromCode(type_idx, component_count, method, self, true, allocator_type); \ + return CheckAndAllocArrayFromCode(dex::TypeIndex(type_idx), \ + component_count, \ + method, \ + self, \ + true, \ + allocator_type); \ } else { \ - return CheckAndAllocArrayFromCodeInstrumented(type_idx, component_count, method, self, true, allocator_type); \ + return CheckAndAllocArrayFromCodeInstrumented(dex::TypeIndex(type_idx), \ + component_count, \ + method, \ + self, \ + true, \ + allocator_type); \ } \ } \ extern "C" mirror::String* artAllocStringFromBytesFromCode##suffix##suffix2( \ diff --git a/runtime/entrypoints/quick/quick_dexcache_entrypoints.cc b/runtime/entrypoints/quick/quick_dexcache_entrypoints.cc index d4384182b2..b1259e1b8d 100644 --- a/runtime/entrypoints/quick/quick_dexcache_entrypoints.cc +++ b/runtime/entrypoints/quick/quick_dexcache_entrypoints.cc @@ -20,6 +20,7 @@ #include "class_linker-inl.h" #include "class_table-inl.h" #include "dex_file-inl.h" +#include "dex_file_types.h" #include "gc/heap.h" #include "mirror/class-inl.h" #include "mirror/class_loader.h" @@ -37,7 +38,7 @@ extern "C" mirror::Class* artInitializeStaticStorageFromCode(uint32_t type_idx, // given by inheritance. ScopedQuickEntrypointChecks sqec(self); auto* caller = GetCalleeSaveMethodCaller(self, Runtime::kSaveRefsOnly); - return ResolveVerifyAndClinit(type_idx, caller, self, true, false); + return ResolveVerifyAndClinit(dex::TypeIndex(type_idx), caller, self, true, false); } extern "C" mirror::Class* artInitializeTypeFromCode(uint32_t type_idx, Thread* self) @@ -45,7 +46,7 @@ extern "C" mirror::Class* artInitializeTypeFromCode(uint32_t type_idx, Thread* s // Called when method->dex_cache_resolved_types_[] misses. ScopedQuickEntrypointChecks sqec(self); auto* caller = GetCalleeSaveMethodCaller(self, Runtime::kSaveRefsOnly); - return ResolveVerifyAndClinit(type_idx, caller, self, false, false); + return ResolveVerifyAndClinit(dex::TypeIndex(type_idx), caller, self, false, false); } extern "C" mirror::Class* artInitializeTypeAndVerifyAccessFromCode(uint32_t type_idx, Thread* self) @@ -54,7 +55,7 @@ extern "C" mirror::Class* artInitializeTypeAndVerifyAccessFromCode(uint32_t type // unpopulated. ScopedQuickEntrypointChecks sqec(self); auto* caller = GetCalleeSaveMethodCaller(self, Runtime::kSaveRefsOnly); - return ResolveVerifyAndClinit(type_idx, caller, self, false, true); + return ResolveVerifyAndClinit(dex::TypeIndex(type_idx), caller, self, false, true); } extern "C" mirror::String* artResolveStringFromCode(int32_t string_idx, Thread* self) diff --git a/runtime/interpreter/interpreter.cc b/runtime/interpreter/interpreter.cc index a32c800491..1b3d339f36 100644 --- a/runtime/interpreter/interpreter.cc +++ b/runtime/interpreter/interpreter.cc @@ -543,7 +543,7 @@ void EnterInterpreterFromDeoptimize(Thread* self, ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); // This is a suspend point. But it's ok since value has been set into shadow_frame. ObjPtr<mirror::Class> klass = class_linker->ResolveType( - instr->VRegB_21c(), shadow_frame->GetMethod()); + dex::TypeIndex(instr->VRegB_21c()), shadow_frame->GetMethod()); DCHECK(klass->IsStringClass()); } } else { diff --git a/runtime/interpreter/interpreter_common.cc b/runtime/interpreter/interpreter_common.cc index 8c63a9e979..05f74d67d4 100644 --- a/runtime/interpreter/interpreter_common.cc +++ b/runtime/interpreter/interpreter_common.cc @@ -1460,7 +1460,7 @@ static inline bool DoCallCommon(ArtMethod* called_method, ObjPtr<mirror::Object> o = shadow_frame.GetVRegReference(src_reg); if (do_assignability_check && o != nullptr) { PointerSize pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize(); - const uint32_t type_idx = params->GetTypeItem(shorty_pos).type_idx_; + const dex::TypeIndex type_idx = params->GetTypeItem(shorty_pos).type_idx_; ObjPtr<mirror::Class> arg_type = method->GetDexCacheResolvedType(type_idx, pointer_size); if (arg_type == nullptr) { @@ -1568,7 +1568,7 @@ bool DoFilledNewArray(const Instruction* inst, return false; } uint16_t type_idx = is_range ? inst->VRegB_3rc() : inst->VRegB_35c(); - ObjPtr<mirror::Class> array_class = ResolveVerifyAndClinit(type_idx, + ObjPtr<mirror::Class> array_class = ResolveVerifyAndClinit(dex::TypeIndex(type_idx), shadow_frame.GetMethod(), self, false, diff --git a/runtime/interpreter/interpreter_switch_impl.cc b/runtime/interpreter/interpreter_switch_impl.cc index 435ac62a9d..989b7da4cf 100644 --- a/runtime/interpreter/interpreter_switch_impl.cc +++ b/runtime/interpreter/interpreter_switch_impl.cc @@ -395,7 +395,7 @@ JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, } case Instruction::CONST_CLASS: { PREAMBLE(); - ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(inst->VRegB_21c(), + ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(inst->VRegB_21c()), shadow_frame.GetMethod(), self, false, @@ -434,7 +434,7 @@ JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, } case Instruction::CHECK_CAST: { PREAMBLE(); - ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(inst->VRegB_21c(), + ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(inst->VRegB_21c()), shadow_frame.GetMethod(), self, false, @@ -454,7 +454,7 @@ JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, } case Instruction::INSTANCE_OF: { PREAMBLE(); - ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(inst->VRegC_22c(), + ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(inst->VRegC_22c()), shadow_frame.GetMethod(), self, false, @@ -484,7 +484,7 @@ JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, case Instruction::NEW_INSTANCE: { PREAMBLE(); ObjPtr<mirror::Object> obj = nullptr; - ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(inst->VRegB_21c(), + ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(inst->VRegB_21c()), shadow_frame.GetMethod(), self, false, @@ -495,8 +495,10 @@ JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, obj = mirror::String::AllocEmptyString<true>(self, allocator_type); } else { obj = AllocObjectFromCode<do_access_check, true>( - inst->VRegB_21c(), shadow_frame.GetMethod(), self, - Runtime::Current()->GetHeap()->GetCurrentAllocator()); + dex::TypeIndex(inst->VRegB_21c()), + shadow_frame.GetMethod(), + self, + Runtime::Current()->GetHeap()->GetCurrentAllocator()); } } if (UNLIKELY(obj == nullptr)) { @@ -520,7 +522,10 @@ JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, PREAMBLE(); int32_t length = shadow_frame.GetVReg(inst->VRegB_22c(inst_data)); ObjPtr<mirror::Object> obj = AllocArrayFromCode<do_access_check, true>( - inst->VRegC_22c(), length, shadow_frame.GetMethod(), self, + dex::TypeIndex(inst->VRegC_22c()), + length, + shadow_frame.GetMethod(), + self, Runtime::Current()->GetHeap()->GetCurrentAllocator()); if (UNLIKELY(obj == nullptr)) { HANDLE_PENDING_EXCEPTION(); diff --git a/runtime/interpreter/mterp/mterp.cc b/runtime/interpreter/mterp/mterp.cc index 2bd47bbfcf..fbfed402ee 100644 --- a/runtime/interpreter/mterp/mterp.cc +++ b/runtime/interpreter/mterp/mterp.cc @@ -304,7 +304,11 @@ extern "C" size_t MterpConstClass(uint32_t index, ShadowFrame* shadow_frame, Thread* self) REQUIRES_SHARED(Locks::mutator_lock_) { - mirror::Class* c = ResolveVerifyAndClinit(index, shadow_frame->GetMethod(), self, false, false); + mirror::Class* c = ResolveVerifyAndClinit(dex::TypeIndex(index), + shadow_frame->GetMethod(), + self, + false, + false); if (UNLIKELY(c == nullptr)) { return true; } @@ -317,7 +321,11 @@ extern "C" size_t MterpCheckCast(uint32_t index, art::ArtMethod* method, Thread* self) REQUIRES_SHARED(Locks::mutator_lock_) { - ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(index, method, self, false, false); + ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(index), + method, + self, + false, + false); if (UNLIKELY(c == nullptr)) { return true; } @@ -335,7 +343,11 @@ extern "C" size_t MterpInstanceOf(uint32_t index, art::ArtMethod* method, Thread* self) REQUIRES_SHARED(Locks::mutator_lock_) { - ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(index, method, self, false, false); + ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(index), + method, + self, + false, + false); if (UNLIKELY(c == nullptr)) { return false; // Caller will check for pending exception. Return value unimportant. } @@ -353,7 +365,7 @@ extern "C" size_t MterpNewInstance(ShadowFrame* shadow_frame, Thread* self, uint REQUIRES_SHARED(Locks::mutator_lock_) { const Instruction* inst = Instruction::At(shadow_frame->GetDexPCPtr()); mirror::Object* obj = nullptr; - mirror::Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), + mirror::Class* c = ResolveVerifyAndClinit(dex::TypeIndex(inst->VRegB_21c()), shadow_frame->GetMethod(), self, false, @@ -363,9 +375,10 @@ extern "C" size_t MterpNewInstance(ShadowFrame* shadow_frame, Thread* self, uint gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator(); obj = mirror::String::AllocEmptyString<true>(self, allocator_type); } else { - obj = AllocObjectFromCode<false, true>( - inst->VRegB_21c(), shadow_frame->GetMethod(), self, - Runtime::Current()->GetHeap()->GetCurrentAllocator()); + obj = AllocObjectFromCode<false, true>(dex::TypeIndex(inst->VRegB_21c()), + shadow_frame->GetMethod(), + self, + Runtime::Current()->GetHeap()->GetCurrentAllocator()); } } if (UNLIKELY(obj == nullptr)) { @@ -446,7 +459,7 @@ extern "C" size_t MterpNewArray(ShadowFrame* shadow_frame, const Instruction* inst = Instruction::At(dex_pc_ptr); int32_t length = shadow_frame->GetVReg(inst->VRegB_22c(inst_data)); mirror::Object* obj = AllocArrayFromCode<false, true>( - inst->VRegC_22c(), length, shadow_frame->GetMethod(), self, + dex::TypeIndex(inst->VRegC_22c()), length, shadow_frame->GetMethod(), self, Runtime::Current()->GetHeap()->GetCurrentAllocator()); if (UNLIKELY(obj == nullptr)) { return false; diff --git a/runtime/jit/offline_profiling_info.cc b/runtime/jit/offline_profiling_info.cc index b9f5981393..6f2a8c673f 100644 --- a/runtime/jit/offline_profiling_info.cc +++ b/runtime/jit/offline_profiling_info.cc @@ -235,7 +235,7 @@ bool ProfileCompilationInfo::Save(int fd) { AddUintToBuffer(&buffer, method_it); } for (auto class_id : dex_data.class_set) { - AddUintToBuffer(&buffer, class_id); + AddUintToBuffer(&buffer, class_id.index_); } DCHECK_EQ(required_capacity, buffer.size()) << "Failed to add the expected number of bytes in the buffer"; @@ -282,7 +282,7 @@ bool ProfileCompilationInfo::AddMethodIndex(const std::string& dex_location, bool ProfileCompilationInfo::AddClassIndex(const std::string& dex_location, uint32_t checksum, - uint16_t type_idx) { + dex::TypeIndex type_idx) { DexFileData* const data = GetOrAddDexFileData(dex_location, checksum); if (data == nullptr) { return false; @@ -305,7 +305,7 @@ bool ProfileCompilationInfo::ProcessLine(SafeBuffer& line_buffer, for (uint16_t i = 0; i < class_set_size; i++) { uint16_t type_idx = line_buffer.ReadUintAndAdvance<uint16_t>(); - if (!AddClassIndex(dex_location, checksum, type_idx)) { + if (!AddClassIndex(dex_location, checksum, dex::TypeIndex(type_idx))) { return false; } } @@ -569,13 +569,13 @@ bool ProfileCompilationInfo::ContainsMethod(const MethodReference& method_ref) c return false; } -bool ProfileCompilationInfo::ContainsClass(const DexFile& dex_file, uint16_t type_idx) const { +bool ProfileCompilationInfo::ContainsClass(const DexFile& dex_file, dex::TypeIndex type_idx) const { auto info_it = info_.find(GetProfileDexFileKey(dex_file.GetLocation())); if (info_it != info_.end()) { if (!ChecksumMatch(dex_file, info_it->second.checksum)) { return false; } - const std::set<uint16_t>& classes = info_it->second.class_set; + const std::set<dex::TypeIndex>& classes = info_it->second.class_set; return classes.find(type_idx) != classes.end(); } return false; @@ -706,7 +706,7 @@ bool ProfileCompilationInfo::GenerateTestProfile(int fd, if (c < (number_of_classes / kFavorSplit)) { type_idx %= kFavorFirstN; } - info.AddClassIndex(profile_key, 0, type_idx); + info.AddClassIndex(profile_key, 0, dex::TypeIndex(type_idx)); } } return info.Save(fd); diff --git a/runtime/jit/offline_profiling_info.h b/runtime/jit/offline_profiling_info.h index f8ed573b8b..413648829a 100644 --- a/runtime/jit/offline_profiling_info.h +++ b/runtime/jit/offline_profiling_info.h @@ -23,6 +23,7 @@ #include "atomic.h" #include "dex_cache_resolved_classes.h" #include "dex_file.h" +#include "dex_file_types.h" #include "method_reference.h" #include "safe_map.h" @@ -66,7 +67,7 @@ class ProfileCompilationInfo { bool ContainsMethod(const MethodReference& method_ref) const; // Returns true if the class's type is present in the profiling info. - bool ContainsClass(const DexFile& dex_file, uint16_t type_idx) const; + bool ContainsClass(const DexFile& dex_file, dex::TypeIndex type_idx) const; // Dumps all the loaded profile info into a string and returns it. // If dex_files is not null then the method indices will be resolved to their @@ -104,7 +105,7 @@ class ProfileCompilationInfo { explicit DexFileData(uint32_t location_checksum) : checksum(location_checksum) {} uint32_t checksum; std::set<uint16_t> method_set; - std::set<uint16_t> class_set; + std::set<dex::TypeIndex> class_set; bool operator==(const DexFileData& other) const { return checksum == other.checksum && method_set == other.method_set; @@ -115,7 +116,7 @@ class ProfileCompilationInfo { DexFileData* GetOrAddDexFileData(const std::string& dex_location, uint32_t checksum); bool AddMethodIndex(const std::string& dex_location, uint32_t checksum, uint16_t method_idx); - bool AddClassIndex(const std::string& dex_location, uint32_t checksum, uint16_t type_idx); + bool AddClassIndex(const std::string& dex_location, uint32_t checksum, dex::TypeIndex type_idx); bool AddResolvedClasses(const DexCacheResolvedClasses& classes); // Parsing functionality. diff --git a/runtime/mirror/class-inl.h b/runtime/mirror/class-inl.h index 9a6d60e0ad..aa5da2e83b 100644 --- a/runtime/mirror/class-inl.h +++ b/runtime/mirror/class-inl.h @@ -372,7 +372,7 @@ inline bool Class::ResolvedFieldAccessTest(ObjPtr<Class> access_to, // to access the field if the FieldId specifies an accessible subclass of the declaring // class rather than the declaring class itself. ObjPtr<DexCache> referrer_dex_cache = use_referrers_cache ? this->GetDexCache() : dex_cache; - uint32_t class_idx = referrer_dex_cache->GetDexFile()->GetFieldId(field_idx).class_idx_; + dex::TypeIndex class_idx = referrer_dex_cache->GetDexFile()->GetFieldId(field_idx).class_idx_; // The referenced class has already been resolved with the field, but may not be in the dex // cache. Use LookupResolveType here to search the class table if it is not in the dex cache. // should be no thread suspension due to the class being resolved. @@ -410,7 +410,7 @@ inline bool Class::ResolvedMethodAccessTest(ObjPtr<Class> access_to, // to access the method if the MethodId specifies an accessible subclass of the declaring // class rather than the declaring class itself. ObjPtr<DexCache> referrer_dex_cache = use_referrers_cache ? this->GetDexCache() : dex_cache; - uint32_t class_idx = referrer_dex_cache->GetDexFile()->GetMethodId(method_idx).class_idx_; + dex::TypeIndex class_idx = referrer_dex_cache->GetDexFile()->GetMethodId(method_idx).class_idx_; // The referenced class has already been resolved with the method, but may not be in the dex // cache. ObjPtr<Class> dex_access_to = Runtime::Current()->GetClassLinker()->LookupResolvedType( @@ -894,7 +894,8 @@ inline void Class::InitializeClassVisitor::operator()(ObjPtr<Object> obj, klass->SetClassSize(class_size_); klass->SetPrimitiveType(Primitive::kPrimNot); // Default to not being primitive. klass->SetDexClassDefIndex(DexFile::kDexNoIndex16); // Default to no valid class def index. - klass->SetDexTypeIndex(DexFile::kDexNoIndex16); // Default to no valid type index. + klass->SetDexTypeIndex(dex::TypeIndex(DexFile::kDexNoIndex16)); // Default to no valid type + // index. // Default to force slow path until initialized. klass->SetObjectSizeAllocFastPath(std::numeric_limits<uint32_t>::max()); } diff --git a/runtime/mirror/class.cc b/runtime/mirror/class.cc index db46027bc8..0cfe29bed9 100644 --- a/runtime/mirror/class.cc +++ b/runtime/mirror/class.cc @@ -923,7 +923,7 @@ const DexFile::ClassDef* Class::GetClassDef() { return &GetDexFile().GetClassDef(class_def_idx); } -uint16_t Class::GetDirectInterfaceTypeIdx(uint32_t idx) { +dex::TypeIndex Class::GetDirectInterfaceTypeIdx(uint32_t idx) { DCHECK(!IsPrimitive()); DCHECK(!IsArrayClass()); return GetInterfaceTypeList()->GetTypeItem(idx).type_idx_; @@ -947,10 +947,11 @@ ObjPtr<Class> Class::GetDirectInterface(Thread* self, DCHECK(interfaces != nullptr); return interfaces->Get(idx); } else { - uint16_t type_idx = klass->GetDirectInterfaceTypeIdx(idx); + dex::TypeIndex type_idx = klass->GetDirectInterfaceTypeIdx(idx); ObjPtr<Class> interface = klass->GetDexCache()->GetResolvedType(type_idx); if (interface == nullptr) { - interface = Runtime::Current()->GetClassLinker()->ResolveType(klass->GetDexFile(), type_idx, + interface = Runtime::Current()->GetClassLinker()->ResolveType(klass->GetDexFile(), + type_idx, klass.Get()); CHECK(interface != nullptr || self->IsExceptionPending()); } @@ -1130,10 +1131,12 @@ uint32_t Class::Depth() { return depth; } -uint32_t Class::FindTypeIndexInOtherDexFile(const DexFile& dex_file) { +dex::TypeIndex Class::FindTypeIndexInOtherDexFile(const DexFile& dex_file) { std::string temp; const DexFile::TypeId* type_id = dex_file.FindTypeId(GetDescriptor(&temp)); - return (type_id == nullptr) ? DexFile::kDexNoIndex : dex_file.GetIndexForTypeId(*type_id); + return (type_id == nullptr) + ? dex::TypeIndex(DexFile::kDexNoIndex) + : dex_file.GetIndexForTypeId(*type_id); } template <PointerSize kPointerSize, bool kTransactionActive> diff --git a/runtime/mirror/class.h b/runtime/mirror/class.h index 711914dc61..792f626eff 100644 --- a/runtime/mirror/class.h +++ b/runtime/mirror/class.h @@ -20,6 +20,7 @@ #include "base/enums.h" #include "base/iteration_range.h" #include "dex_file.h" +#include "dex_file_types.h" #include "class_flags.h" #include "gc_root.h" #include "gc/allocator_type.h" @@ -1148,16 +1149,17 @@ class MANAGED Class FINAL : public Object { SetField32<false>(OFFSET_OF_OBJECT_MEMBER(Class, dex_class_def_idx_), class_def_idx); } - uint16_t GetDexTypeIndex() REQUIRES_SHARED(Locks::mutator_lock_) { - return GetField32(OFFSET_OF_OBJECT_MEMBER(Class, dex_type_idx_)); + dex::TypeIndex GetDexTypeIndex() REQUIRES_SHARED(Locks::mutator_lock_) { + return dex::TypeIndex( + static_cast<uint16_t>(GetField32(OFFSET_OF_OBJECT_MEMBER(Class, dex_type_idx_)))); } - void SetDexTypeIndex(uint16_t type_idx) REQUIRES_SHARED(Locks::mutator_lock_) { + void SetDexTypeIndex(dex::TypeIndex type_idx) REQUIRES_SHARED(Locks::mutator_lock_) { // Not called within a transaction. - SetField32<false>(OFFSET_OF_OBJECT_MEMBER(Class, dex_type_idx_), type_idx); + SetField32<false>(OFFSET_OF_OBJECT_MEMBER(Class, dex_type_idx_), type_idx.index_); } - uint32_t FindTypeIndexInOtherDexFile(const DexFile& dex_file) + dex::TypeIndex FindTypeIndexInOtherDexFile(const DexFile& dex_file) REQUIRES_SHARED(Locks::mutator_lock_); static Class* GetJavaLangClass() REQUIRES_SHARED(Locks::mutator_lock_) { @@ -1198,7 +1200,7 @@ class MANAGED Class FINAL : public Object { ALWAYS_INLINE uint32_t NumDirectInterfaces() REQUIRES_SHARED(Locks::mutator_lock_); - uint16_t GetDirectInterfaceTypeIdx(uint32_t idx) REQUIRES_SHARED(Locks::mutator_lock_); + dex::TypeIndex GetDirectInterfaceTypeIdx(uint32_t idx) REQUIRES_SHARED(Locks::mutator_lock_); static ObjPtr<Class> GetDirectInterface(Thread* self, Handle<Class> klass, diff --git a/runtime/mirror/dex_cache-inl.h b/runtime/mirror/dex_cache-inl.h index c7a123b580..d903f71604 100644 --- a/runtime/mirror/dex_cache-inl.h +++ b/runtime/mirror/dex_cache-inl.h @@ -69,15 +69,15 @@ inline void DexCache::ClearString(uint32_t string_idx) { } } -inline Class* DexCache::GetResolvedType(uint32_t type_idx) { - DCHECK_LT(type_idx, NumResolvedTypes()); - return GetResolvedTypes()[type_idx].Read(); +inline Class* DexCache::GetResolvedType(dex::TypeIndex type_idx) { + DCHECK_LT(type_idx.index_, NumResolvedTypes()); + return GetResolvedTypes()[type_idx.index_].Read(); } -inline void DexCache::SetResolvedType(uint32_t type_idx, ObjPtr<Class> resolved) { - DCHECK_LT(type_idx, NumResolvedTypes()); // NOTE: Unchecked, i.e. not throwing AIOOB. +inline void DexCache::SetResolvedType(dex::TypeIndex type_idx, ObjPtr<Class> resolved) { + DCHECK_LT(type_idx.index_, NumResolvedTypes()); // NOTE: Unchecked, i.e. not throwing AIOOB. // TODO default transaction support. - GetResolvedTypes()[type_idx] = GcRoot<Class>(resolved); + GetResolvedTypes()[type_idx.index_] = GcRoot<Class>(resolved); // TODO: Fine-grained marking, so that we don't need to go through all arrays in full. Runtime::Current()->GetHeap()->WriteBarrierEveryFieldOf(this); } diff --git a/runtime/mirror/dex_cache.h b/runtime/mirror/dex_cache.h index 1ae694d789..7d82d3ad29 100644 --- a/runtime/mirror/dex_cache.h +++ b/runtime/mirror/dex_cache.h @@ -21,6 +21,7 @@ #include "art_field.h" #include "art_method.h" #include "class.h" +#include "dex_file_types.h" #include "object.h" #include "object_array.h" @@ -223,9 +224,9 @@ class MANAGED DexCache FINAL : public Object { // the string isn't kept live. void ClearString(uint32_t string_idx) REQUIRES_SHARED(Locks::mutator_lock_); - Class* GetResolvedType(uint32_t type_idx) REQUIRES_SHARED(Locks::mutator_lock_); + Class* GetResolvedType(dex::TypeIndex type_idx) REQUIRES_SHARED(Locks::mutator_lock_); - void SetResolvedType(uint32_t type_idx, ObjPtr<Class> resolved) + void SetResolvedType(dex::TypeIndex type_idx, ObjPtr<Class> resolved) REQUIRES_SHARED(Locks::mutator_lock_); ALWAYS_INLINE ArtMethod* GetResolvedMethod(uint32_t method_idx, PointerSize ptr_size) diff --git a/runtime/mirror/object_test.cc b/runtime/mirror/object_test.cc index 5bf254d961..4b47f7f614 100644 --- a/runtime/mirror/object_test.cc +++ b/runtime/mirror/object_test.cc @@ -313,7 +313,7 @@ TEST_F(ObjectTest, CheckAndAllocArrayFromCode) { ArtMethod* sort = java_util_Arrays->FindDirectMethod("sort", "([I)V", kRuntimePointerSize); const DexFile::TypeId* type_id = java_lang_dex_file_->FindTypeId("[I"); ASSERT_TRUE(type_id != nullptr); - uint32_t type_idx = java_lang_dex_file_->GetIndexForTypeId(*type_id); + dex::TypeIndex type_idx = java_lang_dex_file_->GetIndexForTypeId(*type_id); Object* array = CheckAndAllocArrayFromCodeInstrumented( type_idx, 3, sort, Thread::Current(), false, Runtime::Current()->GetHeap()->GetCurrentAllocator()); diff --git a/runtime/native/dalvik_system_VMRuntime.cc b/runtime/native/dalvik_system_VMRuntime.cc index 866dc7f73f..48feb11924 100644 --- a/runtime/native/dalvik_system_VMRuntime.cc +++ b/runtime/native/dalvik_system_VMRuntime.cc @@ -34,6 +34,7 @@ extern "C" void android_set_application_target_sdk_version(uint32_t version); #include "common_throws.h" #include "debugger.h" #include "dex_file-inl.h" +#include "dex_file_types.h" #include "gc/accounting/card_table-inl.h" #include "gc/allocator/dlmalloc.h" #include "gc/heap.h" @@ -305,7 +306,7 @@ static void PreloadDexCachesResolveString( // Based on ClassLinker::ResolveType. static void PreloadDexCachesResolveType(Thread* self, ObjPtr<mirror::DexCache> dex_cache, - uint32_t type_idx) + dex::TypeIndex type_idx) REQUIRES_SHARED(Locks::mutator_lock_) { ObjPtr<mirror::Class> klass = dex_cache->GetResolvedType(type_idx); if (klass != nullptr) { @@ -455,7 +456,7 @@ static void PreloadDexCachesStatsFilled(DexCacheStats* filled) } } for (size_t j = 0; j < dex_cache->NumResolvedTypes(); j++) { - ObjPtr<mirror::Class> klass = dex_cache->GetResolvedType(j); + ObjPtr<mirror::Class> klass = dex_cache->GetResolvedType(dex::TypeIndex(j)); if (klass != nullptr) { filled->num_types++; } @@ -519,7 +520,7 @@ static void VMRuntime_preloadDexCaches(JNIEnv* env, jobject) { if (kPreloadDexCachesTypes) { for (size_t j = 0; j < dex_cache->NumResolvedTypes(); j++) { - PreloadDexCachesResolveType(soa.Self(), dex_cache.Get(), j); + PreloadDexCachesResolveType(soa.Self(), dex_cache.Get(), dex::TypeIndex(j)); } } diff --git a/runtime/native/java_lang_DexCache.cc b/runtime/native/java_lang_DexCache.cc index 71379a51a5..f6de593017 100644 --- a/runtime/native/java_lang_DexCache.cc +++ b/runtime/native/java_lang_DexCache.cc @@ -17,6 +17,7 @@ #include "java_lang_DexCache.h" #include "dex_file.h" +#include "dex_file_types.h" #include "jni_internal.h" #include "mirror/class-inl.h" #include "mirror/dex_cache-inl.h" @@ -53,7 +54,7 @@ static jobject DexCache_getResolvedType(JNIEnv* env, jobject javaDexCache, jint ScopedFastNativeObjectAccess soa(env); ObjPtr<mirror::DexCache> dex_cache = soa.Decode<mirror::DexCache>(javaDexCache); CHECK_LT(static_cast<size_t>(type_index), dex_cache->NumResolvedTypes()); - return soa.AddLocalReference<jobject>(dex_cache->GetResolvedType(type_index)); + return soa.AddLocalReference<jobject>(dex_cache->GetResolvedType(dex::TypeIndex(type_index))); } static jobject DexCache_getResolvedString(JNIEnv* env, jobject javaDexCache, jint string_index) { @@ -68,7 +69,7 @@ static void DexCache_setResolvedType(JNIEnv* env, jobject javaDexCache, jint typ ScopedFastNativeObjectAccess soa(env); ObjPtr<mirror::DexCache> dex_cache = soa.Decode<mirror::DexCache>(javaDexCache); CHECK_LT(static_cast<size_t>(type_index), dex_cache->NumResolvedTypes()); - dex_cache->SetResolvedType(type_index, soa.Decode<mirror::Class>(type)); + dex_cache->SetResolvedType(dex::TypeIndex(type_index), soa.Decode<mirror::Class>(type)); } static void DexCache_setResolvedString(JNIEnv* env, jobject javaDexCache, jint string_index, diff --git a/runtime/oat_file.cc b/runtime/oat_file.cc index c14b6169fb..b120a69642 100644 --- a/runtime/oat_file.cc +++ b/runtime/oat_file.cc @@ -38,6 +38,7 @@ #include "base/stl_util.h" #include "base/systrace.h" #include "base/unix_file/fd_file.h" +#include "dex_file_types.h" #include "elf_file.h" #include "elf_utils.h" #include "gc_root.h" @@ -1342,7 +1343,7 @@ const DexFile::ClassDef* OatFile::OatDexFile::FindClassDef(const DexFile& dex_fi } const DexFile::TypeId* type_id = dex_file.FindTypeId(descriptor); if (type_id != nullptr) { - uint16_t type_idx = dex_file.GetIndexForTypeId(*type_id); + dex::TypeIndex type_idx = dex_file.GetIndexForTypeId(*type_id); return dex_file.FindClassDef(type_idx); } return nullptr; diff --git a/runtime/openjdkjvmti/transform.cc b/runtime/openjdkjvmti/transform.cc index fa2983c19c..7bb5205f05 100644 --- a/runtime/openjdkjvmti/transform.cc +++ b/runtime/openjdkjvmti/transform.cc @@ -33,6 +33,7 @@ #include "class_linker.h" #include "dex_file.h" +#include "dex_file_types.h" #include "gc_root-inl.h" #include "globals.h" #include "jni_env_ext-inl.h" @@ -108,10 +109,10 @@ static void InvalidateExistingMethods(art::Thread* self, // Find the code_item for the method then find the dex_method_index and dex_code_item_offset to // set. const art::DexFile::StringId* new_name_id = dex_file->FindStringId(method.GetName()); - uint16_t method_return_idx = + art::dex::TypeIndex method_return_idx = dex_file->GetIndexForTypeId(*dex_file->FindTypeId(method.GetReturnTypeDescriptor())); const auto* old_type_list = method.GetParameterTypeList(); - std::vector<uint16_t> new_type_list; + std::vector<art::dex::TypeIndex> new_type_list; for (uint32_t i = 0; old_type_list != nullptr && i < old_type_list->Size(); i++) { new_type_list.push_back( dex_file->GetIndexForTypeId( diff --git a/runtime/reflection.cc b/runtime/reflection.cc index 3128380f76..8446b525ad 100644 --- a/runtime/reflection.cc +++ b/runtime/reflection.cc @@ -363,7 +363,7 @@ static void CheckMethodArguments(JavaVMExt* vm, ArtMethod* m, uint32_t* args) Thread* const self = Thread::Current(); PointerSize pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize(); for (uint32_t i = 0; i < num_params; i++) { - uint16_t type_idx = params->GetTypeItem(i).type_idx_; + dex::TypeIndex type_idx = params->GetTypeItem(i).type_idx_; ObjPtr<mirror::Class> param_type(m->GetClassFromTypeIndex(type_idx, true /* resolve*/, pointer_size)); diff --git a/runtime/utils/dex_cache_arrays_layout-inl.h b/runtime/utils/dex_cache_arrays_layout-inl.h index c7875b56ec..bd1b044dae 100644 --- a/runtime/utils/dex_cache_arrays_layout-inl.h +++ b/runtime/utils/dex_cache_arrays_layout-inl.h @@ -65,8 +65,8 @@ static constexpr PointerSize GcRootAsPointerSize() { return PointerSize::k32; } -inline size_t DexCacheArraysLayout::TypeOffset(uint32_t type_idx) const { - return types_offset_ + ElementOffset(GcRootAsPointerSize<mirror::Class>(), type_idx); +inline size_t DexCacheArraysLayout::TypeOffset(dex::TypeIndex type_idx) const { + return types_offset_ + ElementOffset(GcRootAsPointerSize<mirror::Class>(), type_idx.index_); } inline size_t DexCacheArraysLayout::TypesSize(size_t num_elements) const { diff --git a/runtime/utils/dex_cache_arrays_layout.h b/runtime/utils/dex_cache_arrays_layout.h index ae3bfab38c..7d4b23a8dd 100644 --- a/runtime/utils/dex_cache_arrays_layout.h +++ b/runtime/utils/dex_cache_arrays_layout.h @@ -18,6 +18,7 @@ #define ART_RUNTIME_UTILS_DEX_CACHE_ARRAYS_LAYOUT_H_ #include "dex_file.h" +#include "dex_file_types.h" namespace art { @@ -59,7 +60,7 @@ class DexCacheArraysLayout { return types_offset_; } - size_t TypeOffset(uint32_t type_idx) const; + size_t TypeOffset(dex::TypeIndex type_idx) const; size_t TypesSize(size_t num_elements) const; diff --git a/runtime/verifier/method_verifier-inl.h b/runtime/verifier/method_verifier-inl.h index def61db81a..363bd8f54f 100644 --- a/runtime/verifier/method_verifier-inl.h +++ b/runtime/verifier/method_verifier-inl.h @@ -74,7 +74,7 @@ inline bool MethodVerifier::HasFailures() const { return !failure_messages_.empty(); } -inline const RegType& MethodVerifier::ResolveCheckedClass(uint32_t class_idx) { +inline const RegType& MethodVerifier::ResolveCheckedClass(dex::TypeIndex class_idx) { DCHECK(!HasFailures()); const RegType& result = ResolveClassAndCheckAccess(class_idx); DCHECK(!HasFailures()); diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc index ed24611801..7137db8773 100644 --- a/runtime/verifier/method_verifier.cc +++ b/runtime/verifier/method_verifier.cc @@ -1072,7 +1072,7 @@ bool MethodVerifier::ScanTryCatchBlocks() { GetInstructionFlags(dex_pc).SetBranchTarget(); // Ensure exception types are resolved so that they don't need resolution to be delivered, // unresolved exception types will be ignored by exception delivery - if (iterator.GetHandlerTypeIndex() != DexFile::kDexNoIndex16) { + if (iterator.GetHandlerTypeIndex().IsValid()) { mirror::Class* exception_type = linker->ResolveType(*dex_file_, iterator.GetHandlerTypeIndex(), dex_cache_, class_loader_); @@ -1155,13 +1155,13 @@ bool MethodVerifier::VerifyInstruction(const Instruction* inst, uint32_t code_of result = result && CheckMethodIndex(inst->VRegB()); break; case Instruction::kVerifyRegBNewInstance: - result = result && CheckNewInstance(inst->VRegB()); + result = result && CheckNewInstance(dex::TypeIndex(inst->VRegB())); break; case Instruction::kVerifyRegBString: result = result && CheckStringIndex(inst->VRegB()); break; case Instruction::kVerifyRegBType: - result = result && CheckTypeIndex(inst->VRegB()); + result = result && CheckTypeIndex(dex::TypeIndex(inst->VRegB())); break; case Instruction::kVerifyRegBWide: result = result && CheckWideRegisterIndex(inst->VRegB()); @@ -1175,10 +1175,10 @@ bool MethodVerifier::VerifyInstruction(const Instruction* inst, uint32_t code_of result = result && CheckFieldIndex(inst->VRegC()); break; case Instruction::kVerifyRegCNewArray: - result = result && CheckNewArray(inst->VRegC()); + result = result && CheckNewArray(dex::TypeIndex(inst->VRegC())); break; case Instruction::kVerifyRegCType: - result = result && CheckTypeIndex(inst->VRegC()); + result = result && CheckTypeIndex(dex::TypeIndex(inst->VRegC())); break; case Instruction::kVerifyRegCWide: result = result && CheckWideRegisterIndex(inst->VRegC()); @@ -1270,9 +1270,9 @@ inline bool MethodVerifier::CheckMethodIndex(uint32_t idx) { return true; } -inline bool MethodVerifier::CheckNewInstance(uint32_t idx) { - if (idx >= dex_file_->GetHeader().type_ids_size_) { - Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad type index " << idx << " (max " +inline bool MethodVerifier::CheckNewInstance(dex::TypeIndex idx) { + if (idx.index_ >= dex_file_->GetHeader().type_ids_size_) { + Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad type index " << idx.index_ << " (max " << dex_file_->GetHeader().type_ids_size_ << ")"; return false; } @@ -1298,18 +1298,18 @@ inline bool MethodVerifier::CheckStringIndex(uint32_t idx) { return true; } -inline bool MethodVerifier::CheckTypeIndex(uint32_t idx) { - if (idx >= dex_file_->GetHeader().type_ids_size_) { - Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad type index " << idx << " (max " +inline bool MethodVerifier::CheckTypeIndex(dex::TypeIndex idx) { + if (idx.index_ >= dex_file_->GetHeader().type_ids_size_) { + Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad type index " << idx.index_ << " (max " << dex_file_->GetHeader().type_ids_size_ << ")"; return false; } return true; } -bool MethodVerifier::CheckNewArray(uint32_t idx) { - if (idx >= dex_file_->GetHeader().type_ids_size_) { - Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad type index " << idx << " (max " +bool MethodVerifier::CheckNewArray(dex::TypeIndex idx) { + if (idx.index_ >= dex_file_->GetHeader().type_ids_size_) { + Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad type index " << idx.index_ << " (max " << dex_file_->GetHeader().type_ids_size_ << ")"; return false; } @@ -1945,7 +1945,7 @@ bool MethodVerifier::CodeFlowVerifyMethod() { // Returns the index of the first final instance field of the given class, or kDexNoIndex if there // is no such field. -static uint32_t GetFirstFinalInstanceFieldIndex(const DexFile& dex_file, uint16_t type_idx) { +static uint32_t GetFirstFinalInstanceFieldIndex(const DexFile& dex_file, dex::TypeIndex type_idx) { const DexFile::ClassDef* class_def = dex_file.FindClassDef(type_idx); DCHECK(class_def != nullptr); const uint8_t* class_data = dex_file.GetClassData(*class_def); @@ -2293,7 +2293,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 - const RegType& res_type = ResolveClassAndCheckAccess(inst->VRegB_21c()); + const RegType& res_type = ResolveClassAndCheckAccess(dex::TypeIndex(inst->VRegB_21c())); // Register holds class, ie its type is class, on error it will hold Conflict. work_line_->SetRegisterType<LockOp::kClear>( this, inst->VRegA_21c(), res_type.IsConflict() ? res_type @@ -2363,7 +2363,7 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) { * dec_insn.vA when branching to a handler. */ const bool is_checkcast = (inst->Opcode() == Instruction::CHECK_CAST); - const uint32_t type_idx = (is_checkcast) ? inst->VRegB_21c() : inst->VRegC_22c(); + const dex::TypeIndex type_idx((is_checkcast) ? inst->VRegB_21c() : inst->VRegC_22c()); const RegType& res_type = ResolveClassAndCheckAccess(type_idx); if (res_type.IsConflict()) { // If this is a primitive type, fail HARD. @@ -2433,7 +2433,7 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) { break; } case Instruction::NEW_INSTANCE: { - const RegType& res_type = ResolveClassAndCheckAccess(inst->VRegB_21c()); + const RegType& res_type = ResolveClassAndCheckAccess(dex::TypeIndex(inst->VRegB_21c())); if (res_type.IsConflict()) { DCHECK_NE(failures_.size(), 0U); break; // bad class @@ -2645,7 +2645,8 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) { // 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. const RegType& orig_type = work_line_->GetRegisterType(this, instance_of_inst->VRegB_22c()); - const RegType& cast_type = ResolveClassAndCheckAccess(instance_of_inst->VRegC_22c()); + const RegType& cast_type = ResolveClassAndCheckAccess( + dex::TypeIndex(instance_of_inst->VRegC_22c())); if (!orig_type.Equals(cast_type) && !cast_type.IsUnresolvedTypes() && !orig_type.IsUnresolvedTypes() && @@ -2883,7 +2884,8 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) { if (return_type == nullptr) { uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c(); const DexFile::MethodId& method_id = dex_file_->GetMethodId(method_idx); - uint32_t return_type_idx = dex_file_->GetProtoId(method_id.proto_idx_).return_type_idx_; + dex::TypeIndex return_type_idx = + dex_file_->GetProtoId(method_id.proto_idx_).return_type_idx_; const char* descriptor = dex_file_->StringByTypeIdx(return_type_idx); return_type = ®_types_.FromDescriptor(GetClassLoader(), descriptor, false); } @@ -2906,7 +2908,8 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) { uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c(); const DexFile::MethodId& method_id = dex_file_->GetMethodId(method_idx); is_constructor = strcmp("<init>", dex_file_->StringDataByIdx(method_id.name_idx_)) == 0; - uint32_t return_type_idx = dex_file_->GetProtoId(method_id.proto_idx_).return_type_idx_; + dex::TypeIndex return_type_idx = + dex_file_->GetProtoId(method_id.proto_idx_).return_type_idx_; return_type_descriptor = dex_file_->StringByTypeIdx(return_type_idx); } else { is_constructor = called_method->IsConstructor(); @@ -2982,7 +2985,8 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) { if (called_method == nullptr) { uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c(); const DexFile::MethodId& method_id = dex_file_->GetMethodId(method_idx); - uint32_t return_type_idx = dex_file_->GetProtoId(method_id.proto_idx_).return_type_idx_; + dex::TypeIndex return_type_idx = + dex_file_->GetProtoId(method_id.proto_idx_).return_type_idx_; descriptor = dex_file_->StringByTypeIdx(return_type_idx); } else { descriptor = called_method->GetReturnTypeDescriptor(); @@ -3036,7 +3040,8 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) { if (abs_method == nullptr) { uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c(); const DexFile::MethodId& method_id = dex_file_->GetMethodId(method_idx); - uint32_t return_type_idx = dex_file_->GetProtoId(method_id.proto_idx_).return_type_idx_; + dex::TypeIndex return_type_idx = + dex_file_->GetProtoId(method_id.proto_idx_).return_type_idx_; descriptor = dex_file_->StringByTypeIdx(return_type_idx); } else { descriptor = abs_method->GetReturnTypeDescriptor(); @@ -3500,8 +3505,8 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) { ClassLinker* linker = Runtime::Current()->GetClassLinker(); for (; iterator.HasNext(); iterator.Next()) { - uint16_t handler_type_idx = iterator.GetHandlerTypeIndex(); - if (handler_type_idx == DexFile::kDexNoIndex16) { + dex::TypeIndex handler_type_idx = iterator.GetHandlerTypeIndex(); + if (!handler_type_idx.IsValid()) { has_catch_all_handler = true; } else { // It is also a catch-all if it is java.lang.Throwable. @@ -3628,7 +3633,7 @@ inline bool MethodVerifier::IsInstantiableOrPrimitive(mirror::Class* klass) { return klass->IsInstantiable() || klass->IsPrimitive(); } -const RegType& MethodVerifier::ResolveClassAndCheckAccess(uint32_t class_idx) { +const RegType& MethodVerifier::ResolveClassAndCheckAccess(dex::TypeIndex class_idx) { mirror::Class* klass = dex_cache_->GetResolvedType(class_idx); const RegType* result = nullptr; if (klass != nullptr) { @@ -3684,7 +3689,7 @@ const RegType& MethodVerifier::GetCaughtExceptionType() { CatchHandlerIterator iterator(handlers_ptr); for (; iterator.HasNext(); iterator.Next()) { if (iterator.GetHandlerAddress() == (uint32_t) work_insn_idx_) { - if (iterator.GetHandlerTypeIndex() == DexFile::kDexNoIndex16) { + if (!iterator.GetHandlerTypeIndex().IsValid()) { common_super = ®_types_.JavaLangThrowable(false); } else { const RegType& exception = ResolveClassAndCheckAccess(iterator.GetHandlerTypeIndex()); @@ -3941,7 +3946,7 @@ ArtMethod* MethodVerifier::VerifyInvocationArgsFromIterator( klass->CannotBeAssignedFromOtherTypes()); } else { const uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c(); - const uint16_t class_idx = dex_file_->GetMethodId(method_idx).class_idx_; + const dex::TypeIndex class_idx = dex_file_->GetMethodId(method_idx).class_idx_; res_method_class = ®_types_.FromDescriptor( GetClassLoader(), dex_file_->StringByTypeIdx(class_idx), @@ -4078,7 +4083,7 @@ ArtMethod* MethodVerifier::VerifyInvocationArgs( // If we're using invoke-super(method), make sure that the executing method's class' superclass // has a vtable entry for the target method. Or the target is on a interface. if (method_type == METHOD_SUPER) { - uint16_t class_idx = dex_file_->GetMethodId(method_idx).class_idx_; + dex::TypeIndex class_idx = dex_file_->GetMethodId(method_idx).class_idx_; const RegType& reference_type = reg_types_.FromDescriptor( GetClassLoader(), dex_file_->StringByTypeIdx(class_idx), @@ -4287,16 +4292,16 @@ ArtMethod* MethodVerifier::VerifyInvokeVirtualQuickArgs(const Instruction* inst, } void MethodVerifier::VerifyNewArray(const Instruction* inst, bool is_filled, bool is_range) { - uint32_t type_idx; + dex::TypeIndex type_idx; if (!is_filled) { DCHECK_EQ(inst->Opcode(), Instruction::NEW_ARRAY); - type_idx = inst->VRegC_22c(); + type_idx = dex::TypeIndex(inst->VRegC_22c()); } else if (!is_range) { DCHECK_EQ(inst->Opcode(), Instruction::FILLED_NEW_ARRAY); - type_idx = inst->VRegB_35c(); + type_idx = dex::TypeIndex(inst->VRegB_35c()); } else { DCHECK_EQ(inst->Opcode(), Instruction::FILLED_NEW_ARRAY_RANGE); - type_idx = inst->VRegB_3rc(); + type_idx = dex::TypeIndex(inst->VRegB_3rc()); } const RegType& res_type = ResolveClassAndCheckAccess(type_idx); if (res_type.IsConflict()) { // bad class @@ -5011,7 +5016,7 @@ const RegType& MethodVerifier::GetMethodReturnType() { if (return_type_ == nullptr) { const DexFile::MethodId& method_id = dex_file_->GetMethodId(dex_method_idx_); const DexFile::ProtoId& proto_id = dex_file_->GetMethodPrototype(method_id); - uint16_t return_type_idx = proto_id.return_type_idx_; + dex::TypeIndex return_type_idx = proto_id.return_type_idx_; const char* descriptor = dex_file_->GetTypeDescriptor(dex_file_->GetTypeId(return_type_idx)); return_type_ = ®_types_.FromDescriptor(GetClassLoader(), descriptor, false); } diff --git a/runtime/verifier/method_verifier.h b/runtime/verifier/method_verifier.h index c6ce583ab4..f3faecd9a7 100644 --- a/runtime/verifier/method_verifier.h +++ b/runtime/verifier/method_verifier.h @@ -27,6 +27,7 @@ #include "base/stl_util.h" #include "base/value_object.h" #include "dex_file.h" +#include "dex_file_types.h" #include "handle.h" #include "instruction_flags.h" #include "method_reference.h" @@ -261,7 +262,7 @@ class MethodVerifier { return have_any_pending_runtime_throw_failure_; } - const RegType& ResolveCheckedClass(uint32_t class_idx) + const RegType& ResolveCheckedClass(dex::TypeIndex class_idx) REQUIRES_SHARED(Locks::mutator_lock_); // Returns the method of a quick invoke or null if it cannot be found. ArtMethod* GetQuickInvokedMethod(const Instruction* inst, RegisterLine* reg_line, @@ -471,18 +472,18 @@ class MethodVerifier { // Perform static checks on a "new-instance" instruction. Specifically, make sure the class // reference isn't for an array class. - bool CheckNewInstance(uint32_t idx); + bool CheckNewInstance(dex::TypeIndex idx); /* Ensure that the string index is in the valid range. */ bool CheckStringIndex(uint32_t idx); // Perform static checks on an instruction that takes a class constant. Ensure that the class // index is in the valid range. - bool CheckTypeIndex(uint32_t idx); + bool CheckTypeIndex(dex::TypeIndex idx); // Perform static checks on a "new-array" instruction. Specifically, make sure they aren't // creating an array of arrays that causes the number of dimensions to exceed 255. - bool CheckNewArray(uint32_t idx); + bool CheckNewArray(dex::TypeIndex idx); // Verify an array data table. "cur_offset" is the offset of the fill-array-data instruction. bool CheckArrayData(uint32_t cur_offset); @@ -625,7 +626,7 @@ class MethodVerifier { // Resolves a class based on an index and performs access checks to ensure the referrer can // access the resolved class. - const RegType& ResolveClassAndCheckAccess(uint32_t class_idx) + const RegType& ResolveClassAndCheckAccess(dex::TypeIndex class_idx) REQUIRES_SHARED(Locks::mutator_lock_); /* diff --git a/runtime/verifier/verifier_deps.cc b/runtime/verifier/verifier_deps.cc index c395612d72..8a0f4cfa31 100644 --- a/runtime/verifier/verifier_deps.cc +++ b/runtime/verifier/verifier_deps.cc @@ -137,7 +137,7 @@ bool VerifierDeps::IsInClassPath(ObjPtr<mirror::Class> klass) const { } void VerifierDeps::AddClassResolution(const DexFile& dex_file, - uint16_t type_idx, + dex::TypeIndex type_idx, mirror::Class* klass) { DexFileDeps* dex_deps = GetDexFileDeps(dex_file); if (dex_deps == nullptr) { @@ -286,7 +286,7 @@ static inline VerifierDeps* GetVerifierDepsSingleton() { } void VerifierDeps::MaybeRecordVerificationStatus(const DexFile& dex_file, - uint16_t type_idx, + dex::TypeIndex type_idx, MethodVerifier::FailureKind failure_kind) { if (failure_kind == MethodVerifier::kNoFailure) { // We only record classes that did not fully verify at compile time. @@ -302,7 +302,7 @@ void VerifierDeps::MaybeRecordVerificationStatus(const DexFile& dex_file, } void VerifierDeps::MaybeRecordClassResolution(const DexFile& dex_file, - uint16_t type_idx, + dex::TypeIndex type_idx, mirror::Class* klass) { VerifierDeps* singleton = GetVerifierDepsSingleton(); if (singleton != nullptr) { @@ -340,36 +340,62 @@ void VerifierDeps::MaybeRecordAssignability(const DexFile& dex_file, } } +namespace { + static inline uint32_t DecodeUint32WithOverflowCheck(const uint8_t** in, const uint8_t* end) { CHECK_LT(*in, end); return DecodeUnsignedLeb128(in); } +template<typename T> inline uint32_t Encode(T in); + +template<> inline uint32_t Encode<uint16_t>(uint16_t in) { + return in; +} +template<> inline uint32_t Encode<uint32_t>(uint32_t in) { + return in; +} +template<> inline uint32_t Encode<dex::TypeIndex>(dex::TypeIndex in) { + return in.index_; +} + +template<typename T> inline T Decode(uint32_t in); + +template<> inline uint16_t Decode<uint16_t>(uint32_t in) { + return dchecked_integral_cast<uint16_t>(in); +} +template<> inline uint32_t Decode<uint32_t>(uint32_t in) { + return in; +} +template<> inline dex::TypeIndex Decode<dex::TypeIndex>(uint32_t in) { + return dex::TypeIndex(in); +} + template<typename T1, typename T2> static inline void EncodeTuple(std::vector<uint8_t>* out, const std::tuple<T1, T2>& t) { - EncodeUnsignedLeb128(out, std::get<0>(t)); - EncodeUnsignedLeb128(out, std::get<1>(t)); + EncodeUnsignedLeb128(out, Encode(std::get<0>(t))); + EncodeUnsignedLeb128(out, Encode(std::get<1>(t))); } template<typename T1, typename T2> static inline void DecodeTuple(const uint8_t** in, const uint8_t* end, std::tuple<T1, T2>* t) { - T1 v1 = static_cast<T1>(DecodeUint32WithOverflowCheck(in, end)); - T2 v2 = static_cast<T2>(DecodeUint32WithOverflowCheck(in, end)); + T1 v1 = Decode<T1>(DecodeUint32WithOverflowCheck(in, end)); + T2 v2 = Decode<T2>(DecodeUint32WithOverflowCheck(in, end)); *t = std::make_tuple(v1, v2); } template<typename T1, typename T2, typename T3> static inline void EncodeTuple(std::vector<uint8_t>* out, const std::tuple<T1, T2, T3>& t) { - EncodeUnsignedLeb128(out, std::get<0>(t)); - EncodeUnsignedLeb128(out, std::get<1>(t)); - EncodeUnsignedLeb128(out, std::get<2>(t)); + EncodeUnsignedLeb128(out, Encode(std::get<0>(t))); + EncodeUnsignedLeb128(out, Encode(std::get<1>(t))); + EncodeUnsignedLeb128(out, Encode(std::get<2>(t))); } template<typename T1, typename T2, typename T3> static inline void DecodeTuple(const uint8_t** in, const uint8_t* end, std::tuple<T1, T2, T3>* t) { - T1 v1 = static_cast<T1>(DecodeUint32WithOverflowCheck(in, end)); - T2 v2 = static_cast<T2>(DecodeUint32WithOverflowCheck(in, end)); - T3 v3 = static_cast<T2>(DecodeUint32WithOverflowCheck(in, end)); + T1 v1 = Decode<T1>(DecodeUint32WithOverflowCheck(in, end)); + T2 v2 = Decode<T2>(DecodeUint32WithOverflowCheck(in, end)); + T3 v3 = Decode<T2>(DecodeUint32WithOverflowCheck(in, end)); *t = std::make_tuple(v1, v2, v3); } @@ -381,11 +407,12 @@ static inline void EncodeSet(std::vector<uint8_t>* out, const std::set<T>& set) } } +template <typename T> static inline void EncodeUint16Vector(std::vector<uint8_t>* out, - const std::vector<uint16_t>& vector) { + const std::vector<T>& vector) { EncodeUnsignedLeb128(out, vector.size()); - for (uint16_t entry : vector) { - EncodeUnsignedLeb128(out, entry); + for (const T& entry : vector) { + EncodeUnsignedLeb128(out, Encode(entry)); } } @@ -400,14 +427,16 @@ static inline void DecodeSet(const uint8_t** in, const uint8_t* end, std::set<T> } } +template<typename T> static inline void DecodeUint16Vector(const uint8_t** in, const uint8_t* end, - std::vector<uint16_t>* vector) { + std::vector<T>* vector) { DCHECK(vector->empty()); size_t num_entries = DecodeUint32WithOverflowCheck(in, end); vector->reserve(num_entries); for (size_t i = 0; i < num_entries; ++i) { - vector->push_back(dchecked_integral_cast<uint16_t>(DecodeUint32WithOverflowCheck(in, end))); + vector->push_back( + Decode<T>(dchecked_integral_cast<uint16_t>(DecodeUint32WithOverflowCheck(in, end)))); } } @@ -436,6 +465,8 @@ static inline void DecodeStringVector(const uint8_t** in, } } +} // namespace + void VerifierDeps::Encode(const std::vector<const DexFile*>& dex_files, std::vector<uint8_t>* buffer) const { MutexLock mu(Thread::Current(), *Locks::verifier_deps_lock_); @@ -599,7 +630,7 @@ void VerifierDeps::Dump(VariableIndentationOutputStream* vios) const { } } - for (uint16_t type_index : dep.second->unverified_classes_) { + for (dex::TypeIndex type_index : dep.second->unverified_classes_) { vios->Stream() << dex_file.StringByTypeIdx(type_index) << " is expected to be verified at runtime\n"; diff --git a/runtime/verifier/verifier_deps.h b/runtime/verifier/verifier_deps.h index 7b419d4260..23e22d956d 100644 --- a/runtime/verifier/verifier_deps.h +++ b/runtime/verifier/verifier_deps.h @@ -57,14 +57,14 @@ class VerifierDeps { // Record the verification status of the class at `type_idx`. static void MaybeRecordVerificationStatus(const DexFile& dex_file, - uint16_t type_idx, + dex::TypeIndex type_idx, MethodVerifier::FailureKind failure_kind) REQUIRES(!Locks::verifier_deps_lock_); // Record the outcome `klass` of resolving type `type_idx` from `dex_file`. // If `klass` is null, the class is assumed unresolved. static void MaybeRecordClassResolution(const DexFile& dex_file, - uint16_t type_idx, + dex::TypeIndex type_idx, mirror::Class* klass) REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Locks::verifier_deps_lock_); @@ -116,7 +116,7 @@ class VerifierDeps { // NO_THREAD_SAFETY_ANALSYS, as this is queried when the VerifierDeps are // fully created. - const std::vector<uint16_t>& GetUnverifiedClasses(const DexFile& dex_file) const + const std::vector<dex::TypeIndex>& GetUnverifiedClasses(const DexFile& dex_file) const NO_THREAD_SAFETY_ANALYSIS { return GetDexFileDeps(dex_file)->unverified_classes_; } @@ -124,15 +124,15 @@ class VerifierDeps { private: static constexpr uint16_t kUnresolvedMarker = static_cast<uint16_t>(-1); - using ClassResolutionBase = std::tuple<uint32_t, uint16_t>; + using ClassResolutionBase = std::tuple<dex::TypeIndex, uint16_t>; struct ClassResolution : public ClassResolutionBase { ClassResolution() = default; ClassResolution(const ClassResolution&) = default; - ClassResolution(uint32_t type_idx, uint16_t access_flags) + ClassResolution(dex::TypeIndex type_idx, uint16_t access_flags) : ClassResolutionBase(type_idx, access_flags) {} bool IsResolved() const { return GetAccessFlags() != kUnresolvedMarker; } - uint32_t GetDexTypeIndex() const { return std::get<0>(*this); } + dex::TypeIndex GetDexTypeIndex() const { return std::get<0>(*this); } uint16_t GetAccessFlags() const { return std::get<1>(*this); } }; @@ -193,7 +193,7 @@ class VerifierDeps { std::set<MethodResolution> interface_methods_; // List of classes that were not fully verified in that dex file. - std::vector<uint16_t> unverified_classes_; + std::vector<dex::TypeIndex> unverified_classes_; bool Equals(const DexFileDeps& rhs) const; }; @@ -238,7 +238,7 @@ class VerifierDeps { REQUIRES(Locks::verifier_deps_lock_); void AddClassResolution(const DexFile& dex_file, - uint16_t type_idx, + dex::TypeIndex type_idx, mirror::Class* klass) REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Locks::verifier_deps_lock_); |