Revert "Revert "Revert "Revert "Make dex2dex return a CompiledMethod after quickening.""""
This reverts commit ed6195a514e3253576af27ea9ba13038509d29ac.
Change-Id: Icb58854301e8982147cdebe3edf2e0d9e0a63a56
diff --git a/compiler/dex/dex_to_dex_compiler.cc b/compiler/dex/dex_to_dex_compiler.cc
index bd59046..4b56b69 100644
--- a/compiler/dex/dex_to_dex_compiler.cc
+++ b/compiler/dex/dex_to_dex_compiler.cc
@@ -18,6 +18,7 @@
#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"
@@ -34,6 +35,13 @@
// 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,
@@ -47,6 +55,10 @@
void Compile();
+ const std::vector<QuickenedInfo>& GetQuickenedInfo() const {
+ return quickened_info_;
+ }
+
private:
const DexFile& GetDexFile() const {
return *unit_.GetDexFile();
@@ -87,6 +99,11 @@
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);
};
@@ -248,6 +265,7 @@
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));
}
}
@@ -287,24 +305,60 @@
} else {
inst->SetVRegB_35c(static_cast<uint16_t>(vtable_idx));
}
+ quickened_info_.push_back(QuickenedInfo(dex_pc, method_idx));
}
}
}
-} // 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);
+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) {
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);
+ }
+ InstructionSet instruction_set = driver.GetInstructionSet();
+ if (instruction_set == kThumb2) {
+ // Don't use the thumb2 instruction set to avoid the one off code delta.
+ instruction_set = kArm;
+ }
+ return CompiledMethod::SwapAllocCompiledMethod(
+ &driver,
+ instruction_set,
+ 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