diff options
Diffstat (limited to 'compiler/image_writer.cc')
| -rw-r--r-- | compiler/image_writer.cc | 106 |
1 files changed, 54 insertions, 52 deletions
diff --git a/compiler/image_writer.cc b/compiler/image_writer.cc index c08d3bdf8b..1c8b8d56bf 100644 --- a/compiler/image_writer.cc +++ b/compiler/image_writer.cc @@ -29,7 +29,6 @@ #include "driver/compiler_driver.h" #include "elf_file.h" #include "elf_utils.h" -#include "elf_patcher.h" #include "elf_writer.h" #include "gc/accounting/card_table-inl.h" #include "gc/accounting/heap_bitmap.h" @@ -68,15 +67,38 @@ using ::art::mirror::String; namespace art { +bool ImageWriter::PrepareImageAddressSpace() { + { + Thread::Current()->TransitionFromSuspendedToRunnable(); + PruneNonImageClasses(); // Remove junk + ComputeLazyFieldsForImageClasses(); // Add useful information + ComputeEagerResolvedStrings(); + Thread::Current()->TransitionFromRunnableToSuspended(kNative); + } + gc::Heap* heap = Runtime::Current()->GetHeap(); + heap->CollectGarbage(false); // Remove garbage. + + if (!AllocMemory()) { + return false; + } + + if (kIsDebugBuild) { + ScopedObjectAccess soa(Thread::Current()); + CheckNonImageClassesRemoved(); + } + + Thread::Current()->TransitionFromSuspendedToRunnable(); + CalculateNewObjectOffsets(); + Thread::Current()->TransitionFromRunnableToSuspended(kNative); + + return true; +} + bool ImageWriter::Write(const std::string& image_filename, - uintptr_t image_begin, const std::string& oat_filename, const std::string& oat_location) { CHECK(!image_filename.empty()); - CHECK_NE(image_begin, 0U); - image_begin_ = reinterpret_cast<byte*>(image_begin); - ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); std::unique_ptr<File> oat_file(OS::OpenFileReadWrite(oat_filename.c_str())); @@ -115,35 +137,18 @@ bool ImageWriter::Write(const std::string& image_filename, oat_file_->GetOatHeader().GetQuickResolutionTrampolineOffset(); quick_to_interpreter_bridge_offset_ = oat_file_->GetOatHeader().GetQuickToInterpreterBridgeOffset(); - { - Thread::Current()->TransitionFromSuspendedToRunnable(); - PruneNonImageClasses(); // Remove junk - ComputeLazyFieldsForImageClasses(); // Add useful information - ComputeEagerResolvedStrings(); - Thread::Current()->TransitionFromRunnableToSuspended(kNative); - } - gc::Heap* heap = Runtime::Current()->GetHeap(); - heap->CollectGarbage(false); // Remove garbage. - if (!AllocMemory()) { - return false; - } - - if (kIsDebugBuild) { - ScopedObjectAccess soa(Thread::Current()); - CheckNonImageClassesRemoved(); - } - - Thread::Current()->TransitionFromSuspendedToRunnable(); size_t oat_loaded_size = 0; size_t oat_data_offset = 0; ElfWriter::GetOatElfInformation(oat_file.get(), oat_loaded_size, oat_data_offset); - CalculateNewObjectOffsets(oat_loaded_size, oat_data_offset); - CopyAndFixupObjects(); - PatchOatCodeAndMethods(oat_file.get()); + Thread::Current()->TransitionFromSuspendedToRunnable(); + CreateHeader(oat_loaded_size, oat_data_offset); + CopyAndFixupObjects(); Thread::Current()->TransitionFromRunnableToSuspended(kNative); + SetOatChecksumFromElfFile(oat_file.get()); + std::unique_ptr<File> image_file(OS::CreateEmptyFile(image_filename.c_str())); ImageHeader* image_header = reinterpret_cast<ImageHeader*>(image_->Begin()); if (image_file.get() == NULL) { @@ -527,8 +532,7 @@ void ImageWriter::WalkFieldsCallback(mirror::Object* obj, void* arg) { writer->WalkFieldsInOrder(obj); } -void ImageWriter::CalculateNewObjectOffsets(size_t oat_loaded_size, size_t oat_data_offset) { - CHECK_NE(0U, oat_loaded_size); +void ImageWriter::CalculateNewObjectOffsets() { Thread* self = Thread::Current(); StackHandleScope<1> hs(self); Handle<ObjectArray<Object>> image_roots(hs.NewHandle(CreateImageRoots())); @@ -548,7 +552,14 @@ void ImageWriter::CalculateNewObjectOffsets(size_t oat_loaded_size, size_t oat_d heap->VisitObjects(WalkFieldsCallback, this); } - const byte* oat_file_begin = image_begin_ + RoundUp(image_end_, kPageSize); + image_roots_address_ = PointerToLowMemUInt32(GetImageAddress(image_roots.Get())); + + // Note that image_end_ is left at end of used space +} + +void ImageWriter::CreateHeader(size_t oat_loaded_size, size_t oat_data_offset) { + CHECK_NE(0U, oat_loaded_size); + const byte* oat_file_begin = GetOatFileBegin(); const byte* oat_file_end = oat_file_begin + oat_loaded_size; oat_data_begin_ = oat_file_begin + oat_data_offset; const byte* oat_data_end = oat_data_begin_ + oat_file_->Size(); @@ -558,21 +569,19 @@ void ImageWriter::CalculateNewObjectOffsets(size_t oat_loaded_size, size_t oat_d const size_t heap_bytes_per_bitmap_byte = kBitsPerByte * kObjectAlignment; const size_t bitmap_bytes = RoundUp(image_end_, heap_bytes_per_bitmap_byte) / heap_bytes_per_bitmap_byte; - ImageHeader image_header(PointerToLowMemUInt32(image_begin_), - static_cast<uint32_t>(image_end_), - RoundUp(image_end_, kPageSize), - RoundUp(bitmap_bytes, kPageSize), - PointerToLowMemUInt32(GetImageAddress(image_roots.Get())), - oat_file_->GetOatHeader().GetChecksum(), - PointerToLowMemUInt32(oat_file_begin), - PointerToLowMemUInt32(oat_data_begin_), - PointerToLowMemUInt32(oat_data_end), - PointerToLowMemUInt32(oat_file_end)); - memcpy(image_->Begin(), &image_header, sizeof(image_header)); - - // Note that image_end_ is left at end of used space + new (image_->Begin()) ImageHeader(PointerToLowMemUInt32(image_begin_), + static_cast<uint32_t>(image_end_), + RoundUp(image_end_, kPageSize), + RoundUp(bitmap_bytes, kPageSize), + image_roots_address_, + oat_file_->GetOatHeader().GetChecksum(), + PointerToLowMemUInt32(oat_file_begin), + PointerToLowMemUInt32(oat_data_begin_), + PointerToLowMemUInt32(oat_data_end), + PointerToLowMemUInt32(oat_file_end)); } + void ImageWriter::CopyAndFixupObjects() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { ScopedAssertNoThreadSuspension ants(Thread::Current(), "ImageWriter"); @@ -809,19 +818,12 @@ static OatHeader* GetOatHeaderFromElf(ElfFile* elf) { return reinterpret_cast<OatHeader*>(elf->Begin() + data_sec->sh_offset); } -void ImageWriter::PatchOatCodeAndMethods(File* elf_file) { +void ImageWriter::SetOatChecksumFromElfFile(File* elf_file) { std::string error_msg; std::unique_ptr<ElfFile> elf(ElfFile::Open(elf_file, PROT_READ|PROT_WRITE, MAP_SHARED, &error_msg)); if (elf.get() == nullptr) { - LOG(FATAL) << "Unable patch oat file: " << error_msg; - return; - } - if (!ElfPatcher::Patch(&compiler_driver_, elf.get(), oat_file_, - reinterpret_cast<uintptr_t>(oat_data_begin_), - GetImageAddressCallback, reinterpret_cast<void*>(this), - &error_msg)) { - LOG(FATAL) << "unable to patch oat file: " << error_msg; + LOG(FATAL) << "Unable open oat file: " << error_msg; return; } OatHeader* oat_header = GetOatHeaderFromElf(elf.get()); |