From e7f82e2515f47f3c3292281312d7031a34a58ffc Mon Sep 17 00:00:00 2001 From: Fred Shih Date: Wed, 6 Aug 2014 10:46:37 -0700 Subject: Added support for patching classes from different dex files. Added support for class patching from different dex files and moved ScopedObjectAccess from the quick compiler to driver. Slight refactoring for clarity. Bug: 16656190 Change-Id: I107fcbce75db42ca61321ea1c5d5f236680a1b3d --- compiler/dex/quick/codegen_util.cc | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) (limited to 'compiler/dex/quick/codegen_util.cc') diff --git a/compiler/dex/quick/codegen_util.cc b/compiler/dex/quick/codegen_util.cc index 2a51b496a3..9f604277ac 100644 --- a/compiler/dex/quick/codegen_util.cc +++ b/compiler/dex/quick/codegen_util.cc @@ -394,6 +394,18 @@ LIR* Mir2Lir::ScanLiteralPoolMethod(LIR* data_target, const MethodReference& met return nullptr; } +/* Search the existing constants in the literal pool for an exact class match */ +LIR* Mir2Lir::ScanLiteralPoolClass(LIR* data_target, const DexFile& dex_file, uint32_t type_idx) { + while (data_target) { + if (static_cast(data_target->operands[0]) == type_idx && + UnwrapPointer(data_target->operands[1]) == &dex_file) { + return data_target; + } + data_target = data_target->next; + } + return nullptr; +} + /* * The following are building blocks to insert constants into the pool or * instruction streams. @@ -492,10 +504,13 @@ void Mir2Lir::InstallLiteralPools() { data_lir = class_literal_list_; while (data_lir != NULL) { uint32_t target_method_idx = data_lir->operands[0]; + const DexFile* class_dex_file = + reinterpret_cast(UnwrapPointer(data_lir->operands[1])); cu_->compiler_driver->AddClassPatch(cu_->dex_file, cu_->class_def_idx, cu_->method_idx, target_method_idx, + class_dex_file, code_buffer_.size()); const DexFile::TypeId& target_method_id = cu_->dex_file->GetTypeId(target_method_idx); // unique value based on target to ensure code deduplication works @@ -1222,12 +1237,14 @@ void Mir2Lir::LoadMethodAddress(const MethodReference& target_method, InvokeType DCHECK_NE(cu_->instruction_set, kMips) << reinterpret_cast(data_target); } -void Mir2Lir::LoadClassType(uint32_t type_idx, SpecialTargetRegister symbolic_reg) { +void Mir2Lir::LoadClassType(const DexFile& dex_file, uint32_t type_idx, + SpecialTargetRegister symbolic_reg) { // Use the literal pool and a PC-relative load from a data word. - LIR* data_target = ScanLiteralPool(class_literal_list_, type_idx, 0); + LIR* data_target = ScanLiteralPoolClass(class_literal_list_, dex_file, type_idx); if (data_target == nullptr) { data_target = AddWordData(&class_literal_list_, type_idx); } + data_target->operands[1] = WrapPointer(const_cast(&dex_file)); // Loads a Class pointer, which is a reference as it lives in the heap. LIR* load_pc_rel = OpPcRelLoad(TargetReg(symbolic_reg, kRef), data_target); AppendLIR(load_pc_rel); -- cgit v1.2.3-59-g8ed1b