Use ELF function index to distinguish generated functions.

We replaced LLVMLongName and LLVMStubName with ElfFuncName,
and we are using the simple name: Art0, Art1, ..., ArtN,
as the function name of every generated functions.  This
gives us 3 benefits:

1. We can avoid the ambiguous function name returned by
   LLVMLongName() in some special situation.

2. We don't need to have the art::Method object during
   the executable linking procedure.  Besides, this will
   make bootstrapping easier.

3. Reduce the size of the ELF executable, since we don't
   have to save a long function name, which usually contains
   more than 30 characters.

Change-Id: Ib698062b272458e847ad5545d7acf33a4dc9eb85
diff --git a/build/Android.common.mk b/build/Android.common.mk
index b2a983e..f70a1ca 100644
--- a/build/Android.common.mk
+++ b/build/Android.common.mk
@@ -189,8 +189,7 @@
 LIBART_COMMON_SRC_FILES += \
 	src/compiler_llvm/elf_loader.cc \
 	src/compiler_llvm/inferred_reg_category_map.cc \
-	src/compiler_llvm/runtime_support_llvm.cc \
-	src/compiler_llvm/utils_llvm.cc
+	src/compiler_llvm/runtime_support_llvm.cc
 endif
 LIBART_COMMON_SRC_FILES += \
 	src/oat/runtime/arm/stub_arm.cc \
@@ -306,11 +305,6 @@
 	src/utils_test.cc \
 	src/zip_archive_test.cc
 
-ifeq ($(ART_USE_LLVM_COMPILER),true)
-TEST_COMMON_SRC_FILES += \
-	src/compiler_llvm/utils_llvm_test.cc
-endif
-
 TEST_TARGET_SRC_FILES := \
 	$(TEST_COMMON_SRC_FILES)
 
diff --git a/build/Android.libart-compiler-llvm.mk b/build/Android.libart-compiler-llvm.mk
index a278517..31bbb3a 100644
--- a/build/Android.libart-compiler-llvm.mk
+++ b/build/Android.libart-compiler-llvm.mk
@@ -28,8 +28,7 @@
 	src/compiler_llvm/jni_compiler.cc \
 	src/compiler_llvm/method_compiler.cc \
 	src/compiler_llvm/runtime_support_llvm.cc \
-	src/compiler_llvm/upcall_compiler.cc \
-	src/compiler_llvm/utils_llvm.cc
+	src/compiler_llvm/upcall_compiler.cc
 
 # $(1): target or host
 # $(2): ndebug or debug
diff --git a/src/common_test.h b/src/common_test.h
index a323831..087168d 100644
--- a/src/common_test.h
+++ b/src/common_test.h
@@ -207,8 +207,10 @@
                                 reinterpret_cast<uint32_t>(invoke_stub)
 #if defined(ART_USE_LLVM_COMPILER)
                               , NULL,
-                                -1u,
-                                -1u
+                                static_cast<uint16_t>(-1u),
+                                static_cast<uint16_t>(-1u),
+                                static_cast<uint16_t>(-1u),
+                                static_cast<uint16_t>(-1u)
 #endif
                                 );
   }
diff --git a/src/compiled_method.cc b/src/compiled_method.cc
index e85809c..2340cbd 100644
--- a/src/compiled_method.cc
+++ b/src/compiled_method.cc
@@ -83,9 +83,12 @@
   CHECK_NE(code.size(), 0U);
 }
 
-CompiledMethod::CompiledMethod(InstructionSet instruction_set, size_t elf_idx)
+CompiledMethod::CompiledMethod(InstructionSet instruction_set,
+                               const uint16_t elf_idx,
+                               const uint16_t elf_func_idx)
     : instruction_set_(instruction_set), frame_size_in_bytes_(0),
-      core_spill_mask_(0), fp_spill_mask_(0), elf_idx_(elf_idx) {
+      core_spill_mask_(0), fp_spill_mask_(0), elf_idx_(elf_idx),
+      elf_func_idx_(elf_func_idx) {
 }
 
 CompiledMethod::~CompiledMethod() {}
@@ -173,7 +176,8 @@
 }
 
 #if defined(ART_USE_LLVM_COMPILER)
-CompiledInvokeStub::CompiledInvokeStub(size_t elf_idx) : elf_idx_(elf_idx) {
+CompiledInvokeStub::CompiledInvokeStub(uint16_t elf_idx, uint16_t elf_func_idx)
+    : elf_idx_(elf_idx), elf_func_idx_(elf_func_idx) {
 }
 #endif
 
diff --git a/src/compiled_method.h b/src/compiled_method.h
index b98df39..2920256 100644
--- a/src/compiled_method.h
+++ b/src/compiled_method.h
@@ -50,7 +50,9 @@
                  const uint32_t fp_spill_mask);
 
   // Constructs a CompiledMethod for the LLVM compiler.
-  CompiledMethod(InstructionSet instruction_set, size_t elf_idx);
+  CompiledMethod(InstructionSet instruction_set,
+                 const uint16_t elf_idx,
+                 const uint16_t elf_func_idx);
 
   ~CompiledMethod();
 
