1 /* 2 * Copyright (C) 2011 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_COMPILER_IR_H_ 18 #define ART_COMPILER_DEX_COMPILER_IR_H_ 19 20 #include "jni.h" 21 #include <string> 22 #include <vector> 23 24 #include "arch/instruction_set.h" 25 #include "base/arena_allocator.h" 26 #include "base/scoped_arena_allocator.h" 27 #include "base/timing_logger.h" 28 #include "invoke_type.h" 29 #include "safe_map.h" 30 31 namespace art { 32 33 class ClassLinker; 34 class CompilerDriver; 35 class DexFile; 36 class Mir2Lir; 37 class MIRGraph; 38 39 constexpr size_t kOptionStringMaxLength = 2048; 40 41 /** 42 * Structure abstracting pass option values, which can be of type string or integer. 43 */ 44 struct OptionContent { OptionContentOptionContent45 OptionContent(const OptionContent& option) : 46 type(option.type), container(option.container, option.type) {} 47 OptionContentOptionContent48 explicit OptionContent(const char* value) : 49 type(kString), container(value) {} 50 OptionContentOptionContent51 explicit OptionContent(int value) : 52 type(kInteger), container(value) {} 53 OptionContentOptionContent54 explicit OptionContent(int64_t value) : 55 type(kInteger), container(value) {} 56 ~OptionContentOptionContent57 ~OptionContent() { 58 if (type == kString) { 59 container.StringDelete(); 60 } 61 } 62 63 /** 64 * Allows for a transparent display of the option content. 65 */ 66 friend std::ostream& operator<<(std::ostream& out, const OptionContent& option) { 67 if (option.type == kString) { 68 out << option.container.s; 69 } else { 70 out << option.container.i; 71 } 72 73 return out; 74 } 75 GetStringOptionContent76 inline const char* GetString() const { 77 return container.s; 78 } 79 GetIntegerOptionContent80 inline int64_t GetInteger() const { 81 return container.i; 82 } 83 84 /** 85 * @brief Used to compare a string option value to a given @p value. 86 * @details Will return whether the internal string option is equal to 87 * the parameter @p value. It will return false if the type of the 88 * object is not a string. 89 * @param value The string to compare to. 90 * @return Returns whether the internal string option is equal to the 91 * parameter @p value. 92 */ EqualsOptionContent93 inline bool Equals(const char* value) const { 94 DCHECK(value != nullptr); 95 if (type != kString) { 96 return false; 97 } 98 return !strncmp(container.s, value, kOptionStringMaxLength); 99 } 100 101 /** 102 * @brief Used to compare an integer option value to a given @p value. 103 * @details Will return whether the internal integer option is equal to 104 * the parameter @p value. It will return false if the type of the 105 * object is not an integer. 106 * @param value The integer to compare to. 107 * @return Returns whether the internal integer option is equal to the 108 * parameter @p value. 109 */ EqualsOptionContent110 inline bool Equals(int64_t value) const { 111 if (type != kInteger) { 112 return false; 113 } 114 return container.i == value; 115 } 116 117 /** 118 * Describes the type of parameters allowed as option values. 119 */ 120 enum OptionType { 121 kString = 0, 122 kInteger 123 }; 124 125 OptionType type; 126 127 private: 128 /** 129 * Union containing the option value of either type. 130 */ 131 union OptionContainer { OptionContainer(const OptionContainer & c,OptionType t)132 explicit OptionContainer(const OptionContainer& c, OptionType t) { 133 if (t == kString) { 134 DCHECK(c.s != nullptr); 135 s = strndup(c.s, kOptionStringMaxLength); 136 } else { 137 i = c.i; 138 } 139 } 140 OptionContainer(const char * value)141 explicit OptionContainer(const char* value) { 142 DCHECK(value != nullptr); 143 s = strndup(value, kOptionStringMaxLength); 144 } 145 OptionContainer(int64_t value)146 explicit OptionContainer(int64_t value) : i(value) {} ~OptionContainer()147 ~OptionContainer() {} 148 StringDelete()149 void StringDelete() { 150 if (s != nullptr) { 151 free(s); 152 } 153 } 154 155 char* s; 156 int64_t i; 157 }; 158 159 OptionContainer container; 160 }; 161 162 struct CompilationUnit { 163 CompilationUnit(ArenaPool* pool, InstructionSet isa, CompilerDriver* driver, ClassLinker* linker); 164 ~CompilationUnit(); 165 166 void StartTimingSplit(const char* label); 167 void NewTimingSplit(const char* label); 168 void EndTiming(); 169 170 /* 171 * Fields needed/generated by common frontend and generally used throughout 172 * the compiler. 173 */ 174 CompilerDriver* const compiler_driver; 175 ClassLinker* const class_linker; // Linker to resolve fields and methods. 176 const DexFile* dex_file; // DexFile containing the method being compiled. 177 jobject class_loader; // compiling method's class loader. 178 uint16_t class_def_idx; // compiling method's defining class definition index. 179 uint32_t method_idx; // compiling method's index into method_ids of DexFile. 180 uint32_t access_flags; // compiling method's access flags. 181 InvokeType invoke_type; // compiling method's invocation type. 182 const char* shorty; // compiling method's shorty. 183 uint32_t disable_opt; // opt_control_vector flags. 184 uint32_t enable_debug; // debugControlVector flags. 185 bool verbose; 186 const InstructionSet instruction_set; 187 const bool target64; 188 189 // TODO: move memory management to mir_graph, or just switch to using standard containers. 190 ArenaAllocator arena; 191 ArenaStack arena_stack; // Arenas for ScopedArenaAllocator. 192 193 std::unique_ptr<MIRGraph> mir_graph; // MIR container. 194 std::unique_ptr<Mir2Lir> cg; // Target-specific codegen. 195 TimingLogger timings; 196 bool print_pass; // Do we want to print a pass or not? 197 198 /** 199 * @brief Holds pass options for current pass being applied to compilation unit. 200 * @details This is updated for every pass to contain the overridden pass options 201 * that were specified by user. The pass itself will check this to see if the 202 * default settings have been changed. The key is simply the option string without 203 * the pass name. 204 */ 205 SafeMap<const std::string, const OptionContent> overridden_pass_options; 206 }; 207 208 } // namespace art 209 210 #endif // ART_COMPILER_DEX_COMPILER_IR_H_ 211