diff options
Diffstat (limited to 'compiler/image_writer.cc')
| -rw-r--r-- | compiler/image_writer.cc | 25 |
1 files changed, 20 insertions, 5 deletions
diff --git a/compiler/image_writer.cc b/compiler/image_writer.cc index aa16885039..e3114eb80d 100644 --- a/compiler/image_writer.cc +++ b/compiler/image_writer.cc @@ -104,6 +104,8 @@ bool ImageWriter::Write(const std::string& image_filename, portable_to_interpreter_bridge_offset_ = oat_file_->GetOatHeader().GetPortableToInterpreterBridgeOffset(); + quick_generic_jni_trampoline_offset_ = + oat_file_->GetOatHeader().GetQuickGenericJniTrampolineOffset(); quick_imt_conflict_trampoline_offset_ = oat_file_->GetOatHeader().GetQuickImtConflictTrampolineOffset(); quick_resolution_trampoline_offset_ = @@ -424,8 +426,6 @@ ObjectArray<Object>* ImageWriter::CreateImageRoots() const { runtime->GetCalleeSaveMethod(Runtime::kRefsOnly)); image_roots->Set<false>(ImageHeader::kRefsAndArgsSaveMethod, runtime->GetCalleeSaveMethod(Runtime::kRefsAndArgs)); - image_roots->Set<false>(ImageHeader::kOatLocation, - String::AllocFromModifiedUtf8(self, oat_file_->GetLocation().c_str())); image_roots->Set<false>(ImageHeader::kDexCaches, dex_caches); image_roots->Set<false>(ImageHeader::kClassRoots, class_linker->GetClassRoots()); for (int i = 0; i < ImageHeader::kImageRootsMax; i++) { @@ -635,9 +635,18 @@ void ImageWriter::FixupMethod(ArtMethod* orig, ArtMethod* copy) { // Use original code if it exists. Otherwise, set the code pointer to the resolution // trampoline. const byte* quick_code = GetOatAddress(orig->GetQuickOatCodeOffset()); - if (quick_code != nullptr) { + if (quick_code != nullptr && + (!orig->IsStatic() || orig->IsConstructor() || orig->GetDeclaringClass()->IsInitialized())) { + // We have code for a non-static or initialized method, just use the code. copy->SetEntryPointFromQuickCompiledCode<kVerifyNone>(quick_code); + } else if (quick_code == nullptr && orig->IsNative() && !orig->IsStatic()) { + // Non-static native method missing compiled code, use generic JNI version. + copy->SetEntryPointFromQuickCompiledCode<kVerifyNone>(GetOatAddress(quick_generic_jni_trampoline_offset_)); + } else if (quick_code == nullptr && !orig->IsNative()) { + // We don't have code at all for a non-native method, use the interpreter. + copy->SetEntryPointFromQuickCompiledCode<kVerifyNone>(GetOatAddress(quick_to_interpreter_bridge_offset_)); } else { + // We have code for a static method, but need to go through the resolution stub for class initialization. copy->SetEntryPointFromQuickCompiledCode<kVerifyNone>(GetOatAddress(quick_resolution_trampoline_offset_)); } const byte* portable_code = GetOatAddress(orig->GetPortableOatCodeOffset()); @@ -807,6 +816,12 @@ void ImageWriter::PatchOatCodeAndMethods() { uintptr_t value = quick_code - patch_location + patch->RelativeOffset(); SetPatchLocation(patch, value); } else { + // generic JNI, not interpreter bridge from GetQuickOatCodeFor(). + if (target->IsNative() && + quick_code == reinterpret_cast<uintptr_t>(GetQuickToInterpreterBridge())) { + code_offset = quick_generic_jni_trampoline_offset_; + } + SetPatchLocation(patch, PointerToLowMemUInt32(GetOatAddress(code_offset))); } } @@ -845,7 +860,7 @@ void ImageWriter::SetPatchLocation(const CompilerDriver::PatchInformation* patch if (patch->IsCall()) { const CompilerDriver::CallPatchInformation* cpatch = patch->AsCall(); const DexFile::MethodId& id = cpatch->GetDexFile().GetMethodId(cpatch->GetTargetMethodIdx()); - uintptr_t expected = reinterpret_cast<uintptr_t>(&id); + uint32_t expected = reinterpret_cast<uintptr_t>(&id) & 0xFFFFFFFF; uint32_t actual = *patch_location; CHECK(actual == expected || actual == value) << std::hex << "actual=" << actual @@ -855,7 +870,7 @@ void ImageWriter::SetPatchLocation(const CompilerDriver::PatchInformation* patch if (patch->IsType()) { const CompilerDriver::TypePatchInformation* tpatch = patch->AsType(); const DexFile::TypeId& id = tpatch->GetDexFile().GetTypeId(tpatch->GetTargetTypeIdx()); - uintptr_t expected = reinterpret_cast<uintptr_t>(&id); + uint32_t expected = reinterpret_cast<uintptr_t>(&id) & 0xFFFFFFFF; uint32_t actual = *patch_location; CHECK(actual == expected || actual == value) << std::hex << "actual=" << actual |