Compile method one-by-one.

Change-Id: Ic56fb397f3bd6dee32372eb875261a3383eaf30c
diff --git a/src/compiler_llvm/compiler_llvm.cc b/src/compiler_llvm/compiler_llvm.cc
index 6c8188e..b793fbd 100644
--- a/src/compiler_llvm/compiler_llvm.cc
+++ b/src/compiler_llvm/compiler_llvm.cc
@@ -22,8 +22,6 @@
 #include "compiled_method.h"
 #include "compiler.h"
 #include "dex_cache.h"
-#include "elf_image.h"
-#include "elf_loader.h"
 #include "ir_builder.h"
 #include "jni_compiler.h"
 #include "method_compiler.h"
@@ -95,9 +93,9 @@
 
 
 CompilerLLVM::CompilerLLVM(Compiler* compiler, InstructionSet insn_set)
-    : compiler_(compiler), compiler_lock_("llvm_compiler_lock"),
-      insn_set_(insn_set), curr_cunit_(NULL) {
-
+    : compiler_(compiler), insn_set_(insn_set),
+      num_cunits_lock_("compilation unit counter lock"), num_cunits_(0),
+      plt_(insn_set) {
 
   // Initialize LLVM libraries
   pthread_once(&llvm_initialized, InitializeLLVM);
@@ -105,152 +103,21 @@
 
 
 CompilerLLVM::~CompilerLLVM() {
-  STLDeleteElements(&cunits_);
 }
 
 
-void CompilerLLVM::EnsureCompilationUnit() {
-  compiler_lock_.AssertHeld();
-
-  if (curr_cunit_ != NULL) {
-    return;
-  }
-
-  // Allocate compilation unit
-  size_t cunit_idx = cunits_.size();
-  curr_cunit_ = new CompilationUnit(insn_set_, cunit_idx);
-
-  // Register compilation unit
-  cunits_.push_back(curr_cunit_);
-}
-
-
-void CompilerLLVM::MaterializeRemainder() {
-  compiler_lock_.Lock();
-  // Localize
-  CompilationUnit* cunit = curr_cunit_;
-  // Reset the curr_cuit_
-  curr_cunit_ = NULL;
-  compiler_lock_.Unlock();
-
-  if (cunit != NULL) {
-    Materialize(cunit);
-  }
-}
-
-
-void CompilerLLVM::MaterializeIfThresholdReached() {
-  compiler_lock_.Lock();
-  // Localize
-  CompilationUnit* cunit = curr_cunit_;
-
-  if (curr_cunit_ != NULL && curr_cunit_->IsMaterializeThresholdReached()) {
-    // Delete the compilation unit
-    curr_cunit_ = NULL;
-  } else {
-    // Reset cunit such that Materialize() won't be invoked
-    cunit = NULL;
-  }
-
-  compiler_lock_.Unlock();
-
-  if (cunit != NULL) {
-    Materialize(cunit);
-  }
-}
-
-
-void CompilerLLVM::Materialize(CompilationUnit* cunit) {
-  DCHECK(cunit != NULL);
-  DCHECK(!cunit->IsMaterialized());
-
-  // Write bitcode to file when filename is set
-  if (IsBitcodeFileNameAvailable()) {
-    const size_t cunit_idx = cunits_.size();
-    cunit->SetBitcodeFileName(
-      StringPrintf("%s-%zu", bitcode_filename_.c_str(), cunit_idx));
-  }
-
-  // Materialize the llvm::Module into ELF object file
-  cunit->Materialize(compiler_->GetThreadCount());
-
-  // Load ELF image when automatic ELF loading is enabled
-  if (IsAutoElfLoadingEnabled()) {
-    LoadElfFromCompilationUnit(cunit);
-  }
-}
-
-
-void CompilerLLVM::EnableAutoElfLoading() {
-  MutexLock GUARD(compiler_lock_);
-
-  if (IsAutoElfLoadingEnabled()) {
-    // If there is an existing ELF loader, then do nothing.
-    // Because the existing ELF loader may have returned some code address
-    // already.  If we replace the existing ELF loader with
-    // elf_loader_.reset(...), then it is possible to have some dangling
-    // pointer.
-    return;
-  }
-
-  // Create ELF loader and load the materialized CompilationUnit
-  elf_loader_.reset(new ElfLoader());
-
-  for (size_t i = 0; i < cunits_.size(); ++i) {
-    if (cunits_[i]->IsMaterialized()) {
-      LoadElfFromCompilationUnit(cunits_[i]);
-    }
-  }
-}
-
-
-void CompilerLLVM::LoadElfFromCompilationUnit(const CompilationUnit* cunit) {
-  MutexLock GUARD(compiler_lock_);
-  DCHECK(cunit->IsMaterialized()) << cunit->GetElfIndex();
-
-  if (!elf_loader_->LoadElfAt(cunit->GetElfIndex(),
-                              cunit->GetElfImage(),
-                              OatFile::kRelocAll)) {
-    LOG(ERROR) << "Failed to load ELF from compilation unit "
-               << cunit->GetElfIndex();
-  }
-}
-
-
-const void* CompilerLLVM::GetMethodCodeAddr(const CompiledMethod* cm) const {
-  return elf_loader_->GetMethodCodeAddr(cm->GetElfIndex(),
-                                        cm->GetElfFuncIndex());
-}
-
-
-const Method::InvokeStub* CompilerLLVM::
-GetMethodInvokeStubAddr(const CompiledInvokeStub* cm) const {
-  return elf_loader_->GetMethodInvokeStubAddr(cm->GetElfIndex(),
-                                              cm->GetElfFuncIndex());
-}
-
-
-std::vector<ElfImage> CompilerLLVM::GetElfImages() const {
-  std::vector<ElfImage> result;
-
-  for (size_t i = 0; i < cunits_.size(); ++i) {
-    result.push_back(cunits_[i]->GetElfImage());
-  }
-
-  return result;
+CompilationUnit* CompilerLLVM::AllocateCompilationUnit() {
+  MutexLock GUARD(num_cunits_lock_);
+  return new CompilationUnit(this, num_cunits_++);
 }
 
 
 CompiledMethod* CompilerLLVM::
 CompileDexMethod(OatCompilationUnit* oat_compilation_unit) {
-  MutexLock GUARD(compiler_lock_);
-
-  EnsureCompilationUnit();
-
-  MutexLock GUARD_CUNIT(curr_cunit_->cunit_lock_);
+  UniquePtr<CompilationUnit> cunit(AllocateCompilationUnit());
 
   UniquePtr<MethodCompiler> method_compiler(
-      new MethodCompiler(curr_cunit_, compiler_, oat_compilation_unit));
+      new MethodCompiler(cunit.get(), compiler_, oat_compilation_unit));
 
   return method_compiler->Compile();
 }
@@ -258,14 +125,10 @@
 
 CompiledMethod* CompilerLLVM::
 CompileNativeMethod(OatCompilationUnit* oat_compilation_unit) {
-  MutexLock GUARD(compiler_lock_);
-
-  EnsureCompilationUnit();
-
-  MutexLock GUARD_CUNIT(curr_cunit_->cunit_lock_);
+  UniquePtr<CompilationUnit> cunit(AllocateCompilationUnit());
 
   UniquePtr<JniCompiler> jni_compiler(
-      new JniCompiler(curr_cunit_, *compiler_, oat_compilation_unit));
+      new JniCompiler(cunit.get(), *compiler_, oat_compilation_unit));
 
   return jni_compiler->Compile();
 }
@@ -273,28 +136,20 @@
 
 CompiledInvokeStub* CompilerLLVM::CreateInvokeStub(bool is_static,
                                                    char const *shorty) {
-  MutexLock GUARD(compiler_lock_);
-
-  EnsureCompilationUnit();
-
-  MutexLock GUARD_CUNIT(curr_cunit_->cunit_lock_);
+  UniquePtr<CompilationUnit> cunit(AllocateCompilationUnit());
 
   UniquePtr<StubCompiler> stub_compiler(
-    new StubCompiler(curr_cunit_, *compiler_));
+    new StubCompiler(cunit.get(), *compiler_));
 
   return stub_compiler->CreateInvokeStub(is_static, shorty);
 }
 
 
 CompiledInvokeStub* CompilerLLVM::CreateProxyStub(char const *shorty) {
-  MutexLock GUARD(compiler_lock_);
-
-  EnsureCompilationUnit();
-
-  MutexLock GUARD_CUNIT(curr_cunit_->cunit_lock_);
+  UniquePtr<CompilationUnit> cunit(AllocateCompilationUnit());
 
   UniquePtr<StubCompiler> stub_compiler(
-    new StubCompiler(curr_cunit_, *compiler_));
+    new StubCompiler(cunit.get(), *compiler_));
 
   return stub_compiler->CreateProxyStub(shorty);
 }