@@ -79,12 +81,18 @@
   static const void* CodePointer(const void* code_pointer,
                                  InstructionSet instruction_set);
 
-  size_t GetElfIndex() const {
+  uint16_t GetElfIndex() const {
+    DCHECK(IsExecutableInElf());
     return elf_idx_;
   }
 
+  uint16_t GetElfFuncIndex() const {
+    DCHECK(IsExecutableInElf());
+    return elf_func_idx_;
+  }
+
   bool IsExecutableInElf() const {
-    return (elf_idx_ != static_cast<size_t>(-1));
+    return (elf_idx_ != static_cast<uint16_t>(-1u));
   }
 
  private:
@@ -98,30 +106,38 @@
   std::vector<uint16_t> vmap_table_;
   std::vector<uint8_t> gc_map_;
   // For LLVM
-  size_t elf_idx_;
+  uint16_t elf_idx_;
+  uint16_t elf_func_idx_;
 };
 
 class CompiledInvokeStub {
  public:
   explicit CompiledInvokeStub(std::vector<uint8_t>& code);
 #if defined(ART_USE_LLVM_COMPILER)
-  explicit CompiledInvokeStub(size_t elf_idx);
+  explicit CompiledInvokeStub(uint16_t elf_idx, uint16_t elf_func_idx);
 #endif
   ~CompiledInvokeStub();
 
   const std::vector<uint8_t>& GetCode() const;
 
-  size_t GetElfIndex() const {
+  uint16_t GetElfIndex() const {
+    DCHECK(IsExecutableInElf());
     return elf_idx_;
   }
 
+  uint16_t GetElfFuncIndex() const {
+    DCHECK(IsExecutableInElf());
+    return elf_func_idx_;
+  }
+
   bool IsExecutableInElf() const {
-    return (elf_idx_ != static_cast<size_t>(-1));
+    return (elf_idx_ != static_cast<uint16_t>(-1u));
   }
 
  private:
   std::vector<uint8_t> code_;
-  size_t elf_idx_;
+  uint16_t elf_idx_;
+  uint16_t elf_func_idx_;
 };
 
 }  // namespace art
diff --git a/src/compiler_llvm/compilation_unit.cc b/src/compiler_llvm/compilation_unit.cc
index c5952f0..b3a9c71 100644
--- a/src/compiler_llvm/compilation_unit.cc
+++ b/src/compiler_llvm/compilation_unit.cc
@@ -62,7 +62,7 @@
 
 CompilationUnit::CompilationUnit(InstructionSet insn_set, size_t elf_idx)
 : insn_set_(insn_set), elf_idx_(elf_idx), context_(new llvm::LLVMContext()),
-  mem_usage_(0) {
+  mem_usage_(0), num_elf_funcs_(0) {
 
   // Create the module and include the runtime function declaration
   module_ = new llvm::Module("art", *context_);
diff --git a/src/compiler_llvm/compilation_unit.h b/src/compiler_llvm/compilation_unit.h
index eb92ce4..1db54fc 100644
--- a/src/compiler_llvm/compilation_unit.h
+++ b/src/compiler_llvm/compilation_unit.h
@@ -73,6 +73,11 @@
     return ElfImage(elf_image_);
   }
 
+  uint16_t AcquireUniqueElfFuncIndex() {
+    CHECK(num_elf_funcs_ < UINT16_MAX);
+    return num_elf_funcs_++;
+  }
+
   bool WriteBitcodeToFile();
 
   bool Materialize();
@@ -101,6 +106,7 @@
   std::string bitcode_filename_;
 
   size_t mem_usage_;
+  uint16_t num_elf_funcs_;
 };
 
 } // namespace compiler_llvm
diff --git a/src/compiler_llvm/compiler_llvm.cc b/src/compiler_llvm/compiler_llvm.cc
index 2b18903..f9af139 100644
--- a/src/compiler_llvm/compiler_llvm.cc
+++ b/src/compiler_llvm/compiler_llvm.cc
@@ -213,15 +213,16 @@
 }
 
 
