summaryrefslogtreecommitdiff
path: root/compiler/oat_writer.cc
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/oat_writer.cc')
-rw-r--r--compiler/oat_writer.cc37
1 files changed, 27 insertions, 10 deletions
diff --git a/compiler/oat_writer.cc b/compiler/oat_writer.cc
index 15b4017816..633bf64171 100644
--- a/compiler/oat_writer.cc
+++ b/compiler/oat_writer.cc
@@ -19,6 +19,7 @@
#include <zlib.h>
#include "arch/arm64/instruction_set_features_arm64.h"
+#include "art_method-inl.h"
#include "base/allocator.h"
#include "base/bit_vector.h"
#include "base/stl_util.h"
@@ -33,7 +34,6 @@
#include "gc/space/space.h"
#include "image_writer.h"
#include "linker/relative_patcher.h"
-#include "mirror/art_method-inl.h"
#include "mirror/array.h"
#include "mirror/class_loader.h"
#include "mirror/dex_cache-inl.h"
@@ -620,10 +620,9 @@ class OatWriter::InitImageMethodVisitor : public OatDexMethodVisitor {
ScopedObjectAccessUnchecked soa(Thread::Current());
StackHandleScope<1> hs(soa.Self());
Handle<mirror::DexCache> dex_cache(hs.NewHandle(linker->FindDexCache(*dex_file_)));
- mirror::ArtMethod* method = linker->ResolveMethod(*dex_file_, it.GetMemberIndex(), dex_cache,
- NullHandle<mirror::ClassLoader>(),
- NullHandle<mirror::ArtMethod>(),
- invoke_type);
+ ArtMethod* method = linker->ResolveMethod(
+ *dex_file_, it.GetMemberIndex(), dex_cache, NullHandle<mirror::ClassLoader>(), nullptr,
+ invoke_type);
if (method == nullptr) {
LOG(ERROR) << "Unexpected failure to resolve a method: "
<< PrettyMethod(it.GetMemberIndex(), *dex_file_, true);
@@ -755,8 +754,8 @@ class OatWriter::WriteCodeMethodVisitor : public OatDexMethodVisitor {
uint32_t target_offset = GetTargetOffset(patch);
PatchCodeAddress(&patched_code_, patch.LiteralOffset(), target_offset);
} else if (patch.Type() == kLinkerPatchMethod) {
- mirror::ArtMethod* method = GetTargetMethod(patch);
- PatchObjectAddress(&patched_code_, patch.LiteralOffset(), method);
+ ArtMethod* method = GetTargetMethod(patch);
+ PatchMethodAddress(&patched_code_, patch.LiteralOffset(), method);
} else if (patch.Type() == kLinkerPatchType) {
mirror::Class* type = GetTargetType(patch);
PatchObjectAddress(&patched_code_, patch.LiteralOffset(), type);
@@ -794,12 +793,13 @@ class OatWriter::WriteCodeMethodVisitor : public OatDexMethodVisitor {
<< PrettyMethod(it.GetMemberIndex(), *dex_file_) << " to " << out_->GetLocation();
}
- mirror::ArtMethod* GetTargetMethod(const LinkerPatch& patch)
+ ArtMethod* GetTargetMethod(const LinkerPatch& patch)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
MethodReference ref = patch.TargetMethod();
mirror::DexCache* dex_cache =
(dex_file_ == ref.dex_file) ? dex_cache_ : class_linker_->FindDexCache(*ref.dex_file);
- mirror::ArtMethod* method = dex_cache->GetResolvedMethod(ref.dex_method_index);
+ ArtMethod* method = dex_cache->GetResolvedMethod(
+ ref.dex_method_index, class_linker_->GetImagePointerSize());
CHECK(method != nullptr);
return method;
}
@@ -810,7 +810,7 @@ class OatWriter::WriteCodeMethodVisitor : public OatDexMethodVisitor {
(target_it != writer_->method_offset_map_.map.end()) ? target_it->second : 0u;
// If there's no compiled code, point to the correct trampoline.
if (UNLIKELY(target_offset == 0)) {
- mirror::ArtMethod* target = GetTargetMethod(patch);
+ ArtMethod* target = GetTargetMethod(patch);
DCHECK(target != nullptr);
size_t size = GetInstructionSetPointerSize(writer_->compiler_driver_->GetInstructionSet());
const void* oat_code_offset = target->GetEntryPointFromQuickCompiledCodePtrSize(size);
@@ -865,6 +865,23 @@ class OatWriter::WriteCodeMethodVisitor : public OatDexMethodVisitor {
data[3] = (address >> 24) & 0xffu;
}
+ void PatchMethodAddress(std::vector<uint8_t>* code, uint32_t offset, ArtMethod* method)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ // NOTE: Direct method pointers across oat files don't use linker patches. However, direct
+ // type pointers across oat files do. (TODO: Investigate why.)
+ if (writer_->image_writer_ != nullptr) {
+ method = writer_->image_writer_->GetImageMethodAddress(method);
+ }
+ // Note: We only patch ArtMethods to low 4gb since thats where the image is.
+ uint32_t address = PointerToLowMemUInt32(method);
+ DCHECK_LE(offset + 4, code->size());
+ uint8_t* data = &(*code)[offset];
+ data[0] = address & 0xffu;
+ data[1] = (address >> 8) & 0xffu;
+ data[2] = (address >> 16) & 0xffu;
+ data[3] = (address >> 24) & 0xffu;
+ }
+
void PatchCodeAddress(std::vector<uint8_t>* code, uint32_t offset, uint32_t target_offset)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
uint32_t address = writer_->image_writer_ == nullptr ? target_offset :