@@ -324,6 +179,11 @@
   compiler.SetCompilerContext(compiler_llvm);
 }
 
+extern "C" void ArtUnInitCompilerContext(art::Compiler& compiler) {
+  delete ContextOf(compiler);
+  compiler.SetCompilerContext(NULL);
+}
+
 extern "C" art::CompiledMethod* ArtCompileMethod(art::Compiler& compiler,
                                                  const art::DexFile::CodeItem* code_item,
                                                  uint32_t access_flags, uint32_t method_idx,
@@ -338,7 +198,6 @@
     method_idx, access_flags);
   art::compiler_llvm::CompilerLLVM* compiler_llvm = ContextOf(compiler);
   art::CompiledMethod* result = compiler_llvm->CompileDexMethod(&oat_compilation_unit);
-  compiler_llvm->MaterializeIfThresholdReached();
   return result;
 }
 
@@ -354,7 +213,6 @@
 
   art::compiler_llvm::CompilerLLVM* compiler_llvm = ContextOf(compiler);
   art::CompiledMethod* result = compiler_llvm->CompileNativeMethod(&oat_compilation_unit);
-  compiler_llvm->MaterializeIfThresholdReached();
   return result;
 }
 
@@ -364,7 +222,6 @@
                                                         uint32_t shorty_len) {
   art::compiler_llvm::CompilerLLVM* compiler_llvm = ContextOf(compiler);
   art::CompiledInvokeStub* result = compiler_llvm->CreateInvokeStub(is_static, shorty);
-  compiler_llvm->MaterializeIfThresholdReached();
   return result;
 }
 