-const void* CompilerLLVM::GetMethodCodeAddr(const CompiledMethod* cm,
-                                            const Method* method) const {
-  return elf_loader_->GetMethodCodeAddr(cm->GetElfIndex(), method);
+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 Method* method) const {
-  return elf_loader_->GetMethodInvokeStubAddr(cm->GetElfIndex(), method);
+GetMethodInvokeStubAddr(const CompiledInvokeStub* cm) const {
+  return elf_loader_->GetMethodInvokeStubAddr(cm->GetElfIndex(),
+                                              cm->GetElfFuncIndex());
 }
 
 
@@ -353,18 +354,18 @@
 
 extern "C" const void* compilerLLVMGetMethodCodeAddr(const art::Compiler& compiler,
                                                      const art::CompiledMethod* cm,
-                                                     const art::Method* method) {
+                                                     const art::Method*) {
   const art::compiler_llvm::CompilerLLVM* compiler_llvm =
       reinterpret_cast<const art::compiler_llvm::CompilerLLVM*>(compiler.GetCompilerContext());
-  return compiler_llvm->GetMethodCodeAddr(cm, method);
+  return compiler_llvm->GetMethodCodeAddr(cm);
 }
 
 extern "C" const art::Method::InvokeStub* compilerLLVMGetMethodInvokeStubAddr(const art::Compiler& compiler,
                                                                               const art::CompiledInvokeStub* cm,
-                                                                              const art::Method* method) {
+                                                                              const art::Method*) {
   const art::compiler_llvm::CompilerLLVM* compiler_llvm =
       reinterpret_cast<const art::compiler_llvm::CompilerLLVM*>(compiler.GetCompilerContext());
-  return compiler_llvm->GetMethodInvokeStubAddr(cm, method);
+  return compiler_llvm->GetMethodInvokeStubAddr(cm);
 }
 
 extern "C" std::vector<art::ElfImage> compilerLLVMGetElfImages(const art::Compiler& compiler) {
diff --git a/src/compiler_llvm/compiler_llvm.h b/src/compiler_llvm/compiler_llvm.h
index b9f8d00..8bb053e 100644
--- a/src/compiler_llvm/compiler_llvm.h
+++ b/src/compiler_llvm/compiler_llvm.h
@@ -93,12 +93,10 @@
     return (elf_loader_.get() != NULL);
   }
 
-  const void* GetMethodCodeAddr(const CompiledMethod* cm,
-                                const Method* method) const;
+  const void* GetMethodCodeAddr(const CompiledMethod* cm) const;
 
   const Method::InvokeStub* GetMethodInvokeStubAddr(
-                                const CompiledInvokeStub* cm,
-                                const Method* method) const;
+                                const CompiledInvokeStub* cm) const;
 
   std::vector<ElfImage> GetElfImages() const;
 
diff --git a/src/compiler_llvm/elf_loader.cc b/src/compiler_llvm/elf_loader.cc
index adea85d..8f8eff9 100644
--- a/src/compiler_llvm/elf_loader.cc
+++ b/src/compiler_llvm/elf_loader.cc
@@ -84,20 +84,18 @@
 }
 
 
