summaryrefslogtreecommitdiff
path: root/compiler
diff options
context:
space:
mode:
author Mathieu Chartier <mathieuc@google.com> 2014-05-29 22:04:24 +0000
committer Android Git Automerger <android-git-automerger@android.com> 2014-05-29 22:04:24 +0000
commitb7fbac4784f5dd041ef8d0c56c0af11410a7fc1a (patch)
tree988f4059e2916b801965500164ec04c5e4f815e6 /compiler
parent90cfca32c9d17594652f088f3954d7994d90b2c5 (diff)
parent31e7fcb904f03a504f082d25814ac4644b5073e4 (diff)
am 31e7fcb9: Merge "Add support for relative patching to quick offsets."
* commit '31e7fcb904f03a504f082d25814ac4644b5073e4': Add support for relative patching to quick offsets.
Diffstat (limited to 'compiler')
-rw-r--r--compiler/image_writer.cc36
1 files changed, 24 insertions, 12 deletions
diff --git a/compiler/image_writer.cc b/compiler/image_writer.cc
index be53926ac8..e909c97f64 100644
--- a/compiler/image_writer.cc
+++ b/compiler/image_writer.cc
@@ -742,30 +742,42 @@ void ImageWriter::PatchOatCodeAndMethods() {
const CompilerDriver::CallPatchInformation* patch = code_to_patch[i];
ArtMethod* target = GetTargetMethod(patch);
uintptr_t quick_code = reinterpret_cast<uintptr_t>(class_linker->GetQuickOatCodeFor(target));
+ DCHECK_NE(quick_code, 0U) << PrettyMethod(target);
uintptr_t code_base = reinterpret_cast<uintptr_t>(&oat_file_->GetOatHeader());
uintptr_t code_offset = quick_code - code_base;
+ bool is_quick_offset = false;
+ if (quick_code == reinterpret_cast<uintptr_t>(GetQuickToInterpreterBridge())) {
+ is_quick_offset = true;
+ code_offset = PointerToLowMemUInt32(GetOatAddress(quick_to_interpreter_bridge_offset_));
+ } else if (quick_code ==
+ reinterpret_cast<uintptr_t>(class_linker->GetQuickGenericJniTrampoline())) {
+ CHECK(target->IsNative());
+ is_quick_offset = true;
+ code_offset = PointerToLowMemUInt32(GetOatAddress(quick_generic_jni_trampoline_offset_));
+ }
+ uintptr_t value;
if (patch->IsRelative()) {
// value to patch is relative to the location being patched
const void* quick_oat_code =
class_linker->GetQuickOatCodeFor(patch->GetDexFile(),
patch->GetReferrerClassDefIdx(),
patch->GetReferrerMethodIdx());
+ if (is_quick_offset) {
+ quick_code = code_offset;
+ // If its a quick offset it means that we are doing a relative patch from the class linker
+ // oat_file to the image writer oat_file so we need to adjust the quick oat code to be the
+ // one in the image writer oat_file.
+ quick_oat_code =
+ reinterpret_cast<const void*>(reinterpret_cast<uintptr_t>(quick_oat_code) +
+ reinterpret_cast<uintptr_t>(oat_data_begin_) - code_base);
+ }
uintptr_t base = reinterpret_cast<uintptr_t>(quick_oat_code);
uintptr_t patch_location = base + patch->GetLiteralOffset();
- uintptr_t value = quick_code - patch_location + patch->RelativeOffset();
- SetPatchLocation(patch, value);
+ value = quick_code - patch_location + patch->RelativeOffset();
} else {
- if (quick_code == reinterpret_cast<uintptr_t>(GetQuickToInterpreterBridge()) ||
- quick_code == reinterpret_cast<uintptr_t>(class_linker->GetQuickGenericJniTrampoline())) {
- if (target->IsNative()) {
- // generic JNI, not interpreter bridge from GetQuickOatCodeFor().
- code_offset = quick_generic_jni_trampoline_offset_;
- } else {
- code_offset = quick_to_interpreter_bridge_offset_;
- }
- }
- SetPatchLocation(patch, PointerToLowMemUInt32(GetOatAddress(code_offset)));
+ value = code_offset;
}
+ SetPatchLocation(patch, value);
}
const CallPatches& methods_to_patch = compiler_driver_.GetMethodsToPatch();