Reduce memory usage.

Also, fix InferredRegCategoryMap constructor. (The regs_size is uint16_t.)

Change-Id: If85df1ad78c3acc6d3c19e605ee7d90f43df1159
diff --git a/src/compiler_llvm/compilation_unit.cc b/src/compiler_llvm/compilation_unit.cc
index 277eae6..b4bdd5d 100644
--- a/src/compiler_llvm/compilation_unit.cc
+++ b/src/compiler_llvm/compilation_unit.cc
@@ -170,7 +170,8 @@
 
 CompilationUnit::CompilationUnit(InstructionSet insn_set, size_t elf_idx)
 : cunit_lock_("compilation_unit_lock"), insn_set_(insn_set), elf_idx_(elf_idx),
-  context_(new llvm::LLVMContext()), mem_usage_(0), num_elf_funcs_(0) {
+  context_(new llvm::LLVMContext()), compiled_methods_map_(new CompiledMethodMap()),
+  mem_usage_(0), num_elf_funcs_(0) {
 
   // Create the module and include the runtime function declaration
   module_ = new llvm::Module("art", *context_);
@@ -215,6 +216,8 @@
   context_.reset(NULL);
   irb_.reset(NULL);
   module_ = NULL;
+  runtime_support_.reset(NULL);
+  compiled_methods_map_.reset(NULL);
 
   return success;
 }
@@ -223,7 +226,7 @@
 void CompilationUnit::RegisterCompiledMethod(const llvm::Function* func,
                                              CompiledMethod* compiled_method) {
   MutexLock GUARD(cunit_lock_);
-  compiled_methods_map_.Put(func, compiled_method);
+  compiled_methods_map_->Put(func, compiled_method);
 }
 
 
@@ -231,9 +234,9 @@
                                              size_t frame_size_in_bytes) {
   MutexLock GUARD(cunit_lock_);
   SafeMap<const llvm::Function*, CompiledMethod*>::iterator iter =
-    compiled_methods_map_.find(func);
+    compiled_methods_map_->find(func);
 
-  if (iter != compiled_methods_map_.end()) {
+  if (iter != compiled_methods_map_->end()) {
     CompiledMethod* compiled_method = iter->second;
     compiled_method->SetFrameSizeInBytes(frame_size_in_bytes);
 
diff --git a/src/compiler_llvm/compilation_unit.h b/src/compiler_llvm/compilation_unit.h
index 52e4ae6..d391620 100644
--- a/src/compiler_llvm/compilation_unit.h
+++ b/src/compiler_llvm/compilation_unit.h
@@ -102,7 +102,7 @@
 
   bool IsMaterializeThresholdReached() const {
     MutexLock GUARD(cunit_lock_);
-    return (mem_usage_ > 5000000u); // (threshold: 5 MB)
+    return (mem_usage_ > 1000000u); // (threshold: 1 MB)
   }
 
   void AddMemUsageApproximation(size_t usage) {
@@ -128,7 +128,8 @@
   std::string bitcode_filename_;
   std::string elf_image_;
 
-  SafeMap<const llvm::Function*, CompiledMethod*> compiled_methods_map_;
+  typedef SafeMap<const llvm::Function*, CompiledMethod*> CompiledMethodMap;
+  UniquePtr<CompiledMethodMap> compiled_methods_map_;
 
   size_t mem_usage_;
   uint16_t num_elf_funcs_;
diff --git a/src/compiler_llvm/inferred_reg_category_map.cc b/src/compiler_llvm/inferred_reg_category_map.cc
index 2403750..0875a3f 100644
--- a/src/compiler_llvm/inferred_reg_category_map.cc
+++ b/src/compiler_llvm/inferred_reg_category_map.cc
@@ -27,31 +27,31 @@
 
 
 InferredRegCategoryMap::InferredRegCategoryMap(uint32_t insns_size,
-                                               uint8_t regs_size)
-: registers_size_(regs_size), lines_(insns_size, NULL), can_be_object_(regs_size) {
+                                               uint16_t regs_size)
+: registers_size_(regs_size), can_be_object_(regs_size) {
 }
 
 InferredRegCategoryMap::~InferredRegCategoryMap() {
-  STLDeleteElements(&lines_);
+  STLDeleteValues(&lines_);
 }
 
 RegCategory InferredRegCategoryMap::GetRegCategory(uint32_t dex_pc,
                                                    uint16_t reg_idx) const {
-  if (lines_[dex_pc] == NULL) {
+  if (lines_.count(dex_pc) == 0) {
     return kRegUnknown;
   }
-  return lines_[dex_pc]->GetRegCategory(reg_idx);
+  return lines_.Get(dex_pc)->GetRegCategory(reg_idx);
 }
 
 void InferredRegCategoryMap::SetRegCategory(uint32_t dex_pc,
                                             uint16_t reg_idx,
                                             RegCategory cat) {
   if (cat != kRegUnknown) {
-    if (lines_[dex_pc] == NULL) {
-      lines_[dex_pc] = new RegCategoryLine();
+    if (lines_.count(dex_pc) == 0) {
+      lines_.Put(dex_pc, new RegCategoryLine(registers_size_));
     }
 
-    (*lines_[dex_pc]).SetRegCategory(reg_idx, cat);
+    lines_.Get(dex_pc)->SetRegCategory(reg_idx, cat);
   }
 }
 
@@ -75,16 +75,16 @@
   }
 
   for (size_t i = 0; i < lines_.size(); ++i) {
-    if (lines_[i] == NULL && rhs.lines_[i] == NULL) {
+    if (lines_.count(i) == 0 && rhs.lines_.count(i) == 0) {
       continue;
     }
 
-    if ((lines_[i] == NULL && rhs.lines_[i] != NULL) ||
-        (lines_[i] != NULL && rhs.lines_[i] == NULL)) {
+    if ((lines_.count(i) == 0 && rhs.lines_.count(i) != 0) ||
+        (lines_.count(i) != 0 && rhs.lines_.count(i) == 0)) {
       return false;
     }
 
-    if (*lines_[i] != *rhs.lines_[i]) {
+    if (*lines_.Get(i) != *rhs.lines_.Get(i)) {
       return false;
     }
   }
diff --git a/src/compiler_llvm/inferred_reg_category_map.h b/src/compiler_llvm/inferred_reg_category_map.h
index 7f4082d..1626d92 100644
--- a/src/compiler_llvm/inferred_reg_category_map.h
+++ b/src/compiler_llvm/inferred_reg_category_map.h
@@ -32,23 +32,19 @@
  private:
   class RegCategoryLine {
    private:
-    typedef SafeMap<uint16_t, uint8_t> Table;
+    typedef std::vector<uint8_t> Table;
     Table reg_category_line_;
 
    public:
+    RegCategoryLine(size_t num_regs) : reg_category_line_(num_regs, kRegUnknown) {}
     RegCategory GetRegCategory(uint16_t reg_idx) const {
-      // TODO: C++0x auto
-      Table::const_iterator result = reg_category_line_.find(reg_idx);
-      if (result == reg_category_line_.end()) {
-        return kRegUnknown;
-      }
-      return static_cast<RegCategory>(result->second);
+      DCHECK_LT(reg_idx, reg_category_line_.size());
+      return static_cast<RegCategory>(reg_category_line_[reg_idx]);
     }
 
     void SetRegCategory(uint16_t reg_idx, RegCategory cat) {
-      if (cat != kRegUnknown) {
-        reg_category_line_.Put(reg_idx, cat);
-      }
+      DCHECK_LT(reg_idx, reg_category_line_.size());
+      reg_category_line_[reg_idx] = cat;
     }
 
     bool operator==(RegCategoryLine const& rhs) const {
@@ -60,7 +56,7 @@
   };
 
  public:
-  InferredRegCategoryMap(uint32_t insns_size_in_code_units, uint8_t regs_size);
+  InferredRegCategoryMap(uint32_t insns_size_in_code_units, uint16_t regs_size);
 
   ~InferredRegCategoryMap();
 
@@ -76,7 +72,7 @@
  private:
   uint16_t registers_size_;
 
-  std::vector<RegCategoryLine*> lines_;
+  SafeMap<uint32_t, RegCategoryLine*> lines_;
 
   std::vector<bool> can_be_object_;
 
diff --git a/src/safe_map.h b/src/safe_map.h
index 1544181..0af158f 100644
--- a/src/safe_map.h
+++ b/src/safe_map.h
@@ -40,8 +40,8 @@
   size_type count(const K& k) const { return map_.count(k); }
 
   // Note that unlike std::map's operator[], this doesn't return a reference to the value.
-  V Get(const K& k) {
-    iterator it = map_.find(k);
+  V Get(const K& k) const {
+    const_iterator it = map_.find(k);
     DCHECK(it != map_.end());
     return it->second;
   }
diff --git a/src/verifier/method_verifier.cc b/src/verifier/method_verifier.cc
index bf6d600..81c755d 100644
--- a/src/verifier/method_verifier.cc
+++ b/src/verifier/method_verifier.cc
@@ -944,6 +944,10 @@
     return false;
   }
 
+  Compiler::MethodReference ref(dex_file_, method_idx_);
+
+#if !defined(ART_USE_LLVM_COMPILER)
+
   /* Generate a register map and add it to the method. */
   UniquePtr<const std::vector<uint8_t> > map(GenerateGcMap());
   if (map.get() == NULL) {
@@ -954,17 +958,18 @@
   VerifyGcMap(*map);
 #endif
   const std::vector<uint8_t>* gc_map = CreateLengthPrefixedGcMap(*(map.get()));
-  Compiler::MethodReference ref(dex_file_, method_idx_);
   verifier::MethodVerifier::SetGcMap(ref, *gc_map);
 
   if (foo_method_ != NULL) {
     foo_method_->SetGcMap(&gc_map->at(0));
   }
 
-#if defined(ART_USE_LLVM_COMPILER)
+#else  //defined(ART_USE_LLVM_COMPILER)
+
   /* Generate Inferred Register Category for LLVM-based Code Generator */
   const InferredRegCategoryMap* table = GenerateInferredRegCategoryMap();
   verifier::MethodVerifier::SetInferredRegCategoryMap(ref, *table);
+
 #endif
 
   return true;
@@ -3336,18 +3341,29 @@
     if (RegisterLine* line = reg_table_.GetLine(i)) {
       for (size_t r = 0; r < regs_size; ++r) {
         const RegType &rt = line->GetRegisterType(r);
-
-        if (rt.IsZero()) {
-          table->SetRegCategory(i, r, kRegZero);
-        } else if (rt.IsCategory1Types()) {
-          table->SetRegCategory(i, r, kRegCat1nr);
-        } else if (rt.IsCategory2Types()) {
-          table->SetRegCategory(i, r, kRegCat2);
-        } else if (rt.IsReferenceTypes()) {
-          table->SetRegCategory(i, r, kRegObject);
+        if (rt.IsNonZeroReferenceTypes()) {
           table->SetRegCanBeObject(r);
-        } else {
-          table->SetRegCategory(i, r, kRegUnknown);
+        }
+      }
+
+      const Instruction* inst = Instruction::At(code_item_->insns_ + i);
+
+      /* We only use InferredRegCategoryMap in two cases */
+      if (inst->IsBranch() || inst->IsReturn()) {
+        for (size_t r = 0; r < regs_size; ++r) {
+          const RegType &rt = line->GetRegisterType(r);
+
+          if (rt.IsZero()) {
+            table->SetRegCategory(i, r, kRegZero);
+          } else if (rt.IsCategory1Types()) {
+            table->SetRegCategory(i, r, kRegCat1nr);
+          } else if (rt.IsCategory2Types()) {
+            table->SetRegCategory(i, r, kRegCat2);
+          } else if (rt.IsReferenceTypes()) {
+            table->SetRegCategory(i, r, kRegObject);
+          } else {
+            table->SetRegCategory(i, r, kRegUnknown);
+          }
         }
       }
     }