1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef ART_COMPILER_DEX_PASS_DRIVER_H_
18 #define ART_COMPILER_DEX_PASS_DRIVER_H_
19 
20 #include <vector>
21 
22 #include "base/logging.h"
23 #include "pass.h"
24 #include "pass_manager.h"
25 
26 namespace art {
27 
28 class Pass;
29 class PassDataHolder;
30 class PassDriver;
31 class PassManager;
32 
33 // Empty holder for the constructor.
34 class PassDriverDataHolder {
35 };
36 
37 /**
38  * @class PassDriver
39  * @brief PassDriver is the wrapper around all Pass instances in order to execute them
40  */
41 class PassDriver {
42  public:
PassDriver(const PassManager * const pass_manager)43   explicit PassDriver(const PassManager* const pass_manager) : pass_manager_(pass_manager) {
44     pass_list_ = *pass_manager_->GetDefaultPassList();
45     DCHECK(!pass_list_.empty());
46   }
47 
~PassDriver()48   virtual ~PassDriver() {
49   }
50 
51   /**
52    * @brief Insert a Pass: can warn if multiple passes have the same name.
53    */
InsertPass(const Pass * new_pass)54   void InsertPass(const Pass* new_pass) {
55     DCHECK(new_pass != nullptr);
56     DCHECK(new_pass->GetName() != nullptr);
57     DCHECK_NE(new_pass->GetName()[0], 0);
58 
59     // It is an error to override an existing pass.
60     DCHECK(GetPass(new_pass->GetName()) == nullptr)
61         << "Pass name " << new_pass->GetName() << " already used.";
62     // Now add to the list.
63     pass_list_.push_back(new_pass);
64   }
65 
66   /**
67    * @brief Run a pass using the name as key.
68    * @return whether the pass was applied.
69    */
RunPass(const char * pass_name)70   virtual bool RunPass(const char* pass_name) {
71     // Paranoid: c_unit cannot be null and we need a pass name.
72     DCHECK(pass_name != nullptr);
73     DCHECK_NE(pass_name[0], 0);
74 
75     const Pass* cur_pass = GetPass(pass_name);
76 
77     if (cur_pass != nullptr) {
78       return RunPass(cur_pass);
79     }
80 
81     // Return false, we did not find the pass.
82     return false;
83   }
84 
85   /**
86    * @brief Runs all the passes with the pass_list_.
87    */
Launch()88   void Launch() {
89     for (const Pass* cur_pass : pass_list_) {
90       RunPass(cur_pass);
91     }
92   }
93 
94   /**
95    * @brief Searches for a particular pass.
96    * @param the name of the pass to be searched for.
97    */
GetPass(const char * name)98   const Pass* GetPass(const char* name) const {
99     for (const Pass* cur_pass : pass_list_) {
100       if (strcmp(name, cur_pass->GetName()) == 0) {
101         return cur_pass;
102       }
103     }
104     return nullptr;
105   }
106 
107   /**
108    * @brief Run a pass using the Pass itself.
109    * @param time_split do we want a time split request(default: false)?
110    * @return whether the pass was applied.
111    */
112   virtual bool RunPass(const Pass* pass, bool time_split = false) = 0;
113 
114  protected:
115   /**
116    * @brief Apply a patch: perform start/work/end functions.
117    */
ApplyPass(PassDataHolder * data,const Pass * pass)118   virtual void ApplyPass(PassDataHolder* data, const Pass* pass) {
119     pass->Start(data);
120     DispatchPass(pass);
121     pass->End(data);
122   }
123 
124   /**
125    * @brief Dispatch a patch.
126    * Gives the ability to add logic when running the patch.
127    */
DispatchPass(const Pass * pass)128   virtual void DispatchPass(const Pass* pass) {
129     UNUSED(pass);
130   }
131 
132   /** @brief List of passes: provides the order to execute the passes.
133    *  Passes are owned by pass_manager_. */
134   std::vector<const Pass*> pass_list_;
135 
136   const PassManager* const pass_manager_;
137 };
138 
139 }  // namespace art
140 #endif  // ART_COMPILER_DEX_PASS_DRIVER_H_
141