Rewrite the compiler interface for CompilerDriver.
Change-Id: I15fa9afe7ffb7283ebda8d788a1e02793e3f75a6
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index 5b22817..8bf2f42 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -25,6 +25,7 @@
#include "base/stl_util.h"
#include "base/timing_logger.h"
#include "class_linker.h"
+#include "compiler_backend.h"
#include "dex_compilation_unit.h"
#include "dex_file-inl.h"
#include "dex/verification_results.h"
@@ -52,12 +53,6 @@
#include "verifier/method_verifier.h"
#include "verifier/method_verifier-inl.h"
-#if defined(ART_USE_PORTABLE_COMPILER)
-#include "elf_writer_mclinker.h"
-#else
-#include "elf_writer_quick.h"
-#endif
-
namespace art {
static double Percentage(size_t x, size_t y) {
@@ -287,28 +282,6 @@
DISALLOW_COPY_AND_ASSIGN(AOTCompilationStats);
};
-extern "C" void ArtInitCompilerContext(art::CompilerDriver& driver);
-extern "C" void ArtInitQuickCompilerContext(art::CompilerDriver& driver);
-
-extern "C" void ArtUnInitCompilerContext(art::CompilerDriver& driver);
-extern "C" void ArtUnInitQuickCompilerContext(art::CompilerDriver& driver);
-
-extern "C" art::CompiledMethod* ArtCompileMethod(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);
-extern "C" art::CompiledMethod* ArtQuickCompileMethod(art::CompilerDriver& compiler,
- 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);
extern "C" art::CompiledMethod* ArtCompileDEX(art::CompilerDriver& compiler,
const art::DexFile::CodeItem* code_item,
@@ -318,36 +291,20 @@
uint32_t method_idx,
jobject class_loader,
const art::DexFile& dex_file);
-#ifdef ART_SEA_IR_MODE
-extern "C" art::CompiledMethod* SeaIrCompileMethod(art::CompilerDriver& compiler,
- 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);
-#endif
-extern "C" art::CompiledMethod* ArtLLVMJniCompileMethod(art::CompilerDriver& driver,
- uint32_t access_flags, uint32_t method_idx,
- const art::DexFile& dex_file);
-
-extern "C" art::CompiledMethod* ArtQuickJniCompileMethod(art::CompilerDriver& compiler,
- uint32_t access_flags, uint32_t method_idx,
- const art::DexFile& dex_file);
extern "C" void compilerLLVMSetBitcodeFileName(art::CompilerDriver& driver,
std::string const& filename);
CompilerDriver::CompilerDriver(VerificationResults* verification_results,
DexFileToMethodInlinerMap* method_inliner_map,
- CompilerBackend compiler_backend, InstructionSet instruction_set,
+ CompilerBackend::Kind compiler_backend_kind,
+ InstructionSet instruction_set,
InstructionSetFeatures instruction_set_features,
bool image, DescriptorSet* image_classes, size_t thread_count,
bool dump_stats, bool dump_passes, CumulativeLogger* timer)
: verification_results_(verification_results),
method_inliner_map_(method_inliner_map),
- compiler_backend_(compiler_backend),
+ compiler_backend_(CompilerBackend::Create(compiler_backend_kind)),
instruction_set_(instruction_set),
instruction_set_features_(instruction_set_features),
freezing_constructor_lock_("freezing constructor lock"),
@@ -362,9 +319,7 @@
dump_passes_(dump_passes),
timings_logger_(timer),
compiler_library_(NULL),
- compiler_(NULL),
compiler_context_(NULL),
- jni_compiler_(NULL),
compiler_enable_auto_elf_loading_(NULL),
compiler_get_method_code_addr_(NULL),
support_boot_image_fixup_(instruction_set != kMips),
@@ -375,34 +330,9 @@
CHECK_PTHREAD_CALL(pthread_key_create, (&tls_key_, NULL), "compiler tls key");
- // TODO: more work needed to combine initializations and allow per-method backend selection
- typedef void (*InitCompilerContextFn)(CompilerDriver&);
- InitCompilerContextFn init_compiler_context;
- if (compiler_backend_ == kPortable) {
- // Initialize compiler_context_
- init_compiler_context = reinterpret_cast<void (*)(CompilerDriver&)>(ArtInitCompilerContext);
- compiler_ = reinterpret_cast<CompilerFn>(ArtCompileMethod);
- } else {
- init_compiler_context = reinterpret_cast<void (*)(CompilerDriver&)>(ArtInitQuickCompilerContext);
- compiler_ = reinterpret_cast<CompilerFn>(ArtQuickCompileMethod);
- }
-
dex_to_dex_compiler_ = reinterpret_cast<DexToDexCompilerFn>(ArtCompileDEX);
-#ifdef ART_SEA_IR_MODE
- sea_ir_compiler_ = NULL;
- if (Runtime::Current()->IsSeaIRMode()) {
- sea_ir_compiler_ = reinterpret_cast<CompilerFn>(SeaIrCompileMethod);
- }
-#endif
-
- init_compiler_context(*this);
-
- if (compiler_backend_ == kPortable) {
- jni_compiler_ = reinterpret_cast<JniCompilerFn>(ArtLLVMJniCompileMethod);
- } else {
- jni_compiler_ = reinterpret_cast<JniCompilerFn>(ArtQuickJniCompileMethod);
- }
+ compiler_backend_->Init(*this);
CHECK(!Runtime::Current()->IsStarted());
if (!image_) {
@@ -449,16 +379,7 @@
STLDeleteElements(&classes_to_patch_);
}
CHECK_PTHREAD_CALL(pthread_key_delete, (tls_key_), "delete tls key");
- typedef void (*UninitCompilerContextFn)(CompilerDriver&);
- UninitCompilerContextFn uninit_compiler_context;
- // Uninitialize compiler_context_
- // TODO: rework to combine initialization/uninitialization
- if (compiler_backend_ == kPortable) {
- uninit_compiler_context = reinterpret_cast<void (*)(CompilerDriver&)>(ArtUnInitCompilerContext);
- } else {
- uninit_compiler_context = reinterpret_cast<void (*)(CompilerDriver&)>(ArtUnInitQuickCompilerContext);
- }
- uninit_compiler_context(*this);
+ compiler_backend_->UnInit(*this);
}
CompilerTls* CompilerDriver::GetTls() {
@@ -1153,7 +1074,7 @@
*direct_method = 0;
bool use_dex_cache = false;
const bool compiling_boot = Runtime::Current()->GetHeap()->IsCompilingBoot();
- if (compiler_backend_ == kPortable) {
+ if (compiler_backend_->IsPortable()) {
if (sharp_type != kStatic && sharp_type != kDirect) {
return;
}
@@ -1230,23 +1151,13 @@
CHECK(!method->IsAbstract());
*type = sharp_type;
*direct_method = reinterpret_cast<uintptr_t>(method);
- if (compiler_backend_ == kQuick) {
- *direct_code = reinterpret_cast<uintptr_t>(method->GetEntryPointFromQuickCompiledCode());
- } else {
- CHECK_EQ(compiler_backend_, kPortable);
- *direct_code = reinterpret_cast<uintptr_t>(method->GetEntryPointFromPortableCompiledCode());
- }
+ *direct_code = compiler_backend_->GetEntryPointOf(method);
target_method->dex_file = method->GetDeclaringClass()->GetDexCache()->GetDexFile();
target_method->dex_method_index = method->GetDexMethodIndex();
} else if (!must_use_direct_pointers) {
// Set the code and rely on the dex cache for the method.
*type = sharp_type;
- if (compiler_backend_ == kQuick) {
- *direct_code = reinterpret_cast<uintptr_t>(method->GetEntryPointFromQuickCompiledCode());
- } else {
- CHECK_EQ(compiler_backend_, kPortable);
- *direct_code = reinterpret_cast<uintptr_t>(method->GetEntryPointFromPortableCompiledCode());
- }
+ *direct_code = compiler_backend_->GetEntryPointOf(method);
} else {
// Direct pointers were required but none were available.
VLOG(compiler) << "Dex cache devirtualization failed for: " << PrettyMethod(method);
@@ -2417,7 +2328,7 @@
uint64_t start_ns = NanoTime();
if ((access_flags & kAccNative) != 0) {
- compiled_method = (*jni_compiler_)(*this, access_flags, method_idx, dex_file);
+ compiled_method = compiler_backend_->JniCompile(*this, access_flags, method_idx, dex_file);
CHECK(compiled_method != NULL);
} else if ((access_flags & kAccAbstract) != 0) {
} else {
@@ -2425,19 +2336,10 @@
bool compile = VerificationResults::IsCandidateForCompilation(method_ref, access_flags);
if (compile) {
- CompilerFn compiler = compiler_;
-#ifdef ART_SEA_IR_MODE
- bool use_sea = Runtime::Current()->IsSeaIRMode();
- use_sea = use_sea &&
- (std::string::npos != PrettyMethod(method_idx, dex_file).find("fibonacci"));
- if (use_sea) {
- compiler = sea_ir_compiler_;
- LOG(INFO) << "Using SEA IR to compile..." << std::endl;
- }
-#endif
// NOTE: if compiler declines to compile this method, it will return NULL.
- compiled_method = (*compiler)(*this, code_item, access_flags, invoke_type, class_def_idx,
- method_idx, class_loader, dex_file);
+ compiled_method = compiler_backend_->Compile(
+ *this, code_item, access_flags, invoke_type, class_def_idx,
+ method_idx, class_loader, dex_file);
} else if (dex_to_dex_compilation_level != kDontDexToDexCompile) {
// TODO: add a mode to disable DEX-to-DEX compilation ?
(*dex_to_dex_compiler_)(*this, code_item, access_flags,
@@ -2447,12 +2349,7 @@
}
}
uint64_t duration_ns = NanoTime() - start_ns;
-#ifdef ART_USE_PORTABLE_COMPILER
- const uint64_t kWarnMilliSeconds = 1000;
-#else
- const uint64_t kWarnMilliSeconds = 100;
-#endif
- if (duration_ns > MsToNs(kWarnMilliSeconds)) {
+ if (duration_ns > MsToNs(compiler_backend_->GetMaximumCompilationTimeBeforeWarning())) {
LOG(WARNING) << "Compilation of " << PrettyMethod(method_idx, dex_file)
<< " took " << PrettyDuration(duration_ns);
}
@@ -2549,11 +2446,7 @@
OatWriter& oat_writer,
art::File* file)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-#if defined(ART_USE_PORTABLE_COMPILER)
- return art::ElfWriterMclinker::Create(file, oat_writer, dex_files, android_root, is_host, *this);
-#else
- return art::ElfWriterQuick::Create(file, oat_writer, dex_files, android_root, is_host, *this);
-#endif
+ return compiler_backend_->WriteElf(file, oat_writer, dex_files, android_root, is_host, *this);
}
void CompilerDriver::InstructionSetToLLVMTarget(InstructionSet instruction_set,
std::string& target_triple,