diff options
| -rw-r--r-- | src/compiler.cc | 15 | ||||
| -rw-r--r-- | src/compiler_llvm/compilation_unit.cc | 14 | ||||
| -rw-r--r-- | src/compiler_llvm/compilation_unit.h | 6 | ||||
| -rw-r--r-- | src/compiler_llvm/compiler_llvm.cc | 102 | ||||
| -rw-r--r-- | src/compiler_llvm/compiler_llvm.h | 18 |
5 files changed, 85 insertions, 70 deletions
diff --git a/src/compiler.cc b/src/compiler.cc index 4b03433569..51354aa368 100644 --- a/src/compiler.cc +++ b/src/compiler.cc @@ -347,7 +347,7 @@ void Compiler::PostCompile(const ClassLoader* class_loader, const std::vector<const DexFile*>& dex_files) { SetGcMaps(class_loader, dex_files); #if defined(ART_USE_LLVM_COMPILER) - compiler_llvm_->MaterializeEveryCompilationUnit(); + compiler_llvm_->MaterializeRemainder(); #endif } @@ -925,6 +925,15 @@ void Compiler::CompileClass(Context* context, size_t class_def_index) { const ClassLoader* class_loader = context->class_loader; const DexFile& dex_file = *context->dex_file; const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index); + +#if defined(ART_USE_LLVM_COMPILER) + compiler_llvm::CompilerLLVM* compiler_llvm = context->compiler->GetCompilerLLVM(); + + MutexLock GUARD(compiler_llvm->compiler_lock_); + // TODO: Remove this. We should not lock the compiler_lock_ in CompileClass() + // However, without this mutex lock, we will get segmentation fault. +#endif + if (SkipClass(class_loader, dex_file, class_def)) { return; } @@ -959,6 +968,10 @@ void Compiler::CompileClass(Context* context, size_t class_def_index) { it.Next(); } DCHECK(!it.HasNext()); + +#if defined(ART_USE_LLVM_COMPILER) + compiler_llvm->MaterializeIfThresholdReached(); +#endif } void Compiler::CompileDexFile(const ClassLoader* class_loader, const DexFile& dex_file) { diff --git a/src/compiler_llvm/compilation_unit.cc b/src/compiler_llvm/compilation_unit.cc index 08c3dfc593..ac956ef6c4 100644 --- a/src/compiler_llvm/compilation_unit.cc +++ b/src/compiler_llvm/compilation_unit.cc @@ -193,24 +193,22 @@ bool CompilationUnit::Materialize() { fpm.run(*F); } fpm.doFinalization(); - LOG(INFO) << "Intraprocedural optimization finished!"; // Run the code generation passes pm.run(*module_); - LOG(INFO) << "Code generation finished!"; + // Keep the generated executable out_file->keep(); - LOG(DEBUG) << "ELF: " << elf_filename_ << " (done)"; + LOG(INFO) << "ELF: " << elf_filename_ << " (done)"; - return true; -} - - -void CompilationUnit::Finalize() { + // Free the resources context_.reset(NULL); irb_.reset(NULL); module_ = NULL; + + return true; } + } // namespace compiler_llvm } // namespace art diff --git a/src/compiler_llvm/compilation_unit.h b/src/compiler_llvm/compilation_unit.h index a10d977219..2ae5c0bae8 100644 --- a/src/compiler_llvm/compilation_unit.h +++ b/src/compiler_llvm/compilation_unit.h @@ -56,12 +56,10 @@ class CompilationUnit { } std::string const& GetElfFileName() const { - CHECK(IsFinalized()); return elf_filename_; } std::string const& GetBitcodeFileName() const { - CHECK(IsFinalized()); return bitcode_filename_; } @@ -77,12 +75,10 @@ class CompilationUnit { bool Materialize(); - bool IsFinalized() const { + bool IsMaterialized() const { return (context_.get() == NULL); } - void Finalize(); - bool IsMaterializeThresholdReached() const { return (mem_usage_ > 300000000u); // (threshold: 300 MB) } diff --git a/src/compiler_llvm/compiler_llvm.cc b/src/compiler_llvm/compiler_llvm.cc index 146f577e95..345872e3ee 100644 --- a/src/compiler_llvm/compiler_llvm.cc +++ b/src/compiler_llvm/compiler_llvm.cc @@ -22,6 +22,7 @@ #include "jni_compiler.h" #include "method_compiler.h" #include "oat_compilation_unit.h" +#include "stl_util.h" #include "upcall_compiler.h" #include <llvm/LinkAllPasses.h> @@ -71,7 +72,7 @@ llvm::Module* makeLLVMModuleContents(llvm::Module* module); CompilerLLVM::CompilerLLVM(Compiler* compiler, InstructionSet insn_set) : compiler_(compiler), compiler_lock_("llvm_compiler_lock"), - insn_set_(insn_set), cunit_counter_(0) { + insn_set_(insn_set), curr_cunit_(NULL) { // Initialize LLVM libraries pthread_once(&llvm_initialized, InitializeLLVM); @@ -79,104 +80,105 @@ CompilerLLVM::CompilerLLVM(Compiler* compiler, InstructionSet insn_set) CompilerLLVM::~CompilerLLVM() { - DCHECK(cunit_.get() == NULL); + STLDeleteElements(&cunits_); } -void CompilerLLVM::EnsureCompilationUnit() { - MutexLock GUARD(compiler_lock_); +void CompilerLLVM::EnsureCompilationUnit(MutexLock& GUARD) { DCHECK_NE(llvm_initialized, PTHREAD_ONCE_INIT); - if (cunit_.get() == NULL) { - cunit_.reset(new CompilationUnit(insn_set_)); + + if (curr_cunit_ != NULL) { + return; } -} + // Allocate compilation unit + size_t cunit_idx = cunits_.size(); + + curr_cunit_ = new CompilationUnit(insn_set_); + + // Setup output filename + curr_cunit_->SetElfFileName( + StringPrintf("%s-%zu", elf_filename_.c_str(), cunit_idx)); -void CompilerLLVM::MaterializeEveryCompilationUnit() { - if (cunit_.get() != NULL) { - MaterializeCompilationUnit(); + if (IsBitcodeFileNameAvailable()) { + curr_cunit_->SetBitcodeFileName( + StringPrintf("%s-%zu", bitcode_filename_.c_str(), cunit_idx)); } + + // Register compilation unit + cunits_.push_back(curr_cunit_); } -void CompilerLLVM::MaterializeCompilationUnitSafePoint() { - if (cunit_->IsMaterializeThresholdReached()) { - MaterializeCompilationUnit(); +void CompilerLLVM::MaterializeRemainder() { + MutexLock GUARD(compiler_lock_); + if (curr_cunit_ != NULL) { + Materialize(GUARD); } } -void CompilerLLVM::MaterializeCompilationUnit() { +void CompilerLLVM::MaterializeIfThresholdReached() { MutexLock GUARD(compiler_lock_); + if (curr_cunit_ != NULL && curr_cunit_->IsMaterializeThresholdReached()) { + Materialize(GUARD); + } +} - cunit_->SetElfFileName(StringPrintf("%s-%u", elf_filename_.c_str(), - cunit_counter_)); - // Write the translated bitcode for debugging - if (!bitcode_filename_.empty()) { - cunit_->SetBitcodeFileName(StringPrintf("%s-%u", bitcode_filename_.c_str(), - cunit_counter_)); - cunit_->WriteBitcodeToFile(); +void CompilerLLVM::Materialize(MutexLock& GUARD) { + DCHECK(curr_cunit_ != NULL); + DCHECK(!curr_cunit_->IsMaterialized()); + + // Write bitcode to file when filename is set + if (IsBitcodeFileNameAvailable()) { + curr_cunit_->WriteBitcodeToFile(); } // Materialize the llvm::Module into ELF object file - cunit_->Materialize(); - - // Increase compilation unit counter - ++cunit_counter_; + curr_cunit_->Materialize(); // Delete the compilation unit - cunit_.reset(NULL); + curr_cunit_ = NULL; } -CompiledMethod* CompilerLLVM::CompileDexMethod(OatCompilationUnit* oat_compilation_unit) { +CompiledMethod* CompilerLLVM:: +CompileDexMethod(OatCompilationUnit* oat_compilation_unit) { MutexLock GUARD(compiler_lock_); - EnsureCompilationUnit(); + EnsureCompilationUnit(GUARD); UniquePtr<MethodCompiler> method_compiler( - new MethodCompiler(cunit_.get(), compiler_, oat_compilation_unit)); - - CompiledMethod* result = method_compiler->Compile(); + new MethodCompiler(curr_cunit_, compiler_, oat_compilation_unit)); - MaterializeCompilationUnitSafePoint(); - - return result; + return method_compiler->Compile(); } -CompiledMethod* CompilerLLVM::CompileNativeMethod(OatCompilationUnit* oat_compilation_unit) { +CompiledMethod* CompilerLLVM:: +CompileNativeMethod(OatCompilationUnit* oat_compilation_unit) { MutexLock GUARD(compiler_lock_); - EnsureCompilationUnit(); + EnsureCompilationUnit(GUARD); UniquePtr<JniCompiler> jni_compiler( - new JniCompiler(cunit_.get(), *compiler_, oat_compilation_unit)); - - CompiledMethod* result = jni_compiler->Compile(); + new JniCompiler(curr_cunit_, *compiler_, oat_compilation_unit)); - MaterializeCompilationUnitSafePoint(); - - return result; + return jni_compiler->Compile(); } CompiledInvokeStub* CompilerLLVM::CreateInvokeStub(bool is_static, char const *shorty) { - MutexLock GUARD(compiler_lock_); - EnsureCompilationUnit(); + EnsureCompilationUnit(GUARD); UniquePtr<UpcallCompiler> upcall_compiler( - new UpcallCompiler(cunit_.get(), *compiler_)); - - CompiledInvokeStub* result = upcall_compiler->CreateStub(is_static, shorty); - - MaterializeCompilationUnitSafePoint(); + new UpcallCompiler(curr_cunit_, *compiler_)); - return result; + return upcall_compiler->CreateStub(is_static, shorty); } diff --git a/src/compiler_llvm/compiler_llvm.h b/src/compiler_llvm/compiler_llvm.h index 208edfcd22..3c653a3669 100644 --- a/src/compiler_llvm/compiler_llvm.h +++ b/src/compiler_llvm/compiler_llvm.h @@ -56,7 +56,9 @@ class CompilerLLVM { ~CompilerLLVM(); - void MaterializeEveryCompilationUnit(); + void MaterializeIfThresholdReached(); + + void MaterializeRemainder(); Compiler* GetCompiler() const { return compiler_; @@ -81,21 +83,25 @@ class CompilerLLVM { CompiledInvokeStub* CreateInvokeStub(bool is_static, char const *shorty); private: - void EnsureCompilationUnit(); + void EnsureCompilationUnit(MutexLock& GUARD); - void MaterializeCompilationUnit(); + void Materialize(MutexLock& GUARD); - void MaterializeCompilationUnitSafePoint(); + bool IsBitcodeFileNameAvailable() const { + return !bitcode_filename_.empty(); + } Compiler* compiler_; + public: Mutex compiler_lock_; + private: InstructionSet insn_set_; - UniquePtr<CompilationUnit> cunit_; + CompilationUnit* curr_cunit_; - unsigned cunit_counter_; + std::vector<CompilationUnit*> cunits_; std::string elf_filename_; |