-const void* ElfLoader::GetMethodCodeAddr(size_t elf_idx,
-                                         const Method* method) const {
+const void* ElfLoader::GetMethodCodeAddr(uint16_t elf_idx,
+                                         uint16_t elf_func_idx) const {
   CHECK_LT(elf_idx, executables_.size());
-  CHECK(method != NULL);
-  return GetAddr(elf_idx, LLVMLongName(method).c_str());
+  return GetAddr(elf_idx, ElfFuncName(elf_func_idx).c_str());
 }
 
 
 const Method::InvokeStub* ElfLoader::
-GetMethodInvokeStubAddr(size_t elf_idx, const Method* method) const {
+GetMethodInvokeStubAddr(uint16_t elf_idx, uint16_t elf_func_idx) const {
   CHECK_LT(elf_idx, executables_.size());
-  CHECK(method != NULL);
   return reinterpret_cast<const Method::InvokeStub*>(
-      GetAddr(elf_idx, LLVMStubName(method).c_str()));
+      GetAddr(elf_idx, ElfFuncName(elf_func_idx).c_str()));
 }
 
 
diff --git a/src/compiler_llvm/elf_loader.h b/src/compiler_llvm/elf_loader.h
index 9e8137f..ea98f61 100644
--- a/src/compiler_llvm/elf_loader.h
+++ b/src/compiler_llvm/elf_loader.h
@@ -26,10 +26,6 @@
 #include <vector>
 
 namespace art {
-  class Method;
-}
-
-namespace art {
 namespace compiler_llvm {
 
 class ElfLoader {
@@ -41,10 +37,11 @@
 
   void RelocateExecutable();
 
-  const void* GetMethodCodeAddr(size_t elf_idx, const Method* method) const;
+  const void* GetMethodCodeAddr(uint16_t elf_idx,
+                                uint16_t elf_func_idx) const;
 
-  const Method::InvokeStub* GetMethodInvokeStubAddr(size_t elf_idx,
-                                                    const Method* method) const;
+  const Method::InvokeStub* GetMethodInvokeStubAddr(uint16_t elf_idx,
+                                                    uint16_t elf_func_idx) const;
 
  private:
   const void* GetAddr(size_t elf_idx, const char* sym_name) const;
diff --git a/src/compiler_llvm/jni_compiler.cc b/src/compiler_llvm/jni_compiler.cc
index 097c4f1..285caab 100644
--- a/src/compiler_llvm/jni_compiler.cc
+++ b/src/compiler_llvm/jni_compiler.cc
@@ -52,7 +52,8 @@
   class_loader_(oat_compilation_unit->class_loader_),
   dex_cache_(oat_compilation_unit->dex_cache_),
   dex_file_(oat_compilation_unit->dex_file_),
-  method_(dex_cache_->GetResolvedMethod(method_idx_)) {
+  method_(dex_cache_->GetResolvedMethod(method_idx_)),
+  elf_func_idx_(cunit_->AcquireUniqueElfFuncIndex()) {
 
   // Check: Ensure that the method is resolved
   CHECK_NE(method_, static_cast<art::Method*>(NULL));
@@ -289,13 +290,14 @@
   llvm::verifyFunction(*func_, llvm::PrintMessageAction);
 
   return new CompiledMethod(cunit_->GetInstructionSet(),
-                            cunit_->GetElfIndex());
+                            cunit_->GetElfIndex(),
+                            elf_func_idx_);
 }
 
 
 void JniCompiler::CreateFunction() {
   // LLVM function name
-  std::string func_name(LLVMLongName(method_));
+  std::string func_name(ElfFuncName(elf_func_idx_));
 
   // Get function type
   llvm::FunctionType* func_type =
diff --git a/src/compiler_llvm/jni_compiler.h b/src/compiler_llvm/jni_compiler.h
index c15dae5..d91293d 100644
--- a/src/compiler_llvm/jni_compiler.h
+++ b/src/compiler_llvm/jni_compiler.h
@@ -84,6 +84,7 @@
   Method* method_;
 
   llvm::Function* func_;
+  uint16_t elf_func_idx_;
 };
 
 
diff --git a/src/compiler_llvm/method_compiler.cc b/src/compiler_llvm/method_compiler.cc
index 8b1cef6..57dbf15 100644
--- a/src/compiler_llvm/method_compiler.cc
+++ b/src/compiler_llvm/method_compiler.cc
@@ -67,7 +67,7 @@
     basic_blocks_(code_item_->insns_size_in_code_units_),
     basic_block_landing_pads_(code_item_->tries_size_, NULL),
     basic_block_unwind_(NULL), basic_block_unreachable_(NULL),
-    shadow_frame_(NULL) {
+    shadow_frame_(NULL), elf_func_idx_(cunit_->AcquireUniqueElfFuncIndex()) {
 }
 
 
@@ -78,7 +78,7 @@
 
 void MethodCompiler::CreateFunction() {
   // LLVM function name
-  std::string func_name(LLVMLongName(method_));
+  std::string func_name(ElfFuncName(elf_func_idx_));
 
   // Get function type
   llvm::FunctionType* func_type =
@@ -3773,7 +3773,8 @@
   // Thus, we got our magic number 9.
 
   return new CompiledMethod(cunit_->GetInstructionSet(),
-                            cunit_->GetElfIndex());
+                            cunit_->GetElfIndex(),
+                            elf_func_idx_);
 }
 
 
diff --git a/src/compiler_llvm/method_compiler.h b/src/compiler_llvm/method_compiler.h
index 006f763..1ff3a9f 100644
--- a/src/compiler_llvm/method_compiler.h
+++ b/src/compiler_llvm/method_compiler.h
@@ -460,6 +460,8 @@
   llvm::BasicBlock* basic_block_unreachable_;
 
   llvm::AllocaInst* shadow_frame_;
+
+  uint16_t elf_func_idx_;
 };
 
 
diff --git a/src/compiler_llvm/upcall_compiler.cc b/src/compiler_llvm/upcall_compiler.cc
index 20bd94b..85bfe24 100644
--- a/src/compiler_llvm/upcall_compiler.cc
+++ b/src/compiler_llvm/upcall_compiler.cc
@@ -24,6 +24,7 @@
 #include "logging.h"
 #include "object.h"
 #include "runtime_support_func.h"
+#include "utils_llvm.h"
 
 #include <llvm/Analysis/Verifier.h>
 #include <llvm/BasicBlock.h>
@@ -42,7 +43,8 @@
 
 UpcallCompiler::UpcallCompiler(CompilationUnit* cunit, Compiler& compiler)
 : cunit_(cunit), compiler_(&compiler), module_(cunit_->GetModule()),
-  context_(cunit_->GetLLVMContext()), irb_(*cunit_->GetIRBuilder()) {
+  context_(cunit_->GetLLVMContext()), irb_(*cunit_->GetIRBuilder()),
+  elf_func_idx_(cunit_->AcquireUniqueElfFuncIndex()) {
 }
 
 
@@ -53,13 +55,7 @@
   size_t shorty_size = strlen(shorty);
 
   // Function name
-  std::string func_name;
-
-  if (is_static) {
-    StringAppendF(&func_name, "ArtSUpcall_%s", shorty);
-  } else {
-    StringAppendF(&func_name, "ArtUpcall_%s", shorty);
-  }
+  std::string func_name(ElfFuncName(elf_func_idx_));
 
   // Get argument types
   llvm::Type* arg_types[] = {
@@ -179,7 +175,7 @@
   // store ret_addr, and ret_void.  Beside, we guess that we have to use
   // 50 bytes to represent one LLVM instruction.
 
-  return new CompiledInvokeStub(cunit_->GetElfIndex());
+  return new CompiledInvokeStub(cunit_->GetElfIndex(), elf_func_idx_);
 }
 
 
diff --git a/src/compiler_llvm/upcall_compiler.h b/src/compiler_llvm/upcall_compiler.h
index 73d00a1..9cb49b0 100644
--- a/src/compiler_llvm/upcall_compiler.h
+++ b/src/compiler_llvm/upcall_compiler.h
@@ -48,6 +48,7 @@
   llvm::Module* module_;
   llvm::LLVMContext* context_;
   IRBuilder& irb_;
+  uint16_t elf_func_idx_;
 };
 
 
diff --git a/src/compiler_llvm/utils_llvm.cc b/src/compiler_llvm/utils_llvm.cc
deleted file mode 100644
index 2a9ccba..0000000
--- a/src/compiler_llvm/utils_llvm.cc
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "utils_llvm.h"
-
-#include <fcntl.h>
-#include <string.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include "android/librsloader.h"
-#include "class_loader.h"
-#include "object.h"
-#include "object_utils.h"
-#include "runtime_support_llvm.h"
-
-namespace art {
-
-std::string MangleForLLVM(const std::string& s) {
-  std::string result;
-  size_t char_count = CountModifiedUtf8Chars(s.c_str());
-  const char* cp = &s[0];
-  for (size_t i = 0; i < char_count; ++i) {
-    uint16_t ch = GetUtf16FromUtf8(&cp);
-    if (ch == '$' || ch == '<' || ch == '>' || ch > 127) {
-      StringAppendF(&result, "_0%04x", ch);
-    } else {
-      switch (ch) {
-      case '_':
-        result += "_1";
-        break;
-      case ';':
-        result += "_2";
-        break;
-      case '[':
-        result += "_3";
-        break;
-      case ')':
-        result += "_4";
-        break;
-      case '/':
-        result += "_";
-        break;
-      default:
-        result.push_back(ch);
-        break;
-      }
-    }
-  }
-  return result;
-}
-
-std::string LLVMShortName(const Method* m) {
-  MethodHelper mh(m);
-  std::string class_name(mh.GetDeclaringClassDescriptor());
-  // Remove the leading 'L' and trailing ';'...
-  CHECK_EQ(class_name[0], 'L') << class_name;
-  CHECK_EQ(class_name[class_name.size() - 1], ';') << class_name;
-  class_name.erase(0, 1);
-  class_name.erase(class_name.size() - 1, 1);
-
-  std::string method_name(mh.GetName());
-
-  std::string short_name;
-  short_name += "Art_";
-  short_name += MangleForLLVM(class_name);
-  short_name += "_";
-  short_name += MangleForLLVM(method_name);
-  return short_name;
-}
-
-std::string LLVMLongName(const Method* m) {
-  std::string long_name;
-  long_name += LLVMShortName(m);
-  long_name += "__";
-
-  std::string signature(MethodHelper(m).GetSignature());
-  signature.erase(0, 1);
-
-  long_name += MangleForLLVM(signature);
-
-  return long_name;
-}
-
-std::string LLVMStubName(const Method* m) {
-  MethodHelper mh(m);
-  std::string stub_name;
-  if (m->IsStatic()) {
-    stub_name += "ArtSUpcall_";
-  } else {
-    stub_name += "ArtUpcall_";
-  }
-  stub_name += mh.GetShorty();
-
-  return stub_name;
-}
-
-}  // namespace art
diff --git a/src/compiler_llvm/utils_llvm.h b/src/compiler_llvm/utils_llvm.h
index fb4da34..fb9f0cb 100644
--- a/src/compiler_llvm/utils_llvm.h
+++ b/src/compiler_llvm/utils_llvm.h
@@ -17,26 +17,17 @@
 #ifndef ART_SRC_UTILS_LLVM_H_
 #define ART_SRC_UTILS_LLVM_H_
 
-#include "object.h"
+#include "stringprintf.h"
 
+#include <stdint.h>
 #include <string>
 
 namespace art {
 
-// Performs LLVM name mangling (similar to MangleForJni with additional '<' and
-// '>' being mangled).
-std::string MangleForLLVM(const std::string& s);
+inline static std::string ElfFuncName(uint16_t elf_func_idx) {
+  return StringPrintf("Art%u", static_cast<unsigned int>(elf_func_idx));
+}
 
-// Returns the LLVM function name for the non-overloaded method 'm'.
-std::string LLVMShortName(const Method* m);
-
-// Returns the LLVM function name for the overloaded method 'm'.
-std::string LLVMLongName(const Method* m);
-
-// Returns the LLVM stub function name for the overloaded method 'm'.
-std::string LLVMStubName(const Method* m);
-
-void LLVMLinkLoadMethod(const std::string& file_name, Method* method);
 }  // namespace art
 
 #endif  // ART_SRC_UTILS_LLVM_H_
diff --git a/src/compiler_llvm/utils_llvm_test.cc b/src/compiler_llvm/utils_llvm_test.cc
deleted file mode 100644
index f5a2c0e..0000000
--- a/src/compiler_llvm/utils_llvm_test.cc
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "object.h"
-#include "common_test.h"
-#include "utils_llvm.h"
-
-namespace art {
-
-class UtilsLLVMTest : public CommonTest {
-};
-
-TEST_F(UtilsLLVMTest, MangleForLLVM) {
-  // Unit test inheritted from MangleForJni
-  EXPECT_EQ("hello_00024world", MangleForLLVM("hello$world"));
-  EXPECT_EQ("hello_000a9world", MangleForLLVM("hello\xc2\xa9world"));
-  EXPECT_EQ("hello_1world", MangleForLLVM("hello_world"));
-  EXPECT_EQ("Ljava_lang_String_2", MangleForLLVM("Ljava/lang/String;"));
-  EXPECT_EQ("_3C", MangleForLLVM("[C"));
-
-  // MangleForLLVM()-specific unit test
-  EXPECT_EQ("_0003cinit_0003e", MangleForLLVM("<init>"));
-  EXPECT_EQ("_0003cclinit_0003e", MangleForLLVM("<clinit>"));
-}
-
-TEST_F(UtilsLLVMTest, LLVMShortName_LLVMLongName) {
-  Class* c = class_linker_->FindSystemClass("Ljava/lang/String;");
-  ASSERT_TRUE(c != NULL);
-  Method* m;
-
-  // Unit test inheritted from MangleForJni
-  m = c->FindVirtualMethod("charAt", "(I)C");
-  ASSERT_TRUE(m != NULL);
-  EXPECT_EQ("Art_java_lang_String_charAt", LLVMShortName(m));
-  EXPECT_EQ("Art_java_lang_String_charAt__I", LLVMLongName(m));
-
-  m = c->FindVirtualMethod("indexOf", "(Ljava/lang/String;I)I");
-  ASSERT_TRUE(m != NULL);
-  EXPECT_EQ("Art_java_lang_String_indexOf", LLVMShortName(m));
-  EXPECT_EQ("Art_java_lang_String_indexOf__Ljava_lang_String_2I", LLVMLongName(m));
-
-  m = c->FindDirectMethod("copyValueOf", "([CII)Ljava/lang/String;");
-  ASSERT_TRUE(m != NULL);
-  EXPECT_EQ("Art_java_lang_String_copyValueOf", LLVMShortName(m));
-  EXPECT_EQ("Art_java_lang_String_copyValueOf___3CII", LLVMLongName(m));
-
-  // MangleForLLVM()-specific unit test
-  m = c->FindDirectMethod("<init>", "()V");
-  ASSERT_TRUE(m != NULL);
-  EXPECT_EQ("Art_java_lang_String__0003cinit_0003e", LLVMShortName(m));
-  EXPECT_EQ("Art_java_lang_String__0003cinit_0003e__", LLVMLongName(m));
-
-  m = c->FindDirectMethod("<init>", "([C)V");
-  ASSERT_TRUE(m != NULL);
-  EXPECT_EQ("Art_java_lang_String__0003cinit_0003e", LLVMShortName(m));
-  EXPECT_EQ("Art_java_lang_String__0003cinit_0003e___3C", LLVMLongName(m));
-
-  m = c->FindDirectMethod("<init>", "([CII)V");
-  ASSERT_TRUE(m != NULL);
-  EXPECT_EQ("Art_java_lang_String__0003cinit_0003e", LLVMShortName(m));
-  EXPECT_EQ("Art_java_lang_String__0003cinit_0003e___3CII", LLVMLongName(m));
-
-  m = c->FindDirectMethod("<init>", "(Ljava/lang/String;)V");
-  ASSERT_TRUE(m != NULL);
-  EXPECT_EQ("Art_java_lang_String__0003cinit_0003e", LLVMShortName(m));
-  EXPECT_EQ("Art_java_lang_String__0003cinit_0003e__Ljava_lang_String_2", LLVMLongName(m));
-}
-
-}  // namespace art
diff --git a/src/oat.cc b/src/oat.cc
index a7b57e6..bf05f71 100644
--- a/src/oat.cc
+++ b/src/oat.cc
@@ -157,8 +157,10 @@
     gc_map_offset_(0),
     invoke_stub_offset_(0)
 #if defined(ART_USE_LLVM_COMPILER)
-  , code_elf_idx_(-1u),
-    invoke_stub_elf_idx_(-1u)
+  , code_elf_idx_(static_cast<uint16_t>(-1u)),
+    code_elf_func_idx_(static_cast<uint16_t>(-1u)),
+    invoke_stub_elf_idx_(static_cast<uint16_t>(-1u)),
+    invoke_stub_elf_func_idx_(static_cast<uint16_t>(-1u))
 #endif
 {}
 
@@ -171,8 +173,10 @@
                                    uint32_t gc_map_offset,
                                    uint32_t invoke_stub_offset
 #if defined(ART_USE_LLVM_COMPILER)
-                                 , uint32_t code_elf_idx,
-                                   uint32_t invoke_stub_elf_idx
+                                 , uint16_t code_elf_idx,
+                                   uint16_t code_elf_func_idx,
+                                   uint16_t invoke_stub_elf_idx,
+                                   uint16_t invoke_stub_elf_func_idx
 #endif
                                    )
   : code_offset_(code_offset),
@@ -185,7 +189,9 @@
     invoke_stub_offset_(invoke_stub_offset)
 #if defined(ART_USE_LLVM_COMPILER)
   , code_elf_idx_(code_elf_idx),
-    invoke_stub_elf_idx_(invoke_stub_elf_idx)
+    code_elf_func_idx_(code_elf_func_idx),
+    invoke_stub_elf_idx_(invoke_stub_elf_idx),
+    invoke_stub_elf_func_idx_(invoke_stub_elf_func_idx)
 #endif
 {}
 
diff --git a/src/oat.h b/src/oat.h
index f07d3f7..4fadcc5 100644
--- a/src/oat.h
+++ b/src/oat.h
@@ -83,8 +83,10 @@
                    uint32_t gc_map_offset,
                    uint32_t invoke_stub_offset
 #if defined(ART_USE_LLVM_COMPILER)
-                 , uint32_t code_elf_idx,
-                   uint32_t invoke_stub_elf_idx
+                 , uint16_t code_elf_idx,
+                   uint16_t code_elf_func_idx,
+                   uint16_t invoke_stub_elf_idx,
+                   uint16_t invoke_stub_elf_func_idx
 #endif
                    );
   ~OatMethodOffsets();
@@ -99,8 +101,10 @@
   uint32_t invoke_stub_offset_;
 
 #if defined(ART_USE_LLVM_COMPILER)
-  uint32_t code_elf_idx_;
-  uint32_t invoke_stub_elf_idx_;
+  uint16_t code_elf_idx_;
+  uint16_t code_elf_func_idx_;
+  uint16_t invoke_stub_elf_idx_;
+  uint16_t invoke_stub_elf_func_idx_;
 #endif
 };
 
