1 /** 2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 #ifndef PANDA_RUNTIME_OPTIONS_H_ 16 #define PANDA_RUNTIME_OPTIONS_H_ 17 18 #include "generated/runtime_options_gen.h" 19 #include "utils/logger.h" 20 #include "runtime/plugins.h" 21 22 namespace panda { 23 /** 24 * \brief Verification mode 25 */ 26 enum class VerificationMode { 27 DISABLED, // No verification 28 ON_THE_FLY, // Verify methods before they are executed (used by panda/ark executable) 29 AHEAD_OF_TIME, // Verify methods at startup (used by verifier executable) 30 DEBUG // Debug verification by enabling breakpoints (used by verifier executable) 31 }; 32 33 /** 34 * \brief Class represents runtime options 35 * 36 * It extends Options that represents public options (that described in options.yaml) and 37 * adds some private options related to runtime initialization that cannot be controlled 38 * via command line tools. Now they are used in unit tests to create minimal runtime for 39 * testing. 40 * 41 * To control private options from any class/function we need make it friend for this class. 42 */ 43 class RuntimeOptions : public Options { 44 public: Options(exe_path)45 explicit RuntimeOptions(const std::string &exe_path = "") : Options(exe_path) {} 46 ShouldLoadBootPandaFiles()47 bool ShouldLoadBootPandaFiles() const 48 { 49 return should_load_boot_panda_files_; 50 } 51 ShouldInitializeIntrinsics()52 bool ShouldInitializeIntrinsics() const 53 { 54 return should_initialize_intrinsics_; 55 } 56 GetMobileLog()57 void *GetMobileLog() 58 { 59 return mlog_buf_print_ptr_; 60 } 61 GetFingerprint()62 const std::string &GetFingerprint() const 63 { 64 return fingerPrint_; 65 } 66 SetFingerprint(const std::string & in)67 void SetFingerprint(const std::string &in) 68 { 69 fingerPrint_.assign(in); 70 } 71 GetVerificationMode()72 VerificationMode GetVerificationMode() const 73 { 74 return verification_mode_; 75 } 76 SetVerificationMode(VerificationMode in)77 void SetVerificationMode(VerificationMode in) 78 { 79 verification_mode_ = in; 80 } 81 IsVerifyRuntimeLibraries()82 bool IsVerifyRuntimeLibraries() const 83 { 84 return verify_runtime_libraries_; 85 } 86 SetVerifyRuntimeLibraries(bool in)87 void SetVerifyRuntimeLibraries(bool in) 88 { 89 verify_runtime_libraries_ = in; 90 } 91 SetUnwindStack(void * in)92 void SetUnwindStack(void *in) 93 { 94 unwindstack_ = reinterpret_cast<char *>(in); 95 } 96 GetUnwindStack()97 void *GetUnwindStack() const 98 { 99 return unwindstack_; 100 } 101 SetCrashConnect(void * in)102 void SetCrashConnect(void *in) 103 { 104 crash_connect_ = reinterpret_cast<char *>(in); 105 } 106 GetCrashConnect()107 void *GetCrashConnect() const 108 { 109 return crash_connect_; 110 } 111 SetMobileLog(void * mlog_buf_print_ptr)112 void SetMobileLog(void *mlog_buf_print_ptr) 113 { 114 mlog_buf_print_ptr_ = mlog_buf_print_ptr; 115 Logger::SetMobileLogPrintEntryPointByPtr(mlog_buf_print_ptr); 116 } 117 SetForSnapShotStart()118 void SetForSnapShotStart() 119 { 120 should_load_boot_panda_files_ = false; 121 should_initialize_intrinsics_ = false; 122 } 123 SetShouldLoadBootPandaFiles(bool value)124 void SetShouldLoadBootPandaFiles(bool value) 125 { 126 should_load_boot_panda_files_ = value; 127 } 128 SetShouldInitializeIntrinsics(bool value)129 void SetShouldInitializeIntrinsics(bool value) 130 { 131 should_initialize_intrinsics_ = value; 132 } 133 UseMallocForInternalAllocations()134 bool UseMallocForInternalAllocations() const 135 { 136 bool use_malloc = false; 137 auto option = GetInternalAllocatorType(); 138 if (option == "default") { 139 #ifdef NDEBUG 140 use_malloc = true; 141 #else 142 use_malloc = false; 143 #endif 144 } else if (option == "malloc") { 145 use_malloc = true; 146 } else if (option == "panda_allocators") { 147 use_malloc = false; 148 } else { 149 UNREACHABLE(); 150 } 151 return use_malloc; 152 } 153 IsG1TrackFreedObjects()154 bool IsG1TrackFreedObjects() const 155 { 156 bool track = false; 157 auto option = GetG1TrackFreedObjects(); 158 if (option == "default") { 159 #ifdef NDEBUG 160 track = true; 161 #else 162 track = false; 163 #endif 164 } else if (option == "true") { 165 track = true; 166 } else if (option == "false") { 167 track = false; 168 } else { 169 UNREACHABLE(); 170 } 171 return track; 172 } 173 InitializeRuntimeSpacesAndType()174 void InitializeRuntimeSpacesAndType() 175 { 176 CheckAndFixIntrinsicSpaces(); 177 if (WasSetLoadRuntimes()) { 178 std::vector<std::string> load_runtimes = GetLoadRuntimes(); 179 std::vector<std::string> class_spaces; 180 std::string runtime_type = "core"; 181 182 if (WasSetBootClassSpaces()) { 183 class_spaces = GetBootClassSpaces(); 184 std::unique_copy(load_runtimes.begin(), load_runtimes.end(), std::back_inserter(class_spaces)); 185 } else { 186 class_spaces = load_runtimes; 187 } 188 189 if (WasSetRuntimeType()) { 190 runtime_type = GetRuntimeType(); 191 } else { 192 // Select first non-core runtime 193 for (auto &runtime : load_runtimes) { 194 if (runtime != "core") { 195 runtime_type = runtime; 196 break; 197 } 198 } 199 } 200 201 SetRuntimeType(runtime_type); 202 SetBootClassSpaces(class_spaces); 203 } else { 204 std::vector<std::string> intrinsic_spaces = GetBootIntrinsicSpaces(); 205 std::vector<std::string> class_spaces = GetBootClassSpaces(); 206 std::vector<std::string> load_runtimes; 207 if (intrinsic_spaces.size() < class_spaces.size()) { 208 load_runtimes = intrinsic_spaces; 209 } else { 210 load_runtimes = class_spaces; 211 } 212 SetLoadRuntimes(load_runtimes); 213 } 214 } 215 216 private: 217 // Fix default value for possible missing plugins. CheckAndFixIntrinsicSpaces()218 void CheckAndFixIntrinsicSpaces() 219 { 220 bool intr_set = WasSetBootIntrinsicSpaces(); 221 std::vector<std::string> spaces = GetBootIntrinsicSpaces(); 222 for (auto it = spaces.begin(); it != spaces.end();) { 223 if (panda::plugins::HasRuntime(*it)) { 224 ++it; 225 continue; 226 } 227 228 if (intr_set) { 229 LOG(FATAL, RUNTIME) << "Missing runtime for intrinsic space " << *it; 230 } 231 it = spaces.erase(it); 232 } 233 234 SetBootIntrinsicSpaces(spaces); 235 } 236 237 bool should_load_boot_panda_files_ {true}; 238 bool should_initialize_intrinsics_ {true}; 239 void *mlog_buf_print_ptr_ {nullptr}; 240 std::string fingerPrint_ {"unknown"}; 241 void *unwindstack_ {nullptr}; 242 void *crash_connect_ {nullptr}; 243 VerificationMode verification_mode_ {VerificationMode::DISABLED}; 244 bool verify_runtime_libraries_ {false}; 245 }; 246 } // namespace panda 247 248 #endif // PANDA_RUNTIME_OPTIONS_H_ 249