From 22384aeab988df7fa5ccdc48a668589c5f602c39 Mon Sep 17 00:00:00 2001 From: Nicolas Geoffray Date: Mon, 12 Dec 2016 22:33:36 +0000 Subject: Revert "Revert "Add kJitTableAddress for HLoadClass."" This reverts commit d2d5262c8370309e1f2a009f00aafc24f1cf00a0. Change-Id: I6149d5c7d5df0b0fc5cb646a802a2eea8d01ac08 --- compiler/optimizing/code_generator.cc | 8 ++ compiler/optimizing/code_generator.h | 13 ++- compiler/optimizing/code_generator_arm.cc | 64 ++++++----- compiler/optimizing/code_generator_arm.h | 13 ++- compiler/optimizing/code_generator_arm64.cc | 60 ++++++----- compiler/optimizing/code_generator_arm64.h | 13 ++- compiler/optimizing/code_generator_arm_vixl.cc | 4 +- compiler/optimizing/code_generator_mips.cc | 17 +-- compiler/optimizing/code_generator_x86.cc | 58 ++++++---- compiler/optimizing/code_generator_x86.h | 8 ++ compiler/optimizing/code_generator_x86_64.cc | 72 +++++++------ compiler/optimizing/code_generator_x86_64.h | 9 ++ compiler/optimizing/inliner.cc | 2 +- compiler/optimizing/nodes.cc | 4 +- compiler/optimizing/nodes.h | 15 +-- compiler/optimizing/optimizing_compiler.cc | 144 +++++++++++++------------ compiler/optimizing/sharpening.cc | 24 +++-- compiler/optimizing/sharpening.h | 7 +- 18 files changed, 316 insertions(+), 219 deletions(-) (limited to 'compiler/optimizing') diff --git a/compiler/optimizing/code_generator.cc b/compiler/optimizing/code_generator.cc index fa6a5225e7..402eeee65f 100644 --- a/compiler/optimizing/code_generator.cc +++ b/compiler/optimizing/code_generator.cc @@ -1402,6 +1402,14 @@ void CodeGenerator::EmitJitRoots(uint8_t* code, entry.second = index; ++index; } + for (auto& entry : jit_class_roots_) { + // Update the `roots` with the class, and replace the address temporarily + // stored to the index in the table. + uint64_t address = entry.second; + roots->Set(index, reinterpret_cast*>(address)->AsMirrorPtr()); + entry.second = index; + ++index; + } EmitJitRootPatches(code, roots_data); } diff --git a/compiler/optimizing/code_generator.h b/compiler/optimizing/code_generator.h index 4b11e7c699..2e2c3c00af 100644 --- a/compiler/optimizing/code_generator.h +++ b/compiler/optimizing/code_generator.h @@ -34,6 +34,7 @@ #include "stack_map_stream.h" #include "string_reference.h" #include "utils/label.h" +#include "utils/type_reference.h" namespace art { @@ -343,7 +344,7 @@ class CodeGenerator : public DeletableArenaObject { void BuildStackMaps(MemoryRegion region, const DexFile::CodeItem& code_item); size_t ComputeStackMapsSize(); size_t GetNumberOfJitRoots() const { - return jit_string_roots_.size(); + return jit_string_roots_.size() + jit_class_roots_.size(); } // Fills the `literals` array with literals collected during code generation. @@ -611,6 +612,8 @@ class CodeGenerator : public DeletableArenaObject { block_order_(nullptr), jit_string_roots_(StringReferenceValueComparator(), graph->GetArena()->Adapter(kArenaAllocCodeGenerator)), + jit_class_roots_(TypeReferenceValueComparator(), + graph->GetArena()->Adapter(kArenaAllocCodeGenerator)), disasm_info_(nullptr), stats_(stats), graph_(graph), @@ -681,6 +684,7 @@ class CodeGenerator : public DeletableArenaObject { virtual void EmitJitRootPatches(uint8_t* code ATTRIBUTE_UNUSED, const uint8_t* roots_data ATTRIBUTE_UNUSED) { DCHECK_EQ(jit_string_roots_.size(), 0u); + DCHECK_EQ(jit_class_roots_.size(), 0u); } // Frame size required for this method. @@ -711,7 +715,12 @@ class CodeGenerator : public DeletableArenaObject { // Maps a StringReference (dex_file, string_index) to the index in the literal table. // Entries are intially added with a 0 index, and `EmitJitRoots` will compute all the // indices. - ArenaSafeMap jit_string_roots_; + ArenaSafeMap jit_string_roots_; + + // Maps a ClassReference (dex_file, type_index) to the index in the literal table. + // Entries are intially added with a pointer in the handle zone, and `EmitJitRoots` + // will compute all the indices. + ArenaSafeMap jit_class_roots_; DisassemblyInformation* disasm_info_; diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc index ed6eef1b55..866f2c58d8 100644 --- a/compiler/optimizing/code_generator_arm.cc +++ b/compiler/optimizing/code_generator_arm.cc @@ -1216,7 +1216,9 @@ CodeGeneratorARM::CodeGeneratorARM(HGraph* graph, boot_image_address_patches_(std::less(), graph->GetArena()->Adapter(kArenaAllocCodeGenerator)), jit_string_patches_(StringReferenceValueComparator(), - graph->GetArena()->Adapter(kArenaAllocCodeGenerator)) { + graph->GetArena()->Adapter(kArenaAllocCodeGenerator)), + jit_class_patches_(TypeReferenceValueComparator(), + graph->GetArena()->Adapter(kArenaAllocCodeGenerator)) { // Always save the LR register to mimic Quick. AddAllocatedRegister(Location::RegisterLocation(LR)); } @@ -5712,8 +5714,7 @@ HLoadClass::LoadKind CodeGeneratorARM::GetSupportedLoadClassKind( break; case HLoadClass::LoadKind::kBootImageAddress: break; - case HLoadClass::LoadKind::kDexCacheAddress: - DCHECK(Runtime::Current()->UseJitCompilation()); + case HLoadClass::LoadKind::kJitTableAddress: break; case HLoadClass::LoadKind::kDexCachePcRelative: DCHECK(!Runtime::Current()->UseJitCompilation()); @@ -5814,22 +5815,12 @@ void InstructionCodeGeneratorARM::VisitLoadClass(HLoadClass* cls) { __ LoadLiteral(out, codegen_->DeduplicateBootImageAddressLiteral(address)); break; } - case HLoadClass::LoadKind::kDexCacheAddress: { - DCHECK_NE(cls->GetAddress(), 0u); - uint32_t address = dchecked_integral_cast(cls->GetAddress()); - // 16-bit LDR immediate has a 5-bit offset multiplied by the size and that gives - // a 128B range. To try and reduce the number of literals if we load multiple types, - // simply split the dex cache address to a 128B aligned base loaded from a literal - // and the remaining offset embedded in the load. - static_assert(sizeof(GcRoot) == 4u, "Expected GC root to be 4 bytes."); - DCHECK_ALIGNED(cls->GetAddress(), 4u); - constexpr size_t offset_bits = /* encoded bits */ 5 + /* scale */ 2; - uint32_t base_address = address & ~MaxInt(offset_bits); - uint32_t offset = address & MaxInt(offset_bits); - __ LoadLiteral(out, codegen_->DeduplicateDexCacheAddressLiteral(base_address)); - // /* GcRoot */ out = *(base_address + offset) - GenerateGcRootFieldLoad(cls, out_loc, out, offset, read_barrier_option); - generate_null_check = !cls->IsInDexCache(); + case HLoadClass::LoadKind::kJitTableAddress: { + __ LoadLiteral(out, codegen_->DeduplicateJitClassLiteral(cls->GetDexFile(), + cls->GetTypeIndex(), + cls->GetAddress())); + // /* GcRoot */ out = *out + GenerateGcRootFieldLoad(cls, out_loc, out, /* offset */ 0, kCompilerReadBarrierOption); break; } case HLoadClass::LoadKind::kDexCachePcRelative: { @@ -7391,6 +7382,15 @@ Literal* CodeGeneratorARM::DeduplicateJitStringLiteral(const DexFile& dex_file, [this]() { return __ NewLiteral(/* placeholder */ 0u); }); } +Literal* CodeGeneratorARM::DeduplicateJitClassLiteral(const DexFile& dex_file, + dex::TypeIndex type_index, + uint64_t address) { + jit_class_roots_.Overwrite(TypeReference(&dex_file, type_index), address); + return jit_class_patches_.GetOrCreate( + TypeReference(&dex_file, type_index), + [this]() { return __ NewLiteral(/* placeholder */ 0u); }); +} + template inline void CodeGeneratorARM::EmitPcRelativeLinkerPatches( const ArenaDeque& infos, @@ -7707,18 +7707,28 @@ void InstructionCodeGeneratorARM::VisitClassTableGet(HClassTableGet* instruction } } +static void PatchJitRootUse(uint8_t* code, + const uint8_t* roots_data, + Literal* literal, + uint64_t index_in_table) { + DCHECK(literal->GetLabel()->IsBound()); + uint32_t literal_offset = literal->GetLabel()->Position(); + uintptr_t address = + reinterpret_cast(roots_data) + index_in_table * sizeof(GcRoot); + uint8_t* data = code + literal_offset; + reinterpret_cast(data)[0] = dchecked_integral_cast(address); +} + void CodeGeneratorARM::EmitJitRootPatches(uint8_t* code, const uint8_t* roots_data) { for (const auto& entry : jit_string_patches_) { const auto& it = jit_string_roots_.find(entry.first); DCHECK(it != jit_string_roots_.end()); - size_t index_in_table = it->second; - Literal* literal = entry.second; - DCHECK(literal->GetLabel()->IsBound()); - uint32_t literal_offset = literal->GetLabel()->Position(); - uintptr_t address = - reinterpret_cast(roots_data) + index_in_table * sizeof(GcRoot); - uint8_t* data = code + literal_offset; - reinterpret_cast(data)[0] = dchecked_integral_cast(address); + PatchJitRootUse(code, roots_data, entry.second, it->second); + } + for (const auto& entry : jit_class_patches_) { + const auto& it = jit_class_roots_.find(entry.first); + DCHECK(it != jit_class_roots_.end()); + PatchJitRootUse(code, roots_data, entry.second, it->second); } } diff --git a/compiler/optimizing/code_generator_arm.h b/compiler/optimizing/code_generator_arm.h index 8230512825..b9291728ff 100644 --- a/compiler/optimizing/code_generator_arm.h +++ b/compiler/optimizing/code_generator_arm.h @@ -491,6 +491,9 @@ class CodeGeneratorARM : public CodeGenerator { Literal* DeduplicateBootImageAddressLiteral(uint32_t address); Literal* DeduplicateDexCacheAddressLiteral(uint32_t address); Literal* DeduplicateJitStringLiteral(const DexFile& dex_file, dex::StringIndex string_index); + Literal* DeduplicateJitClassLiteral(const DexFile& dex_file, + dex::TypeIndex type_index, + uint64_t address); void EmitLinkerPatches(ArenaVector* linker_patches) OVERRIDE; @@ -599,9 +602,9 @@ class CodeGeneratorARM : public CodeGenerator { using StringToLiteralMap = ArenaSafeMap; - using BootTypeToLiteralMap = ArenaSafeMap; + using TypeToLiteralMap = ArenaSafeMap; Literal* DeduplicateUint32Literal(uint32_t value, Uint32ToLiteralMap* map); Literal* DeduplicateMethodLiteral(MethodReference target_method, MethodToLiteralMap* map); @@ -638,7 +641,7 @@ class CodeGeneratorARM : public CodeGenerator { // PC-relative String patch info; type depends on configuration (app .bss or boot image PIC). ArenaDeque pc_relative_string_patches_; // Deduplication map for boot type literals for kBootImageLinkTimeAddress. - BootTypeToLiteralMap boot_image_type_patches_; + TypeToLiteralMap boot_image_type_patches_; // PC-relative type patch info. ArenaDeque pc_relative_type_patches_; // Deduplication map for patchable boot image addresses. @@ -646,6 +649,8 @@ class CodeGeneratorARM : public CodeGenerator { // Patches for string literals in JIT compiled code. StringToLiteralMap jit_string_patches_; + // Patches for class literals in JIT compiled code. + TypeToLiteralMap jit_class_patches_; DISALLOW_COPY_AND_ASSIGN(CodeGeneratorARM); }; diff --git a/compiler/optimizing/code_generator_arm64.cc b/compiler/optimizing/code_generator_arm64.cc index 6eebd69a04..89e5d9eb68 100644 --- a/compiler/optimizing/code_generator_arm64.cc +++ b/compiler/optimizing/code_generator_arm64.cc @@ -1162,7 +1162,9 @@ CodeGeneratorARM64::CodeGeneratorARM64(HGraph* graph, boot_image_address_patches_(std::less(), graph->GetArena()->Adapter(kArenaAllocCodeGenerator)), jit_string_patches_(StringReferenceValueComparator(), - graph->GetArena()->Adapter(kArenaAllocCodeGenerator)) { + graph->GetArena()->Adapter(kArenaAllocCodeGenerator)), + jit_class_patches_(TypeReferenceValueComparator(), + graph->GetArena()->Adapter(kArenaAllocCodeGenerator)) { // Save the link register (containing the return address) to mimic Quick. AddAllocatedRegister(LocationFrom(lr)); } @@ -4182,6 +4184,14 @@ vixl::aarch64::Literal* CodeGeneratorARM64::DeduplicateJitStringLitera [this]() { return __ CreateLiteralDestroyedWithPool(/* placeholder */ 0u); }); } +vixl::aarch64::Literal* CodeGeneratorARM64::DeduplicateJitClassLiteral( + const DexFile& dex_file, dex::TypeIndex type_index, uint64_t address) { + jit_class_roots_.Overwrite(TypeReference(&dex_file, type_index), address); + return jit_class_patches_.GetOrCreate( + TypeReference(&dex_file, type_index), + [this]() { return __ CreateLiteralDestroyedWithPool(/* placeholder */ 0u); }); +} + void CodeGeneratorARM64::EmitAdrpPlaceholder(vixl::aarch64::Label* fixup_label, vixl::aarch64::Register reg) { DCHECK(reg.IsX()); @@ -4359,7 +4369,7 @@ HLoadClass::LoadKind CodeGeneratorARM64::GetSupportedLoadClassKind( break; case HLoadClass::LoadKind::kBootImageAddress: break; - case HLoadClass::LoadKind::kDexCacheAddress: + case HLoadClass::LoadKind::kJitTableAddress: DCHECK(Runtime::Current()->UseJitCompilation()); break; case HLoadClass::LoadKind::kDexCachePcRelative: @@ -4452,26 +4462,16 @@ void InstructionCodeGeneratorARM64::VisitLoadClass(HLoadClass* cls) { __ Ldr(out.W(), codegen_->DeduplicateBootImageAddressLiteral(cls->GetAddress())); break; } - case HLoadClass::LoadKind::kDexCacheAddress: { - DCHECK_NE(cls->GetAddress(), 0u); - // LDR immediate has a 12-bit offset multiplied by the size and for 32-bit loads - // that gives a 16KiB range. To try and reduce the number of literals if we load - // multiple types, simply split the dex cache address to a 16KiB aligned base - // loaded from a literal and the remaining offset embedded in the load. - static_assert(sizeof(GcRoot) == 4u, "Expected GC root to be 4 bytes."); - DCHECK_ALIGNED(cls->GetAddress(), 4u); - constexpr size_t offset_bits = /* encoded bits */ 12 + /* scale */ 2; - uint64_t base_address = cls->GetAddress() & ~MaxInt(offset_bits); - uint32_t offset = cls->GetAddress() & MaxInt(offset_bits); - __ Ldr(out.X(), codegen_->DeduplicateDexCacheAddressLiteral(base_address)); - // /* GcRoot */ out = *(base_address + offset) + case HLoadClass::LoadKind::kJitTableAddress: { + __ Ldr(out, codegen_->DeduplicateJitClassLiteral(cls->GetDexFile(), + cls->GetTypeIndex(), + cls->GetAddress())); GenerateGcRootFieldLoad(cls, out_loc, out.X(), - offset, + /* offset */ 0, /* fixup_label */ nullptr, - read_barrier_option); - generate_null_check = !cls->IsInDexCache(); + kCompilerReadBarrierOption); break; } case HLoadClass::LoadKind::kDexCachePcRelative: { @@ -5782,17 +5782,27 @@ void InstructionCodeGeneratorARM64::VisitClassTableGet(HClassTableGet* instructi } } +static void PatchJitRootUse(uint8_t* code, + const uint8_t* roots_data, + vixl::aarch64::Literal* literal, + uint64_t index_in_table) { + uint32_t literal_offset = literal->GetOffset(); + uintptr_t address = + reinterpret_cast(roots_data) + index_in_table * sizeof(GcRoot); + uint8_t* data = code + literal_offset; + reinterpret_cast(data)[0] = dchecked_integral_cast(address); +} + void CodeGeneratorARM64::EmitJitRootPatches(uint8_t* code, const uint8_t* roots_data) { for (const auto& entry : jit_string_patches_) { const auto& it = jit_string_roots_.find(entry.first); DCHECK(it != jit_string_roots_.end()); - size_t index_in_table = it->second; - vixl::aarch64::Literal* literal = entry.second; - uint32_t literal_offset = literal->GetOffset(); - uintptr_t address = - reinterpret_cast(roots_data) + index_in_table * sizeof(GcRoot); - uint8_t* data = code + literal_offset; - reinterpret_cast(data)[0] = dchecked_integral_cast(address); + PatchJitRootUse(code, roots_data, entry.second, it->second); + } + for (const auto& entry : jit_class_patches_) { + const auto& it = jit_class_roots_.find(entry.first); + DCHECK(it != jit_class_roots_.end()); + PatchJitRootUse(code, roots_data, entry.second, it->second); } } diff --git a/compiler/optimizing/code_generator_arm64.h b/compiler/optimizing/code_generator_arm64.h index 868c8b07ed..50bbc99ca5 100644 --- a/compiler/optimizing/code_generator_arm64.h +++ b/compiler/optimizing/code_generator_arm64.h @@ -569,6 +569,9 @@ class CodeGeneratorARM64 : public CodeGenerator { vixl::aarch64::Literal* DeduplicateDexCacheAddressLiteral(uint64_t address); vixl::aarch64::Literal* DeduplicateJitStringLiteral(const DexFile& dex_file, dex::StringIndex string_index); + vixl::aarch64::Literal* DeduplicateJitClassLiteral(const DexFile& dex_file, + dex::TypeIndex string_index, + uint64_t address); void EmitAdrpPlaceholder(vixl::aarch64::Label* fixup_label, vixl::aarch64::Register reg); void EmitAddPlaceholder(vixl::aarch64::Label* fixup_label, @@ -682,9 +685,9 @@ class CodeGeneratorARM64 : public CodeGenerator { using StringToLiteralMap = ArenaSafeMap*, StringReferenceValueComparator>; - using BootTypeToLiteralMap = ArenaSafeMap*, - TypeReferenceValueComparator>; + using TypeToLiteralMap = ArenaSafeMap*, + TypeReferenceValueComparator>; vixl::aarch64::Literal* DeduplicateUint32Literal(uint32_t value, Uint32ToLiteralMap* map); @@ -749,7 +752,7 @@ class CodeGeneratorARM64 : public CodeGenerator { // PC-relative String patch info; type depends on configuration (app .bss or boot image PIC). ArenaDeque pc_relative_string_patches_; // Deduplication map for boot type literals for kBootImageLinkTimeAddress. - BootTypeToLiteralMap boot_image_type_patches_; + TypeToLiteralMap boot_image_type_patches_; // PC-relative type patch info. ArenaDeque pc_relative_type_patches_; // Deduplication map for patchable boot image addresses. @@ -757,6 +760,8 @@ class CodeGeneratorARM64 : public CodeGenerator { // Patches for string literals in JIT compiled code. StringToLiteralMap jit_string_patches_; + // Patches for class literals in JIT compiled code. + TypeToLiteralMap jit_class_patches_; DISALLOW_COPY_AND_ASSIGN(CodeGeneratorARM64); }; diff --git a/compiler/optimizing/code_generator_arm_vixl.cc b/compiler/optimizing/code_generator_arm_vixl.cc index 3a3d2a9db1..2c6df38daa 100644 --- a/compiler/optimizing/code_generator_arm_vixl.cc +++ b/compiler/optimizing/code_generator_arm_vixl.cc @@ -5776,7 +5776,7 @@ HLoadClass::LoadKind CodeGeneratorARMVIXL::GetSupportedLoadClassKind( case HLoadClass::LoadKind::kBootImageAddress: // TODO(VIXL): Enable it back when literal pools are fixed in VIXL. return HLoadClass::LoadKind::kDexCacheViaMethod; - case HLoadClass::LoadKind::kDexCacheAddress: + case HLoadClass::LoadKind::kJitTableAddress: // TODO(VIXL): Enable it back when literal pools are fixed in VIXL. return HLoadClass::LoadKind::kDexCacheViaMethod; case HLoadClass::LoadKind::kDexCachePcRelative: @@ -5868,7 +5868,7 @@ void InstructionCodeGeneratorARMVIXL::VisitLoadClass(HLoadClass* cls) { TODO_VIXL32(FATAL); break; } - case HLoadClass::LoadKind::kDexCacheAddress: { + case HLoadClass::LoadKind::kJitTableAddress: { TODO_VIXL32(FATAL); break; } diff --git a/compiler/optimizing/code_generator_mips.cc b/compiler/optimizing/code_generator_mips.cc index ff48f6642d..cae4161daf 100644 --- a/compiler/optimizing/code_generator_mips.cc +++ b/compiler/optimizing/code_generator_mips.cc @@ -5251,9 +5251,9 @@ HLoadClass::LoadKind CodeGeneratorMIPS::GetSupportedLoadClassKind( break; case HLoadClass::LoadKind::kBootImageAddress: break; - case HLoadClass::LoadKind::kDexCacheAddress: + case HLoadClass::LoadKind::kJitTableAddress: DCHECK(Runtime::Current()->UseJitCompilation()); - fallback_load = false; + fallback_load = true; break; case HLoadClass::LoadKind::kDexCachePcRelative: DCHECK(!Runtime::Current()->UseJitCompilation()); @@ -5614,17 +5614,8 @@ void InstructionCodeGeneratorMIPS::VisitLoadClass(HLoadClass* cls) { codegen_->DeduplicateBootImageAddressLiteral(address)); break; } - case HLoadClass::LoadKind::kDexCacheAddress: { - DCHECK_NE(cls->GetAddress(), 0u); - uint32_t address = dchecked_integral_cast(cls->GetAddress()); - static_assert(sizeof(GcRoot) == 4u, "Expected GC root to be 4 bytes."); - DCHECK_ALIGNED(cls->GetAddress(), 4u); - int16_t offset = Low16Bits(address); - uint32_t base_address = address - offset; // This accounts for offset sign extension. - __ Lui(out, High16Bits(base_address)); - // /* GcRoot */ out = *(base_address + offset) - GenerateGcRootFieldLoad(cls, out_loc, out, offset); - generate_null_check = !cls->IsInDexCache(); + case HLoadClass::LoadKind::kJitTableAddress: { + LOG(FATAL) << "Unimplemented"; break; } case HLoadClass::LoadKind::kDexCachePcRelative: { diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc index d6e92ccb81..8612a67c8b 100644 --- a/compiler/optimizing/code_generator_x86.cc +++ b/compiler/optimizing/code_generator_x86.cc @@ -1013,6 +1013,7 @@ CodeGeneratorX86::CodeGeneratorX86(HGraph* graph, string_patches_(graph->GetArena()->Adapter(kArenaAllocCodeGenerator)), type_patches_(graph->GetArena()->Adapter(kArenaAllocCodeGenerator)), jit_string_patches_(graph->GetArena()->Adapter(kArenaAllocCodeGenerator)), + jit_class_patches_(graph->GetArena()->Adapter(kArenaAllocCodeGenerator)), constant_area_start_(-1), fixups_to_jump_tables_(graph->GetArena()->Adapter(kArenaAllocCodeGenerator)), method_address_offset_(-1) { @@ -6034,7 +6035,7 @@ HLoadClass::LoadKind CodeGeneratorX86::GetSupportedLoadClassKind( break; case HLoadClass::LoadKind::kBootImageAddress: break; - case HLoadClass::LoadKind::kDexCacheAddress: + case HLoadClass::LoadKind::kJitTableAddress: DCHECK(Runtime::Current()->UseJitCompilation()); break; case HLoadClass::LoadKind::kDexCacheViaMethod: @@ -6073,6 +6074,16 @@ void LocationsBuilderX86::VisitLoadClass(HLoadClass* cls) { locations->SetOut(Location::RequiresRegister()); } +Label* CodeGeneratorX86::NewJitRootClassPatch(const DexFile& dex_file, + dex::TypeIndex dex_index, + uint64_t address) { + jit_class_roots_.Overwrite(TypeReference(&dex_file, dex_index), address); + // Add a patch entry and return the label. + jit_class_patches_.emplace_back(dex_file, dex_index.index_); + PatchInfo