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 /// @brief Verification mode 24 enum class VerificationMode { 25 DISABLED, // No verification 26 ON_THE_FLY, // Verify methods before they are executed (used by panda/ark executable) 27 AHEAD_OF_TIME, // Verify methods at startup (used by verifier executable) 28 DEBUG // Debug verification by enabling breakpoints (used by verifier executable) 29 }; 30 IsEnabled(VerificationMode mode)31static inline bool IsEnabled(VerificationMode mode) 32 { 33 return mode != VerificationMode::DISABLED; 34 } 35 VerificationModeFromString(const std::string & mode)36static inline VerificationMode VerificationModeFromString(const std::string &mode) 37 { 38 if (mode == "on-the-fly") { 39 return VerificationMode::ON_THE_FLY; 40 } 41 if (mode == "ahead-of-time") { 42 return VerificationMode::AHEAD_OF_TIME; 43 } 44 if (mode == "debug") { 45 return VerificationMode::DEBUG; 46 } 47 return VerificationMode::DISABLED; 48 } 49 50 /** 51 * @brief Class represents runtime options 52 * 53 * It extends Options that represents public options (that described in options.yaml) and 54 * adds some private options related to runtime initialization that cannot be controlled 55 * via command line tools. Now they are used in unit tests to create minimal runtime for 56 * testing. 57 * 58 * To control private options from any class/function we need make it friend for this class. 59 */ 60 class PANDA_PUBLIC_API RuntimeOptions : public Options { 61 public: Options(exePath)62 explicit RuntimeOptions(const std::string &exePath = "") : Options(exePath) {} 63 ShouldLoadBootPandaFiles()64 bool ShouldLoadBootPandaFiles() const 65 { 66 return shouldLoadBootPandaFiles_; 67 } 68 ShouldInitializeIntrinsics()69 bool ShouldInitializeIntrinsics() const 70 { 71 return shouldInitializeIntrinsics_; 72 } 73 GetMobileLog()74 void *GetMobileLog() 75 { 76 return mlogBufPrintPtr_; 77 } 78 GetFingerprint()79 const std::string &GetFingerprint() const 80 { 81 return fingerPrint_; 82 } 83 SetFingerprint(const std::string & in)84 void SetFingerprint(const std::string &in) 85 { 86 fingerPrint_.assign(in); 87 } 88 GetVerificationMode()89 VerificationMode GetVerificationMode() const 90 { 91 return verificationMode_; 92 } 93 SetVerificationMode(VerificationMode in)94 void SetVerificationMode(VerificationMode in) 95 { 96 verificationMode_ = in; 97 } 98 IsVerifyRuntimeLibraries()99 bool IsVerifyRuntimeLibraries() const 100 { 101 return verifyRuntimeLibraries_; 102 } 103 SetVerifyRuntimeLibraries(bool in)104 void SetVerifyRuntimeLibraries(bool in) 105 { 106 verifyRuntimeLibraries_ = in; 107 } 108 SetUnwindStack(void * in)109 void SetUnwindStack(void *in) 110 { 111 unwindstack_ = reinterpret_cast<char *>(in); 112 } 113 GetUnwindStack()114 void *GetUnwindStack() const 115 { 116 return unwindstack_; 117 } 118 SetCrashConnect(void * in)119 void SetCrashConnect(void *in) 120 { 121 crashConnect_ = reinterpret_cast<char *>(in); 122 } 123 GetCrashConnect()124 void *GetCrashConnect() const 125 { 126 return crashConnect_; 127 } 128 SetMobileLog(void * mlogBufPrintPtr)129 void SetMobileLog(void *mlogBufPrintPtr) 130 { 131 mlogBufPrintPtr_ = mlogBufPrintPtr; 132 Logger::SetMobileLogPrintEntryPointByPtr(mlogBufPrintPtr); 133 } 134 SetForSnapShotStart()135 void SetForSnapShotStart() 136 { 137 shouldLoadBootPandaFiles_ = false; 138 shouldInitializeIntrinsics_ = false; 139 } 140 SetShouldLoadBootPandaFiles(bool value)141 void SetShouldLoadBootPandaFiles(bool value) 142 { 143 shouldLoadBootPandaFiles_ = value; 144 } 145 SetShouldInitializeIntrinsics(bool value)146 void SetShouldInitializeIntrinsics(bool value) 147 { 148 shouldInitializeIntrinsics_ = value; 149 } 150 UseMallocForInternalAllocations()151 bool UseMallocForInternalAllocations() const 152 { 153 bool useMalloc = false; 154 auto option = GetInternalAllocatorType(); 155 if (option == "default") { 156 #ifdef NDEBUG 157 useMalloc = true; 158 #else 159 useMalloc = false; 160 #endif 161 } else if (option == "malloc") { 162 useMalloc = true; 163 } else if (option == "panda_allocators") { 164 useMalloc = false; 165 } else { 166 UNREACHABLE(); 167 } 168 return useMalloc; 169 } 170 IsG1TrackFreedObjects()171 bool IsG1TrackFreedObjects() const 172 { 173 bool track = false; 174 auto option = GetG1TrackFreedObjects(); 175 if (option == "default") { 176 #ifdef NDEBUG 177 track = false; 178 #else 179 track = true; 180 #endif 181 } else if (option == "true") { 182 track = true; 183 } else if (option == "false") { 184 track = false; 185 } else { 186 UNREACHABLE(); 187 } 188 return track; 189 } 190 InitializeRuntimeSpacesAndType()191 void InitializeRuntimeSpacesAndType() 192 { 193 CheckAndFixIntrinsicSpaces(); 194 if (WasSetLoadRuntimes()) { 195 std::vector<std::string> loadRuntimes = GetLoadRuntimes(); 196 std::string runtimeType = "core"; 197 198 // Select first non-core runtime 199 for (auto &runtime : loadRuntimes) { 200 if (runtime != "core") { 201 runtimeType = runtime; 202 break; 203 } 204 } 205 206 SetRuntimeType(runtimeType); 207 SetBootClassSpaces(loadRuntimes); 208 SetBootIntrinsicSpaces(loadRuntimes); 209 } 210 } 211 212 private: 213 // Fix default value for possible missing plugins. CheckAndFixIntrinsicSpaces()214 void CheckAndFixIntrinsicSpaces() 215 { 216 bool intrSet = WasSetBootIntrinsicSpaces(); 217 std::vector<std::string> spaces = GetBootIntrinsicSpaces(); 218 for (auto it = spaces.begin(); it != spaces.end();) { 219 if (panda::plugins::HasRuntime(*it)) { 220 ++it; 221 continue; 222 } 223 224 if (intrSet) { 225 LOG(FATAL, RUNTIME) << "Missing runtime for intrinsic space " << *it; 226 } 227 it = spaces.erase(it); 228 } 229 230 SetBootIntrinsicSpaces(spaces); 231 } 232 233 bool shouldLoadBootPandaFiles_ {true}; 234 bool shouldInitializeIntrinsics_ {true}; 235 void *mlogBufPrintPtr_ {nullptr}; 236 std::string fingerPrint_ {"unknown"}; 237 void *unwindstack_ {nullptr}; 238 void *crashConnect_ {nullptr}; 239 VerificationMode verificationMode_ {VerificationMode::DISABLED}; 240 bool verifyRuntimeLibraries_ {false}; 241 }; 242 } // namespace panda 243 244 #endif // PANDA_RUNTIME_OPTIONS_H 245