diff --git a/src/oat_file.cc b/src/oat_file.cc
index 97d8f64..81aa013 100644
--- a/src/oat_file.cc
+++ b/src/oat_file.cc
@@ -312,7 +312,9 @@
 #if defined(ART_USE_LLVM_COMPILER)
     , oat_file_->elf_loader_.get(),
       oat_method_offsets.code_elf_idx_,
-      oat_method_offsets.invoke_stub_elf_idx_
+      oat_method_offsets.code_elf_func_idx_,
+      oat_method_offsets.invoke_stub_elf_idx_,
+      oat_method_offsets.invoke_stub_elf_func_idx_
 #endif
       );
 }
@@ -328,8 +330,10 @@
                               const uint32_t invoke_stub_offset
 #if defined(ART_USE_LLVM_COMPILER)
                             , const compiler_llvm::ElfLoader* elf_loader,
-                              const uint32_t code_elf_idx,
-                              const uint32_t invoke_stub_elf_idx
+                              const uint16_t code_elf_idx,
+                              const uint16_t code_elf_func_idx,
+                              const uint16_t invoke_stub_elf_idx,
+                              const uint16_t invoke_stub_elf_func_idx
 #endif
                               )
   : begin_(base),
@@ -344,7 +348,9 @@
 #if defined(ART_USE_LLVM_COMPILER)
   , elf_loader_(elf_loader),
     code_elf_idx_(code_elf_idx),
