From f4da675bbc4615c5f854c81964cac9dd1153baea Mon Sep 17 00:00:00 2001 From: Vladimir Marko Date: Fri, 1 Aug 2014 19:04:18 +0100 Subject: Implement method calls using relative BL on ARM. Store the linker patches with each CompiledMethod instead of keeping them in CompilerDriver. Reorganize oat file creation to apply the patches as we're writing the method code. Add framework for platform-specific relative call patches in the OatWriter. Implement relative call patches for ARM. Change-Id: Ie2effb3d92b61ac8f356140eba09dc37d62290f8 --- compiler/dex/quick/codegen_util.cc | 42 +++++++++++++++----------------------- 1 file changed, 17 insertions(+), 25 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 bd2a942acd..313589227f 100644 --- a/compiler/dex/quick/codegen_util.cc +++ b/compiler/dex/quick/codegen_util.cc @@ -472,20 +472,15 @@ void Mir2Lir::InstallLiteralPools() { Push32(code_buffer_, data_lir->operands[0]); data_lir = NEXT_LIR(data_lir); } + // TODO: patches_.reserve() as needed. // Push code and method literals, record offsets for the compiler to patch. data_lir = code_literal_list_; while (data_lir != NULL) { uint32_t target_method_idx = data_lir->operands[0]; const DexFile* target_dex_file = reinterpret_cast(UnwrapPointer(data_lir->operands[1])); - cu_->compiler_driver->AddCodePatch(cu_->dex_file, - cu_->class_def_idx, - cu_->method_idx, - cu_->invoke_type, - target_method_idx, - target_dex_file, - static_cast(data_lir->operands[2]), - code_buffer_.size()); + patches_.push_back(LinkerPatch::CodePatch(code_buffer_.size(), + target_dex_file, target_method_idx)); const DexFile::MethodId& target_method_id = target_dex_file->GetMethodId(target_method_idx); // unique value based on target to ensure code deduplication works PushPointer(code_buffer_, &target_method_id, cu_->target64); @@ -496,14 +491,8 @@ void Mir2Lir::InstallLiteralPools() { uint32_t target_method_idx = data_lir->operands[0]; const DexFile* target_dex_file = reinterpret_cast(UnwrapPointer(data_lir->operands[1])); - cu_->compiler_driver->AddMethodPatch(cu_->dex_file, - cu_->class_def_idx, - cu_->method_idx, - cu_->invoke_type, - target_method_idx, - target_dex_file, - static_cast(data_lir->operands[2]), - code_buffer_.size()); + patches_.push_back(LinkerPatch::MethodPatch(code_buffer_.size(), + target_dex_file, target_method_idx)); const DexFile::MethodId& target_method_id = target_dex_file->GetMethodId(target_method_idx); // unique value based on target to ensure code deduplication works PushPointer(code_buffer_, &target_method_id, cu_->target64); @@ -512,16 +501,12 @@ void Mir2Lir::InstallLiteralPools() { // Push class literals. data_lir = class_literal_list_; while (data_lir != NULL) { - uint32_t target_method_idx = data_lir->operands[0]; + uint32_t target_type_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 = class_dex_file->GetTypeId(target_method_idx); + patches_.push_back(LinkerPatch::TypePatch(code_buffer_.size(), + class_dex_file, target_type_idx)); + const DexFile::TypeId& target_method_id = class_dex_file->GetTypeId(target_type_idx); // unique value based on target to ensure code deduplication works PushPointer(code_buffer_, &target_method_id, cu_->target64); data_lir = NEXT_LIR(data_lir); @@ -1006,6 +991,7 @@ Mir2Lir::Mir2Lir(CompilationUnit* cu, MIRGraph* mir_graph, ArenaAllocator* arena live_sreg_(0), core_vmap_table_(mir_graph->GetArena()->Adapter()), fp_vmap_table_(mir_graph->GetArena()->Adapter()), + patches_(mir_graph->GetArena()->Adapter()), num_core_spills_(0), num_fp_spills_(0), frame_size_(0), @@ -1097,11 +1083,17 @@ CompiledMethod* Mir2Lir::GetCompiledMethod() { vmap_encoder.PushBackUnsigned(0u); // Size is 0. } + // Sort patches by literal offset for better deduplication. + std::sort(patches_.begin(), patches_.end(), [](const LinkerPatch& lhs, const LinkerPatch& rhs) { + return lhs.LiteralOffset() < rhs.LiteralOffset(); + }); + std::unique_ptr> cfi_info(ReturnFrameDescriptionEntry()); CompiledMethod* result = new CompiledMethod(cu_->compiler_driver, cu_->instruction_set, code_buffer_, frame_size_, core_spill_mask_, fp_spill_mask_, &src_mapping_table_, encoded_mapping_table_, - vmap_encoder.GetData(), native_gc_map_, cfi_info.get()); + vmap_encoder.GetData(), native_gc_map_, cfi_info.get(), + ArrayRef(patches_)); return result; } -- cgit v1.2.3-59-g8ed1b