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