-    invoke_stub_elf_idx_(invoke_stub_elf_idx)
+    code_elf_func_idx_(code_elf_func_idx),
+    invoke_stub_elf_idx_(invoke_stub_elf_idx),
+    invoke_stub_elf_func_idx_(invoke_stub_elf_func_idx)
 #endif
 {
 #ifndef NDEBUG
@@ -363,7 +369,6 @@
 
 OatFile::OatMethod::~OatMethod() {}
 
-
 const void* OatFile::OatMethod::GetCode() const {
   if (!IsCodeInElf()) {
     return GetOatPointer<const void*>(code_offset_);
@@ -373,7 +378,8 @@
     return NULL;
 #else
     CHECK(elf_loader_ != NULL);
-    const void* code = elf_loader_->GetMethodCodeAddr(code_elf_idx_, method);
+    const void* code =
+        elf_loader_->GetMethodCodeAddr(code_elf_idx_, code_elf_func_idx_);
     CHECK(code != NULL);
     return code;
 #endif
@@ -405,7 +411,9 @@
     return NULL;
 #else
     CHECK(elf_loader_ != NULL);
-    const Method::InvokeStub* stub = elf_loader_->GetMethodInvokeStubAddr(invoke_stub_elf_idx_, method);
+    const Method::InvokeStub* stub =
+        elf_loader_->GetMethodInvokeStubAddr(invoke_stub_elf_idx_,
+                                             invoke_stub_elf_func_idx_);
     CHECK(stub != NULL);
     return stub;
 #endif
@@ -420,7 +428,7 @@
     }
     return reinterpret_cast<uint32_t*>(code)[-1];
   } else {
-    UNIMPLEMENTED(ERROR);
+    UNIMPLEMENTED(WARNING);
     return 0;
   }
 }
