Pass Framework Cleanup

Fixed an end-of-program  memory leak and added const as qualifiers
for various parameters.

The memory leak involves the pass array holder that would not be freed.
The solution now uses a template getter that holds the unique instance.

Change-Id: Ie8f5b0e5f4249f92851e8ba14e4238952edffee6
diff --git a/compiler/dex/pass_driver.cc b/compiler/dex/pass_driver.cc
index 99541ac..820dc5a 100644
--- a/compiler/dex/pass_driver.cc
+++ b/compiler/dex/pass_driver.cc
@@ -25,7 +25,20 @@
 
 namespace art {
 
-PassDriver::PassDriver(CompilationUnit* const cu, bool create_default_passes) : cu_(cu) {
+namespace {  // anonymous namespace
+
+/**
+ * @brief Helper function to create a single instance of a given Pass and can be shared across the threads
+ */
+template <typename PassType>
+const Pass* GetPassInstance() {
+  static const PassType pass;
+  return &pass;
+}
+
+}  // anonymous namespace
+
+PassDriver::PassDriver(CompilationUnit* cu, bool create_default_passes) : cu_(cu) {
   dump_cfg_folder_ = "/sdcard/";
 
   // If need be, create the default passes.
@@ -39,7 +52,7 @@
   pass_map_.clear();
 }
 
-void PassDriver::InsertPass(Pass* new_pass, bool warn_override) {
+void PassDriver::InsertPass(const Pass* new_pass, bool warn_override) {
   assert(new_pass != 0);
 
   // Get name here to not do it all over the method.
@@ -47,7 +60,7 @@
 
   // Do we want to warn the user about squashing a pass?
   if (warn_override == false) {
-    SafeMap<std::string, Pass* >::iterator it = pass_map_.find(name);
+    auto it = pass_map_.find(name);
 
     if (it != pass_map_.end()) {
       LOG(INFO) << "Pass name " << name << " already used, overwriting pass";
@@ -71,16 +84,16 @@
    * Disadvantage is the passes can't change their internal states depending on CompilationUnit:
    *   - This is not yet an issue: no current pass would require it.
    */
-  static UniquePtr<Pass> *passes[] = {
-      new UniquePtr<Pass>(new CodeLayout()),
-      new UniquePtr<Pass>(new SSATransformation()),
-      new UniquePtr<Pass>(new ConstantPropagation()),
-      new UniquePtr<Pass>(new InitRegLocations()),
-      new UniquePtr<Pass>(new MethodUseCount()),
-      new UniquePtr<Pass>(new NullCheckEliminationAndTypeInferenceInit()),
-      new UniquePtr<Pass>(new NullCheckEliminationAndTypeInference()),
-      new UniquePtr<Pass>(new BBCombine()),
-      new UniquePtr<Pass>(new BBOptimizations()),
+  static const Pass* passes[] = {
+      GetPassInstance<CodeLayout>(),
+      GetPassInstance<SSATransformation>(),
+      GetPassInstance<ConstantPropagation>(),
+      GetPassInstance<InitRegLocations>(),
+      GetPassInstance<MethodUseCount>(),
+      GetPassInstance<NullCheckEliminationAndTypeInferenceInit>(),
+      GetPassInstance<NullCheckEliminationAndTypeInference>(),
+      GetPassInstance<BBCombine>(),
+      GetPassInstance<BBOptimizations>(),
   };
 
   // Get number of elements in the array.
@@ -90,17 +103,17 @@
   //   - Map is used for the lookup
   //   - List is used for the pass walk
   for (unsigned int i = 0; i < nbr; i++) {
-    InsertPass(passes[i]->get());
+    InsertPass(passes[i]);
   }
 }
 
-void PassDriver::HandlePassFlag(CompilationUnit* c_unit, Pass* pass) {
+void PassDriver::HandlePassFlag(CompilationUnit* c_unit, const Pass* pass) {
   // Unused parameters for the moment.
   UNUSED(c_unit);
   UNUSED(pass);
 }
 
-void PassDriver::DispatchPass(CompilationUnit* c_unit, Pass* curPass) {
+void PassDriver::DispatchPass(CompilationUnit* c_unit, const Pass* curPass) {
   DataflowIterator* iterator = 0;
 
   LOG(DEBUG) << "Dispatching " << curPass->GetName();
@@ -147,13 +160,13 @@
   }
 }
 
-void PassDriver::ApplyPass(CompilationUnit* c_unit, Pass* curPass) {
+void PassDriver::ApplyPass(CompilationUnit* c_unit, const Pass* curPass) {
   curPass->Start(c_unit);
   DispatchPass(c_unit, curPass);
   curPass->End(c_unit);
 }
 
-bool PassDriver::RunPass(CompilationUnit* c_unit, Pass* curPass, bool time_split) {
+bool PassDriver::RunPass(CompilationUnit* c_unit, const Pass* curPass, bool time_split) {
   // Paranoid: c_unit or curPass cannot be 0, and the pass should have a name.
   if (c_unit == 0 || curPass == 0 || (strcmp(curPass->GetName(), "") == 0)) {
     return false;
@@ -200,7 +213,7 @@
     return false;
   }
 
-  Pass* curPass = GetPass(pass_name);
+  const Pass* curPass = GetPass(pass_name);
 
   if (curPass != 0) {
     return RunPass(c_unit, curPass);
@@ -211,8 +224,7 @@
 }
 
 void PassDriver::Launch() {
-  for (std::list<Pass* >::iterator it = pass_list_.begin(); it != pass_list_.end(); it++) {
-    Pass* curPass = *it;
+  for (const Pass *curPass : pass_list_) {
     RunPass(cu_, curPass, true);
   }
 }
@@ -220,14 +232,13 @@
 void PassDriver::PrintPassNames() const {
   LOG(INFO) << "Loop Passes are:";
 
-  for (std::list<Pass* >::const_iterator it = pass_list_.begin(); it != pass_list_.end(); it++) {
-    const Pass* curPass = *it;
+  for (const Pass *curPass : pass_list_) {
     LOG(INFO) << "\t-" << curPass->GetName();
   }
 }
 
-Pass* PassDriver::GetPass(const std::string& name) const {
-  SafeMap<std::string, Pass*>::const_iterator it = pass_map_.find(name);
+const Pass* PassDriver::GetPass(const std::string& name) const {
+  auto it = pass_map_.find(name);
 
   if (it != pass_map_.end()) {
     return it->second;
diff --git a/compiler/dex/pass_driver.h b/compiler/dex/pass_driver.h
index 29da351..d580460 100644
--- a/compiler/dex/pass_driver.h
+++ b/compiler/dex/pass_driver.h
@@ -33,7 +33,7 @@
  */
 class PassDriver {
  public:
-  explicit PassDriver(CompilationUnit* const cu, bool create_default_passes = true);
+  explicit PassDriver(CompilationUnit* cu, bool create_default_passes = true);
 
   ~PassDriver();
 
@@ -42,7 +42,7 @@
    * @param new_pass the new Pass to insert in the map and list.
    * @param warn_override warn if the name of the Pass is already used.
    */
-  void InsertPass(Pass *new_pass, bool warn_override = true);
+  void InsertPass(const Pass* new_pass, bool warn_override = true);
 
   /**
    * @brief Run a pass using the name as key.
@@ -57,25 +57,25 @@
    * @param time_split do we want a time split request(default: false)?
    * @return whether the pass was applied.
    */
-  bool RunPass(CompilationUnit* c_unit, Pass* pass, bool time_split = false);
+  bool RunPass(CompilationUnit* c_unit, const Pass* pass, bool time_split = false);
 
   void Launch();
 
-  void HandlePassFlag(CompilationUnit* c_unit, Pass* pass);
+  void HandlePassFlag(CompilationUnit* c_unit, const Pass* pass);
 
   /**
    * @brief Apply a patch: perform start/work/end functions.
    */
-  void ApplyPass(CompilationUnit* c_unit, Pass* pass);
+  void ApplyPass(CompilationUnit* c_unit, const Pass* pass);
 
   /**
    * @brief Dispatch a patch: walk the BasicBlocks depending on the traversal mode
    */
-  void DispatchPass(CompilationUnit* c_unit, Pass* pass);
+  void DispatchPass(CompilationUnit* c_unit, const Pass* pass);
 
   void PrintPassNames() const;
 
-  Pass* GetPass(const std::string& name) const;
+  const Pass* GetPass(const std::string& name) const;
 
   const char *GetDumpCFGFolder() const {
     return dump_cfg_folder_;
@@ -85,10 +85,10 @@
   void CreatePasses();
 
   /** @brief The Pass Map: contains name -> pass for quick lookup. */
-  SafeMap<std::string, Pass*> pass_map_;
+  SafeMap<std::string, const Pass*> pass_map_;
 
   /** @brief List of passes: provides the order to execute the passes. */
-  std::list<Pass*> pass_list_;
+  std::list<const Pass*> pass_list_;
 
   /** @brief The CompilationUnit on which to execute the passes on. */
   CompilationUnit* const cu_;