diff options
author | 2015-07-13 11:53:56 +0000 | |
---|---|---|
committer | 2015-07-13 11:53:56 +0000 | |
commit | 327c5ed30a1f016ef3e1bb26ea7b4abd34eb63b9 (patch) | |
tree | 55d58d66f154edade95e909a6badf3bb43f75be9 | |
parent | 6920703c8eae0d90528ea09945e742582b6f8198 (diff) |
Revert "Make dex2dex return a CompiledMethod after quickening."
Build failures on arm/arm64.
This reverts commit 6920703c8eae0d90528ea09945e742582b6f8198.
Change-Id: I0dd5426610150937dac6e4d9dd9aa759bdf7fca4
-rw-r--r-- | compiler/compiled_method.cc | 3 | ||||
-rw-r--r-- | compiler/dex/dex_to_dex_compiler.cc | 67 | ||||
-rw-r--r-- | compiler/driver/compiler_driver.cc | 14 | ||||
-rw-r--r-- | compiler/driver/compiler_driver.h | 13 | ||||
-rw-r--r-- | compiler/image_writer.h | 2 | ||||
-rw-r--r-- | compiler/oat_writer.cc | 180 |
6 files changed, 110 insertions, 169 deletions
diff --git a/compiler/compiled_method.cc b/compiler/compiled_method.cc index f33db09677..d1acada6dd 100644 --- a/compiler/compiled_method.cc +++ b/compiler/compiled_method.cc @@ -27,7 +27,8 @@ CompiledCode::CompiledCode(CompilerDriver* compiler_driver, InstructionSet instr } void CompiledCode::SetCode(const ArrayRef<const uint8_t>* quick_code) { - if (quick_code != nullptr && !quick_code->empty()) { + if (quick_code != nullptr) { + CHECK(!quick_code->empty()); if (owns_code_array_) { // If we are supposed to own the code, don't deduplicate it. CHECK(quick_code_ == nullptr); diff --git a/compiler/dex/dex_to_dex_compiler.cc b/compiler/dex/dex_to_dex_compiler.cc index b0bbbf619c..bd590467e3 100644 --- a/compiler/dex/dex_to_dex_compiler.cc +++ b/compiler/dex/dex_to_dex_compiler.cc @@ -18,7 +18,6 @@ #include "art_method-inl.h" #include "base/logging.h" #include "base/mutex.h" -#include "compiled_method.h" #include "dex_file-inl.h" #include "dex_instruction-inl.h" #include "driver/compiler_driver.h" @@ -35,13 +34,6 @@ const bool kEnableQuickening = true; // Control check-cast elision. const bool kEnableCheckCastEllision = true; -struct QuickenedInfo { - QuickenedInfo(uint32_t pc, uint16_t index) : dex_pc(pc), dex_member_index(index) {} - - uint32_t dex_pc; - uint16_t dex_member_index; -}; - class DexCompiler { public: DexCompiler(art::CompilerDriver& compiler, @@ -55,10 +47,6 @@ class DexCompiler { void Compile(); - const std::vector<QuickenedInfo>& GetQuickenedInfo() const { - return quickened_info_; - } - private: const DexFile& GetDexFile() const { return *unit_.GetDexFile(); @@ -99,11 +87,6 @@ class DexCompiler { const DexCompilationUnit& unit_; const DexToDexCompilationLevel dex_to_dex_compilation_level_; - // Filled by the compiler when quickening, in order to encode that information - // in the .oat file. The runtime will use that information to get to the original - // opcodes. - std::vector<QuickenedInfo> quickened_info_; - DISALLOW_COPY_AND_ASSIGN(DexCompiler); }; @@ -265,7 +248,6 @@ void DexCompiler::CompileInstanceFieldAccess(Instruction* inst, inst->SetOpcode(new_opcode); // Replace field index by field offset. inst->SetVRegC_22c(static_cast<uint16_t>(field_offset.Int32Value())); - quickened_info_.push_back(QuickenedInfo(dex_pc, field_idx)); } } @@ -305,55 +287,24 @@ void DexCompiler::CompileInvokeVirtual(Instruction* inst, uint32_t dex_pc, } else { inst->SetVRegB_35c(static_cast<uint16_t>(vtable_idx)); } - quickened_info_.push_back(QuickenedInfo(dex_pc, method_idx)); } } } -extern "C" CompiledMethod* ArtCompileDEX( - art::CompilerDriver& driver, - const art::DexFile::CodeItem* code_item, - uint32_t access_flags, - art::InvokeType invoke_type ATTRIBUTE_UNUSED, - uint16_t class_def_idx, - uint32_t method_idx, - jobject class_loader, - const art::DexFile& dex_file, - art::DexToDexCompilationLevel dex_to_dex_compilation_level) { +} // namespace optimizer +} // namespace art + +extern "C" void ArtCompileDEX(art::CompilerDriver& driver, const art::DexFile::CodeItem* code_item, + uint32_t access_flags, art::InvokeType invoke_type, + uint16_t class_def_idx, uint32_t method_idx, jobject class_loader, + const art::DexFile& dex_file, + art::DexToDexCompilationLevel dex_to_dex_compilation_level) { + UNUSED(invoke_type); if (dex_to_dex_compilation_level != art::kDontDexToDexCompile) { art::DexCompilationUnit unit(nullptr, class_loader, art::Runtime::Current()->GetClassLinker(), dex_file, code_item, class_def_idx, method_idx, access_flags, driver.GetVerifiedMethod(&dex_file, method_idx)); art::optimizer::DexCompiler dex_compiler(driver, unit, dex_to_dex_compilation_level); dex_compiler.Compile(); - if (dex_compiler.GetQuickenedInfo().empty()) { - // No need to create a CompiledMethod if there are no quickened opcodes. - return nullptr; - } - - // Create a `CompiledMethod`, with the quickened information in the vmap table. - Leb128EncodingVector builder; - for (QuickenedInfo info : dex_compiler.GetQuickenedInfo()) { - builder.PushBackUnsigned(info.dex_pc); - builder.PushBackUnsigned(info.dex_member_index); - } - return CompiledMethod::SwapAllocCompiledMethod( - &driver, - driver.GetInstructionSet(), - ArrayRef<const uint8_t>(), // no code - 0, - 0, - 0, - nullptr, // src_mapping_table - ArrayRef<const uint8_t>(), // mapping_table - ArrayRef<const uint8_t>(builder.GetData()), // vmap_table - ArrayRef<const uint8_t>(), // gc_map - ArrayRef<const uint8_t>(), // cfi data - ArrayRef<const LinkerPatch>()); } - return nullptr; } - -} // namespace optimizer - -} // namespace art diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc index a52bfaeb5b..7890108f41 100644 --- a/compiler/driver/compiler_driver.cc +++ b/compiler/driver/compiler_driver.cc @@ -2291,16 +2291,10 @@ void CompilerDriver::CompileMethod(Thread* self, const DexFile::CodeItem* code_i // TODO: add a command-line option to disable DEX-to-DEX compilation ? // Do not optimize if a VerifiedMethod is missing. SafeCast elision, for example, relies on // it. - compiled_method = (*dex_to_dex_compiler_)( - *this, - code_item, - access_flags, - invoke_type, - class_def_idx, - method_idx, - class_loader, - dex_file, - has_verified_method ? dex_to_dex_compilation_level : kRequired); + (*dex_to_dex_compiler_)(*this, code_item, access_flags, + invoke_type, class_def_idx, + method_idx, class_loader, dex_file, + has_verified_method ? dex_to_dex_compilation_level : kRequired); } } if (kTimeCompileMethod) { diff --git a/compiler/driver/compiler_driver.h b/compiler/driver/compiler_driver.h index 5cf4044fd4..2d7ceaeea1 100644 --- a/compiler/driver/compiler_driver.h +++ b/compiler/driver/compiler_driver.h @@ -675,13 +675,12 @@ class CompilerDriver { typedef void (*CompilerCallbackFn)(CompilerDriver& driver); typedef MutexLock* (*CompilerMutexLockFn)(CompilerDriver& driver); - typedef CompiledMethod* (*DexToDexCompilerFn)( - CompilerDriver& driver, - const DexFile::CodeItem* code_item, - uint32_t access_flags, InvokeType invoke_type, - uint32_t class_dex_idx, uint32_t method_idx, - jobject class_loader, const DexFile& dex_file, - DexToDexCompilationLevel dex_to_dex_compilation_level); + typedef void (*DexToDexCompilerFn)(CompilerDriver& driver, + const DexFile::CodeItem* code_item, + uint32_t access_flags, InvokeType invoke_type, + uint32_t class_dex_idx, uint32_t method_idx, + jobject class_loader, const DexFile& dex_file, + DexToDexCompilationLevel dex_to_dex_compilation_level); DexToDexCompilerFn dex_to_dex_compiler_; void* compiler_context_; diff --git a/compiler/image_writer.h b/compiler/image_writer.h index 62d8a691af..9d45ce2bd4 100644 --- a/compiler/image_writer.h +++ b/compiler/image_writer.h @@ -199,7 +199,7 @@ class ImageWriter FINAL { const uint8_t* GetOatAddress(uint32_t offset) const { // With Quick, code is within the OatFile, as there are all in one // .o ELF object. - DCHECK_LE(offset, oat_file_->Size()); + DCHECK_LT(offset, oat_file_->Size()); DCHECK(oat_data_begin_ != nullptr); return offset == 0u ? nullptr : oat_data_begin_ + offset; } diff --git a/compiler/oat_writer.cc b/compiler/oat_writer.cc index a2551e567c..a98a3046e5 100644 --- a/compiler/oat_writer.cc +++ b/compiler/oat_writer.cc @@ -374,23 +374,23 @@ class OatWriter::InitCodeMethodVisitor : public OatDexMethodVisitor { uint32_t quick_code_offset = 0; const SwapVector<uint8_t>* quick_code = compiled_method->GetQuickCode(); - uint32_t code_size = (quick_code == nullptr) ? 0 : quick_code->size() * sizeof(uint8_t); + CHECK(quick_code != nullptr); + uint32_t code_size = quick_code->size() * sizeof(uint8_t); + CHECK_NE(code_size, 0U); uint32_t thumb_offset = compiled_method->CodeDelta(); // Deduplicate code arrays if we are not producing debuggable code. bool deduped = false; - if (code_size != 0) { - if (debuggable_) { - quick_code_offset = NewQuickCodeOffset(compiled_method, it, thumb_offset); + if (debuggable_) { + quick_code_offset = NewQuickCodeOffset(compiled_method, it, thumb_offset); + } else { + auto lb = dedupe_map_.lower_bound(compiled_method); + if (lb != dedupe_map_.end() && !dedupe_map_.key_comp()(compiled_method, lb->first)) { + quick_code_offset = lb->second; + deduped = true; } else { - auto lb = dedupe_map_.lower_bound(compiled_method); - if (lb != dedupe_map_.end() && !dedupe_map_.key_comp()(compiled_method, lb->first)) { - quick_code_offset = lb->second; - deduped = true; - } else { - quick_code_offset = NewQuickCodeOffset(compiled_method, it, thumb_offset); - dedupe_map_.PutBefore(lb, compiled_method, quick_code_offset); - } + quick_code_offset = NewQuickCodeOffset(compiled_method, it, thumb_offset); + dedupe_map_.PutBefore(lb, compiled_method, quick_code_offset); } } @@ -411,24 +411,21 @@ class OatWriter::InitCodeMethodVisitor : public OatDexMethodVisitor { OatQuickMethodHeader* method_header = &oat_class->method_headers_[method_offsets_index_]; uint32_t mapping_table_offset = method_header->mapping_table_offset_; uint32_t vmap_table_offset = method_header->vmap_table_offset_; - // If we don't have quick code, then we must have a vmap, as that is how the dex2dex - // compiler records its transformations. - DCHECK(quick_code != nullptr || vmap_table_offset != 0); uint32_t gc_map_offset = method_header->gc_map_offset_; // The code offset was 0 when the mapping/vmap table offset was set, so it's set // to 0-offset and we need to adjust it by code_offset. uint32_t code_offset = quick_code_offset - thumb_offset; - if (mapping_table_offset != 0u && code_offset != 0u) { + if (mapping_table_offset != 0u) { mapping_table_offset += code_offset; - DCHECK_LT(mapping_table_offset, code_offset) << "Overflow in oat offsets"; + DCHECK_LT(mapping_table_offset, code_offset); } - if (vmap_table_offset != 0u && code_offset != 0u) { + if (vmap_table_offset != 0u) { vmap_table_offset += code_offset; - DCHECK_LT(vmap_table_offset, code_offset) << "Overflow in oat offsets"; + DCHECK_LT(vmap_table_offset, code_offset); } - if (gc_map_offset != 0u && code_offset != 0u) { + if (gc_map_offset != 0u) { gc_map_offset += code_offset; - DCHECK_LT(gc_map_offset, code_offset) << "Overflow in oat offsets"; + DCHECK_LT(gc_map_offset, code_offset); } uint32_t frame_size_in_bytes = compiled_method->GetFrameSizeInBytes(); uint32_t core_spill_mask = compiled_method->GetCoreSpillMask(); @@ -437,7 +434,7 @@ class OatWriter::InitCodeMethodVisitor : public OatDexMethodVisitor { gc_map_offset, frame_size_in_bytes, core_spill_mask, fp_spill_mask, code_size); - if (!deduped && (code_size != 0)) { + if (!deduped) { // Update offsets. (Checksum is updated when writing.) offset_ += sizeof(*method_header); // Method header is prepended before code. offset_ += code_size; @@ -692,86 +689,85 @@ class OatWriter::WriteCodeMethodVisitor : public OatDexMethodVisitor { OutputStream* out = out_; const SwapVector<uint8_t>* quick_code = compiled_method->GetQuickCode(); - // Need a wrapper if we create a copy for patching. - ArrayRef<const uint8_t> wrapped; - uint32_t code_size = 0; if (quick_code != nullptr) { - wrapped = (*quick_code); - code_size = quick_code->size() * sizeof(uint8_t); - } - - // Deduplicate code arrays. - const OatMethodOffsets& method_offsets = oat_class->method_offsets_[method_offsets_index_]; - if (method_offsets.code_offset_ > offset_) { - offset_ = writer_->relative_patcher_->WriteThunks(out, offset_); - if (offset_ == 0u) { - 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)) { - ReportWriteFailure("code alignment padding", it); + // Need a wrapper if we create a copy for patching. + ArrayRef<const uint8_t> wrapped(*quick_code); + uint32_t code_size = quick_code->size() * sizeof(uint8_t); + CHECK_NE(code_size, 0U); + + // Deduplicate code arrays. + const OatMethodOffsets& method_offsets = oat_class->method_offsets_[method_offsets_index_]; + if (method_offsets.code_offset_ >= offset_) { + offset_ = writer_->relative_patcher_->WriteThunks(out, offset_); + if (offset_ == 0u) { + 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)) { + ReportWriteFailure("code alignment padding", it); + return false; + } + offset_ += aligned_code_delta; + DCHECK_OFFSET_(); + } + DCHECK_ALIGNED_PARAM(offset_, + GetInstructionSetAlignment(compiled_method->GetInstructionSet())); + DCHECK_EQ(method_offsets.code_offset_, + offset_ + sizeof(OatQuickMethodHeader) + compiled_method->CodeDelta()) + << PrettyMethod(it.GetMemberIndex(), *dex_file_); + const OatQuickMethodHeader& method_header = + oat_class->method_headers_[method_offsets_index_]; + writer_->oat_header_->UpdateChecksum(&method_header, sizeof(method_header)); + if (!out->WriteFully(&method_header, sizeof(method_header))) { + ReportWriteFailure("method header", it); return false; } - offset_ += aligned_code_delta; + writer_->size_method_header_ += sizeof(method_header); + offset_ += sizeof(method_header); DCHECK_OFFSET_(); - } - DCHECK_ALIGNED_PARAM(offset_, - GetInstructionSetAlignment(compiled_method->GetInstructionSet())); - DCHECK_EQ(method_offsets.code_offset_, - offset_ + sizeof(OatQuickMethodHeader) + compiled_method->CodeDelta()) - << PrettyMethod(it.GetMemberIndex(), *dex_file_); - const OatQuickMethodHeader& method_header = - oat_class->method_headers_[method_offsets_index_]; - writer_->oat_header_->UpdateChecksum(&method_header, sizeof(method_header)); - if (!out->WriteFully(&method_header, sizeof(method_header))) { - ReportWriteFailure("method header", it); - return false; - } - writer_->size_method_header_ += sizeof(method_header); - offset_ += sizeof(method_header); - DCHECK_OFFSET_(); - if (!compiled_method->GetPatches().empty()) { - patched_code_.assign(quick_code->begin(), quick_code->end()); - wrapped = ArrayRef<const uint8_t>(patched_code_); - for (const LinkerPatch& patch : compiled_method->GetPatches()) { - if (patch.Type() == kLinkerPatchCallRelative) { - // NOTE: Relative calls across oat files are not supported. - uint32_t target_offset = GetTargetOffset(patch); - uint32_t literal_offset = patch.LiteralOffset(); - writer_->relative_patcher_->PatchCall(&patched_code_, literal_offset, - offset_ + literal_offset, target_offset); - } else if (patch.Type() == kLinkerPatchDexCacheArray) { - uint32_t target_offset = GetDexCacheOffset(patch); - uint32_t literal_offset = patch.LiteralOffset(); - writer_->relative_patcher_->PatchDexCacheReference(&patched_code_, patch, - offset_ + literal_offset, - target_offset); - } else if (patch.Type() == kLinkerPatchCall) { - uint32_t target_offset = GetTargetOffset(patch); - PatchCodeAddress(&patched_code_, patch.LiteralOffset(), target_offset); - } else if (patch.Type() == kLinkerPatchMethod) { - ArtMethod* method = GetTargetMethod(patch); - PatchMethodAddress(&patched_code_, patch.LiteralOffset(), method); - } else if (patch.Type() == kLinkerPatchType) { - mirror::Class* type = GetTargetType(patch); - PatchObjectAddress(&patched_code_, patch.LiteralOffset(), type); + if (!compiled_method->GetPatches().empty()) { + patched_code_.assign(quick_code->begin(), quick_code->end()); + wrapped = ArrayRef<const uint8_t>(patched_code_); + for (const LinkerPatch& patch : compiled_method->GetPatches()) { + if (patch.Type() == kLinkerPatchCallRelative) { + // NOTE: Relative calls across oat files are not supported. + uint32_t target_offset = GetTargetOffset(patch); + uint32_t literal_offset = patch.LiteralOffset(); + writer_->relative_patcher_->PatchCall(&patched_code_, literal_offset, + offset_ + literal_offset, target_offset); + } else if (patch.Type() == kLinkerPatchDexCacheArray) { + uint32_t target_offset = GetDexCacheOffset(patch); + uint32_t literal_offset = patch.LiteralOffset(); + writer_->relative_patcher_->PatchDexCacheReference(&patched_code_, patch, + offset_ + literal_offset, + target_offset); + } else if (patch.Type() == kLinkerPatchCall) { + uint32_t target_offset = GetTargetOffset(patch); + PatchCodeAddress(&patched_code_, patch.LiteralOffset(), target_offset); + } else if (patch.Type() == kLinkerPatchMethod) { + ArtMethod* method = GetTargetMethod(patch); + PatchMethodAddress(&patched_code_, patch.LiteralOffset(), method); + } else if (patch.Type() == kLinkerPatchType) { + mirror::Class* type = GetTargetType(patch); + PatchObjectAddress(&patched_code_, patch.LiteralOffset(), type); + } } } - } - writer_->oat_header_->UpdateChecksum(wrapped.data(), code_size); - if (!out->WriteFully(wrapped.data(), code_size)) { - ReportWriteFailure("method code", it); - return false; + writer_->oat_header_->UpdateChecksum(wrapped.data(), code_size); + if (!out->WriteFully(wrapped.data(), code_size)) { + ReportWriteFailure("method code", it); + return false; + } + writer_->size_code_ += code_size; + offset_ += code_size; } - writer_->size_code_ += code_size; - offset_ += code_size; + DCHECK_OFFSET_(); } - DCHECK_OFFSET_(); ++method_offsets_index_; } |