@@ -449,10 +457,12 @@
   method->SetOatInvokeStubOffset(GetInvokeStubOffset());
 }
 
+#if defined(ART_USE_LLVM_COMPILER)
 OatFile::OatElfImage::OatElfImage(const OatFile* oat_file,
                                   const byte* addr,
                                   uint32_t size)
     : oat_file_(oat_file), elf_addr_(addr), elf_size_(size) {
 }
+#endif
 
 }  // namespace art
diff --git a/src/oat_file.h b/src/oat_file.h
index 07d7f63..0bd9d33 100644
--- a/src/oat_file.h
+++ b/src/oat_file.h
@@ -104,17 +104,23 @@
     }
 
 #if defined(ART_USE_LLVM_COMPILER)
-    uint32_t GetCodeElfIndex() const {
+    uint16_t GetCodeElfIndex() const {
       return code_elf_idx_;
     }
-    uint32_t GetInvokeStubElfIndex() const {
+    uint16_t GetCodeElfFuncIndex() const {
+      return code_elf_func_idx_;
+    }
+    uint16_t GetInvokeStubElfIndex() const {
       return invoke_stub_elf_idx_;
     }
+    uint16_t GetInvokeStubElfFuncIndex() const {
+      return invoke_stub_elf_func_idx_;
+    }
 #endif
 
     bool IsCodeInElf() const {
 #if defined(ART_USE_LLVM_COMPILER)
-      return (code_elf_idx_ != -1u);
+      return (code_elf_idx_ != static_cast<uint16_t>(-1));
 #else
       return false;
 #endif
@@ -122,7 +128,7 @@
 
     bool IsInvokeStubInElf() const {
 #if defined(ART_USE_LLVM_COMPILER)
-      return (invoke_stub_elf_idx_ != -1u);
+      return (invoke_stub_elf_idx_ != static_cast<uint16_t>(-1));
 #else
       return false;
 #endif
@@ -158,8 +164,10 @@
               const uint32_t invoke_stub_offset
 #if defined(ART_USE_LLVM_COMPILER)
             , const compiler_llvm::ElfLoader* elf_loader,
-              const uint32_t code_elf_idx,
-              const uint32_t invoke_stub_elf_idx
+              const uint16_t code_elf_idx,
+              const uint16_t code_elf_func_idx,
+              const uint16_t invoke_stub_elf_idx,
+              const uint16_t invoke_stub_elf_func_idx
 #endif
               );
 
@@ -186,8 +194,10 @@
 #if defined(ART_USE_LLVM_COMPILER)
     const compiler_llvm::ElfLoader* elf_loader_;
 
-    uint32_t code_elf_idx_;
-    uint32_t invoke_stub_elf_idx_;
+    uint16_t code_elf_idx_;
+    uint16_t code_elf_func_idx_;
+    uint16_t invoke_stub_elf_idx_;
+    uint16_t invoke_stub_elf_func_idx_;
 #endif
 
     friend class OatClass;
@@ -247,6 +257,7 @@
     DISALLOW_COPY_AND_ASSIGN(OatDexFile);
   };
 
+#if defined(ART_USE_LLVM_COMPILER)
   class OatElfImage {
    public:
     const byte* begin() const {
@@ -271,6 +282,7 @@
     friend class OatFile;
     DISALLOW_COPY_AND_ASSIGN(OatElfImage);
   };
+#endif
 
   const OatDexFile* GetOatDexFile(const std::string& dex_file_location,
                                   bool warn_if_not_found = true) const;
diff --git a/src/oat_writer.cc b/src/oat_writer.cc
index c639271..f08aa8d 100644
--- a/src/oat_writer.cc
+++ b/src/oat_writer.cc
@@ -257,7 +257,8 @@
                                     uint32_t method_idx, const DexFile* dex_file) {
   // derived from CompiledMethod if available
   uint32_t code_offset = 0;
-  uint32_t code_elf_idx = -1u;
+  uint16_t code_elf_idx = static_cast<uint16_t>(-1u);
+  uint16_t code_elf_func_idx = static_cast<uint16_t>(-1u);
   uint32_t frame_size_in_bytes = kStackAlignment;
   uint32_t core_spill_mask = 0;
   uint32_t fp_spill_mask = 0;
@@ -266,13 +267,15 @@
   uint32_t gc_map_offset = 0;
   // derived from CompiledInvokeStub if available
   uint32_t invoke_stub_offset = 0;
-  uint32_t invoke_stub_elf_idx = -1u;
+  uint16_t invoke_stub_elf_idx = static_cast<uint16_t>(-1u);
+  uint16_t invoke_stub_elf_func_idx = static_cast<uint16_t>(-1u);
 
   CompiledMethod* compiled_method =
       compiler_->GetCompiledMethod(Compiler::MethodReference(dex_file, method_idx));
   if (compiled_method != NULL) {
     if (compiled_method->IsExecutableInElf()) {
       code_elf_idx = compiled_method->GetElfIndex();
+      code_elf_func_idx = compiled_method->GetElfFuncIndex();
     } else {
       offset = compiled_method->AlignCode(offset);
       DCHECK_ALIGNED(offset, kArmAlignment);
@@ -355,6 +358,7 @@
   if (compiled_invoke_stub != NULL) {
     if (compiled_invoke_stub->IsExecutableInElf()) {
       invoke_stub_elf_idx = compiled_invoke_stub->GetElfIndex();
+      invoke_stub_elf_func_idx = compiled_invoke_stub->GetElfFuncIndex();
     } else {
       offset = CompiledMethod::AlignCode(offset, compiler_->GetInstructionSet());
       DCHECK_ALIGNED(offset, kArmAlignment);
@@ -387,7 +391,9 @@
                          invoke_stub_offset
 #if defined(ART_USE_LLVM_COMPILER)
                        , code_elf_idx,
-                         invoke_stub_elf_idx
+                         code_elf_func_idx,
+                         invoke_stub_elf_idx,
+                         invoke_stub_elf_func_idx
 #endif
                          );