• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)31 static inline bool IsEnabled(VerificationMode mode)
32 {
33     return mode != VerificationMode::DISABLED;
34 }
35 
VerificationModeFromString(const std::string & mode)36 static 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