diff options
-rw-r--r-- | compiler/dex/quick/arm64/call_arm64.cc | 5 | ||||
-rw-r--r-- | compiler/driver/compiler_driver.cc | 10 | ||||
-rw-r--r-- | compiler/oat_writer.cc | 23 |
3 files changed, 26 insertions, 12 deletions
diff --git a/compiler/dex/quick/arm64/call_arm64.cc b/compiler/dex/quick/arm64/call_arm64.cc index 6492442..d2204f5 100644 --- a/compiler/dex/quick/arm64/call_arm64.cc +++ b/compiler/dex/quick/arm64/call_arm64.cc @@ -400,9 +400,8 @@ void Arm64Mir2Lir::GenSpecialExitSequence() { } static bool Arm64UseRelativeCall(CompilationUnit* cu, const MethodReference& target_method) { - UNUSED(cu, target_method); - // Always emit relative calls. - return true; + // Emit relative calls anywhere in the image or within a dex file otherwise. + return cu->compiler_driver->IsImage() || cu->dex_file == target_method.dex_file; } /* diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc index 2d8c9d4..b8a8936 100644 --- a/compiler/driver/compiler_driver.cc +++ b/compiler/driver/compiler_driver.cc @@ -1285,7 +1285,15 @@ void CompilerDriver::GetCodeAndMethodForDirectCall(InvokeType* type, InvokeType *stats_flags |= kFlagDirectCallToBoot | kFlagDirectMethodToBoot; } if (!use_dex_cache && force_relocations) { - if (!IsImage() || !IsImageClass(method->GetDeclaringClassDescriptor())) { + bool is_in_image; + if (IsImage()) { + is_in_image = IsImageClass(method->GetDeclaringClassDescriptor()); + } else { + is_in_image = instruction_set_ != kX86 && instruction_set_ != kX86_64 && + Runtime::Current()->GetHeap()->FindSpaceFromObject(method->GetDeclaringClass(), + false)->IsImageSpace(); + } + if (!is_in_image) { // We can only branch directly to Methods that are resolved in the DexCache. // Otherwise we won't invoke the resolution trampoline. use_dex_cache = true; diff --git a/compiler/oat_writer.cc b/compiler/oat_writer.cc index 3c36ffa..7516811 100644 --- a/compiler/oat_writer.cc +++ b/compiler/oat_writer.cc @@ -1103,10 +1103,18 @@ class OatWriter::WriteCodeMethodVisitor : public OatDexMethodVisitor { if (UNLIKELY(target_offset == 0)) { mirror::ArtMethod* target = GetTargetMethod(patch); DCHECK(target != nullptr); - DCHECK_EQ(target->GetQuickOatCodeOffset(), 0u); - target_offset = target->IsNative() - ? writer_->oat_header_->GetQuickGenericJniTrampolineOffset() - : writer_->oat_header_->GetQuickToInterpreterBridgeOffset(); + size_t size = GetInstructionSetPointerSize(writer_->compiler_driver_->GetInstructionSet()); + const void* oat_code_offset = target->GetEntryPointFromQuickCompiledCodePtrSize(size); + if (oat_code_offset != 0) { + DCHECK(!Runtime::Current()->GetClassLinker()->IsQuickResolutionStub(oat_code_offset)); + DCHECK(!Runtime::Current()->GetClassLinker()->IsQuickToInterpreterBridge(oat_code_offset)); + DCHECK(!Runtime::Current()->GetClassLinker()->IsQuickGenericJniStub(oat_code_offset)); + target_offset = PointerToLowMemUInt32(oat_code_offset); + } else { + target_offset = target->IsNative() + ? writer_->oat_header_->GetQuickGenericJniTrampolineOffset() + : writer_->oat_header_->GetQuickToInterpreterBridgeOffset(); + } } return target_offset; } @@ -1138,10 +1146,9 @@ class OatWriter::WriteCodeMethodVisitor : public OatDexMethodVisitor { void PatchCodeAddress(std::vector<uint8_t>* code, uint32_t offset, uint32_t target_offset) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { - // NOTE: Direct calls across oat files don't use linker patches. - DCHECK(writer_->image_writer_ != nullptr); - uint32_t address = PointerToLowMemUInt32(writer_->image_writer_->GetOatFileBegin() + - writer_->oat_data_offset_ + target_offset); + uint32_t address = writer_->image_writer_ == nullptr ? target_offset : + PointerToLowMemUInt32(writer_->image_writer_->GetOatFileBegin() + + writer_->oat_data_offset_ + target_offset); DCHECK_LE(offset + 4, code->size()); uint8_t* data = &(*code)[offset]; data[0] = address & 0xffu; |