diff options
author | Mathieu Chartier <mathieuc@google.com> | 2014-05-29 22:00:50 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2014-05-29 22:00:50 +0000 |
commit | 31e7fcb904f03a504f082d25814ac4644b5073e4 (patch) | |
tree | 3564e74f52a40a242e6be2bbb03f1e31a2428e3a | |
parent | b478dab31955402e9f78665f45a3fb24f8f17b77 (diff) | |
parent | 57d27334bcb9ea95c969be70d8d93eb1a9c72b41 (diff) | |
download | android_art-31e7fcb904f03a504f082d25814ac4644b5073e4.tar.gz android_art-31e7fcb904f03a504f082d25814ac4644b5073e4.tar.bz2 android_art-31e7fcb904f03a504f082d25814ac4644b5073e4.zip |
Merge "Add support for relative patching to quick offsets."
-rw-r--r-- | compiler/image_writer.cc | 36 |
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(); |