diff options
Diffstat (limited to 'compiler/oat_writer.cc')
| -rw-r--r-- | compiler/oat_writer.cc | 49 |
1 files changed, 31 insertions, 18 deletions
diff --git a/compiler/oat_writer.cc b/compiler/oat_writer.cc index cdc7df11b6..8a809822df 100644 --- a/compiler/oat_writer.cc +++ b/compiler/oat_writer.cc @@ -23,6 +23,7 @@ #include "art_method-inl.h" #include "base/allocator.h" #include "base/bit_vector.h" +#include "base/enums.h" #include "base/file_magic.h" #include "base/stl_util.h" #include "base/unix_file/fd_file.h" @@ -86,6 +87,13 @@ class ChecksumUpdatingOutputStream : public OutputStream { OatHeader* const oat_header_; }; +inline uint32_t CodeAlignmentSize(uint32_t header_offset, const CompiledMethod& compiled_method) { + // We want to align the code rather than the preheader. + uint32_t unaligned_code_offset = header_offset + sizeof(OatQuickMethodHeader); + uint32_t aligned_code_offset = compiled_method.AlignCode(unaligned_code_offset); + return aligned_code_offset - unaligned_code_offset; +} + } // anonymous namespace // Defines the location of the raw dex file to write. @@ -323,14 +331,14 @@ bool OatWriter::AddDexFileSource(const char* filename, DCHECK(write_state_ == WriteState::kAddingDexFileSources); uint32_t magic; std::string error_msg; - ScopedFd fd(OpenAndReadMagic(filename, &magic, &error_msg)); - if (fd.get() == -1) { + File fd = OpenAndReadMagic(filename, &magic, &error_msg); + if (fd.Fd() == -1) { PLOG(ERROR) << "Failed to read magic number from dex file: '" << filename << "'"; return false; } else if (IsDexMagic(magic)) { // The file is open for reading, not writing, so it's OK to let the File destructor // close it without checking for explicit Close(), so pass checkUsage = false. - raw_dex_files_.emplace_back(new File(fd.release(), location, /* checkUsage */ false)); + raw_dex_files_.emplace_back(new File(fd.Release(), location, /* checkUsage */ false)); oat_dex_files_.emplace_back(location, DexFileSource(raw_dex_files_.back().get()), create_type_lookup_table); @@ -346,12 +354,12 @@ bool OatWriter::AddDexFileSource(const char* filename, } // Add dex file source(s) from a zip file specified by a file handle. -bool OatWriter::AddZippedDexFilesSource(ScopedFd&& zip_fd, +bool OatWriter::AddZippedDexFilesSource(File&& zip_fd, const char* location, CreateTypeLookupTable create_type_lookup_table) { DCHECK(write_state_ == WriteState::kAddingDexFileSources); std::string error_msg; - zip_archives_.emplace_back(ZipArchive::OpenFromFd(zip_fd.release(), location, &error_msg)); + zip_archives_.emplace_back(ZipArchive::OpenFromFd(zip_fd.Release(), location, &error_msg)); ZipArchive* zip_archive = zip_archives_.back().get(); if (zip_archive == nullptr) { LOG(ERROR) << "Failed to open zip from file descriptor for '" << location << "': " @@ -506,7 +514,7 @@ void OatWriter::PrepareLayout(const CompilerDriver* compiler, if (!HasBootImage()) { // Allocate space for app dex cache arrays in the .bss section. size_t bss_start = RoundUp(size_, kPageSize); - size_t pointer_size = GetInstructionSetPointerSize(instruction_set); + PointerSize pointer_size = GetInstructionSetPointerSize(instruction_set); bss_size_ = 0u; for (const DexFile* dex_file : *dex_files_) { dex_cache_arrays_offsets_.Put(dex_file, bss_start + bss_size_); @@ -816,8 +824,8 @@ class OatWriter::InitCodeMethodVisitor : public OatDexMethodVisitor { uint32_t thumb_offset) { offset_ = writer_->relative_patcher_->ReserveSpace( offset_, compiled_method, MethodReference(dex_file_, it.GetMemberIndex())); - offset_ = compiled_method->AlignCode(offset_); - DCHECK_ALIGNED_PARAM(offset_, + offset_ += CodeAlignmentSize(offset_, *compiled_method); + DCHECK_ALIGNED_PARAM(offset_ + sizeof(OatQuickMethodHeader), GetInstructionSetAlignment(compiled_method->GetInstructionSet())); return offset_ + sizeof(OatQuickMethodHeader) + thumb_offset; } @@ -941,7 +949,7 @@ class OatWriter::InitImageMethodVisitor : public OatDexMethodVisitor { } protected: - const size_t pointer_size_; + const PointerSize pointer_size_; }; class OatWriter::WriteCodeMethodVisitor : public OatDexMethodVisitor { @@ -1010,17 +1018,16 @@ class OatWriter::WriteCodeMethodVisitor : public OatDexMethodVisitor { ReportWriteFailure("relative call thunk", it); return false; } - uint32_t aligned_offset = compiled_method->AlignCode(offset_); - uint32_t aligned_code_delta = aligned_offset - offset_; - if (aligned_code_delta != 0) { - if (!writer_->WriteCodeAlignment(out, aligned_code_delta)) { + uint32_t alignment_size = CodeAlignmentSize(offset_, *compiled_method); + if (alignment_size != 0) { + if (!writer_->WriteCodeAlignment(out, alignment_size)) { ReportWriteFailure("code alignment padding", it); return false; } - offset_ += aligned_code_delta; + offset_ += alignment_size; DCHECK_OFFSET_(); } - DCHECK_ALIGNED_PARAM(offset_, + DCHECK_ALIGNED_PARAM(offset_ + sizeof(OatQuickMethodHeader), GetInstructionSetAlignment(compiled_method->GetInstructionSet())); DCHECK_EQ(method_offsets.code_offset_, offset_ + sizeof(OatQuickMethodHeader) + compiled_method->CodeDelta()) @@ -1149,7 +1156,8 @@ class OatWriter::WriteCodeMethodVisitor : public OatDexMethodVisitor { if (UNLIKELY(target_offset == 0)) { ArtMethod* target = GetTargetMethod(patch); DCHECK(target != nullptr); - size_t size = GetInstructionSetPointerSize(writer_->compiler_driver_->GetInstructionSet()); + PointerSize size = + GetInstructionSetPointerSize(writer_->compiler_driver_->GetInstructionSet()); const void* oat_code_offset = target->GetEntryPointFromQuickCompiledCodePtrSize(size); if (oat_code_offset != 0) { DCHECK(!writer_->HasBootImage()); @@ -1181,8 +1189,13 @@ class OatWriter::WriteCodeMethodVisitor : public OatDexMethodVisitor { } mirror::String* GetTargetString(const LinkerPatch& patch) SHARED_REQUIRES(Locks::mutator_lock_) { - mirror::DexCache* dex_cache = GetDexCache(patch.TargetStringDexFile()); - mirror::String* string = dex_cache->GetResolvedString(patch.TargetStringIndex()); + ScopedObjectAccessUnchecked soa(Thread::Current()); + StackHandleScope<1> hs(soa.Self()); + ClassLinker* linker = Runtime::Current()->GetClassLinker(); + Handle<mirror::DexCache> dex_cache(hs.NewHandle(GetDexCache(patch.TargetStringDexFile()))); + mirror::String* string = linker->LookupString(*patch.TargetStringDexFile(), + patch.TargetStringIndex(), + dex_cache); DCHECK(string != nullptr); DCHECK(writer_->HasBootImage() || Runtime::Current()->GetHeap()->ObjectIsInBootImageSpace(string)); |