@@ -373,7 +230,6 @@
                                                        uint32_t shorty_len) {
   art::compiler_llvm::CompilerLLVM* compiler_llvm = ContextOf(compiler);
   art::CompiledInvokeStub* result = compiler_llvm->CreateProxyStub(shorty);
-  compiler_llvm->MaterializeIfThresholdReached();
   return result;
 }
 
@@ -381,37 +237,3 @@
                                                std::string const& filename) {
   ContextOf(compiler)->SetBitcodeFileName(filename);
 }
-
-extern "C" void compilerLLVMMaterializeRemainder(art::Compiler& compiler) {
-  ContextOf(compiler)->MaterializeRemainder();
-}
-
-extern "C" void compilerLLVMEnableAutoElfLoading(art::Compiler& compiler) {
-  art::compiler_llvm::CompilerLLVM* compiler_llvm =
-      reinterpret_cast<art::compiler_llvm::CompilerLLVM*>(compiler.GetCompilerContext());
-  return compiler_llvm->EnableAutoElfLoading();
-}
-
-extern "C" const void* compilerLLVMGetMethodCodeAddr(const art::Compiler& compiler,
-                                                     const art::CompiledMethod* cm,
-                                                     const art::Method*) {
-  const art::compiler_llvm::CompilerLLVM* compiler_llvm =
-      reinterpret_cast<const art::compiler_llvm::CompilerLLVM*>(compiler.GetCompilerContext());
-  return compiler_llvm->GetMethodCodeAddr(cm);
-}
-
-extern "C" const art::Method::InvokeStub* compilerLLVMGetMethodInvokeStubAddr(const art::Compiler& compiler,
-                                                                              const art::CompiledInvokeStub* cm,
-                                                                              const art::Method*) {
-  const art::compiler_llvm::CompilerLLVM* compiler_llvm =
-      reinterpret_cast<const art::compiler_llvm::CompilerLLVM*>(compiler.GetCompilerContext());
-  return compiler_llvm->GetMethodInvokeStubAddr(cm);
-}
-
-extern "C" std::vector<art::ElfImage> compilerLLVMGetElfImages(const art::Compiler& compiler) {
-  return ContextOf(compiler)->GetElfImages();
-}
-
-extern "C" void compilerLLVMDispose(art::Compiler& compiler) {
-  delete ContextOf(compiler);
-}