summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--compiler/dex/quick/arm64/call_arm64.cc5
-rw-r--r--compiler/driver/compiler_driver.cc10
-rw-r--r--compiler/oat_writer.cc23
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;