• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 
16 #ifndef PANDA_RUNTIME_INCLUDE_RUNTIME_H_
17 #define PANDA_RUNTIME_INCLUDE_RUNTIME_H_
18 
19 #include <atomic>
20 #include <memory>
21 #include <string>
22 #include <signal.h>  // NOLINTNEXTLINE(modernize-deprecated-headers)
23 #include <vector>
24 
25 #include "libpandabase/mem/arena_allocator.h"
26 #include "libpandabase/os/mutex.h"
27 #include "libpandabase/os/library_loader.h"
28 #include "libpandabase/utils/expected.h"
29 #include "libpandabase/utils/dfx.h"
30 #include "libpandafile/file_items.h"
31 #include "libpandafile/literal_data_accessor.h"
32 #include "runtime/include/class_linker.h"
33 #include "runtime/include/mem/panda_smart_pointers.h"
34 #include "runtime/include/runtime_options.h"
35 #include "runtime/include/gc_task.h"
36 #include "runtime/include/tooling/debug_interface.h"
37 #include "runtime/signal_handler.h"
38 #include "runtime/mem/allocator_adapter.h"
39 #include "runtime/mem/gc/gc.h"
40 #include "runtime/mem/gc/gc_trigger.h"
41 #include "runtime/mem/memory_manager.h"
42 #include "runtime/monitor_pool.h"
43 #include "runtime/string_table.h"
44 #include "runtime/thread_manager.h"
45 #include "verification/verification_options.h"
46 
47 namespace panda {
48 
49 class DProfiler;
50 class ClassLinker;
51 class CompilerInterface;
52 class RuntimeController;
53 
54 class PandaVM;
55 class RuntimeNotificationManager;
56 class Trace;
57 
58 namespace tooling {
59 class PtLangExt;
60 class Debugger;
61 }  // namespace tooling
62 
63 class Runtime {
64 public:
65     using ExitHook = void (*)(int32_t status);
66     using AbortHook = void (*)();
67 
68     enum class Error {
69         PANDA_FILE_LOAD_ERROR,
70         INVALID_ENTRY_POINT,
71         CLASS_NOT_FOUND,
72         CLASS_NOT_INITIALIZED,
73         METHOD_NOT_FOUND,
74         CLASS_LINKER_EXTENSION_NOT_FOUND
75     };
76 
77     LanguageContext GetLanguageContext(const std::string &runtime_type);
78     LanguageContext GetLanguageContext(const Method &method);
79     LanguageContext GetLanguageContext(const Class &cls);
80     LanguageContext GetLanguageContext(const BaseClass &cls);
81     LanguageContext GetLanguageContext(panda_file::ClassDataAccessor *cda);
82     LanguageContext GetLanguageContext(panda_file::SourceLang lang);
83 
84     static bool CreateInstance(const RuntimeOptions &options, mem::InternalAllocatorPtr internal_allocator,
85                                const std::vector<LanguageContextBase *> &ctxs);
86 
87     PANDA_PUBLIC_API static bool Create(const RuntimeOptions &options,
88                                         const std::vector<LanguageContextBase *> &ctxs = {});
89 
90     static bool DestroyUnderLockHolder();
91 
92     PANDA_PUBLIC_API static bool Destroy();
93 
94     PANDA_PUBLIC_API static Runtime *GetCurrent();
95 
96     template <typename Handler>
GetCurrentSync(Handler && handler)97     static auto GetCurrentSync(Handler &&handler)
98     {
99         os::memory::LockHolder<os::memory::Mutex> lock(mutex);
100         return handler(*GetCurrent());
101     }
102 
GetClassLinker()103     ClassLinker *GetClassLinker() const
104     {
105         return class_linker_;
106     }
107 
GetNotificationManager()108     RuntimeNotificationManager *GetNotificationManager() const
109     {
110         return notification_manager_;
111     }
112 
GetOptions()113     static const RuntimeOptions &GetOptions()
114     {
115         return options_;
116     }
117 
SetZygoteNoThreadSection(bool val)118     void SetZygoteNoThreadSection(bool val)
119     {
120         zygote_no_threads_ = val;
121     }
122 
123     coretypes::String *ResolveString(PandaVM *vm, const Method &caller, panda_file::File::EntityId id);
124 
125     coretypes::String *ResolveString(PandaVM *vm, const panda_file::File &pf, panda_file::File::EntityId id,
126                                      LanguageContext ctx);
127 
128     coretypes::String *ResolveString(PandaVM *vm, const uint8_t *mutf8, uint32_t length, LanguageContext ctx);
129 
130     Class *GetClassRootForLiteralTag(const ClassLinkerExtension &ext, panda_file::LiteralTag tag) const;
131     static bool GetLiteralTagAndValue(const panda_file::File &pf, panda_file::File::EntityId id,
132                                       panda_file::LiteralTag *tag,
133                                       panda_file::LiteralDataAccessor::LiteralValue *value);
134 
135     coretypes::Array *ResolveLiteralArray(PandaVM *vm, const Method &caller, panda_file::File::EntityId id);
136 
137     coretypes::Array *ResolveLiteralArray(PandaVM *vm, const panda_file::File &pf, panda_file::File::EntityId id,
138                                           LanguageContext ctx);
139 
140     void PreZygoteFork();
141 
142     void PostZygoteFork();
143 
144     Expected<int, Error> ExecutePandaFile(std::string_view filename, std::string_view entry_point,
145                                           const std::vector<std::string> &args);
146 
147     int StartDProfiler(std::string_view app_name);
148 
149     Expected<int, Error> Execute(std::string_view entry_point, const std::vector<std::string> &args);
150 
151     int StartDProfiler(const PandaString &app_name);
152 
IsDebugMode()153     bool IsDebugMode() const
154     {
155         return is_debug_mode_;
156     }
157 
SetDebugMode(bool is_debug_mode)158     void SetDebugMode(bool is_debug_mode)
159     {
160         is_debug_mode_ = is_debug_mode;
161     }
162 
SetDebuggerLibrary(os::library_loader::LibraryHandle debugger_library)163     void SetDebuggerLibrary(os::library_loader::LibraryHandle debugger_library)
164     {
165         debugger_library_ = std::move(debugger_library);
166     }
167 
IsDebuggerConnected()168     bool IsDebuggerConnected() const
169     {
170         return is_debugger_connected_;
171     }
172 
SetDebuggerConnected(bool dbg_connected_state)173     void SetDebuggerConnected(bool dbg_connected_state)
174     {
175         is_debugger_connected_ = dbg_connected_state;
176     }
177 
178     PandaVector<PandaString> GetBootPandaFiles();
179 
180     PandaVector<PandaString> GetPandaFiles();
181 
182     // Additional VMInfo
183     void RegisterAppInfo(const PandaVector<PandaString> &code_paths, const PandaString &profile_output_filename);
184 
185     // Returns true if profile saving is enabled.
186     bool SaveProfileInfo() const;
187 
GetProcessPackageName()188     const std::string &GetProcessPackageName() const
189     {
190         return process_package_name_;
191     }
192 
SetProcessPackageName(const char * package_name)193     void SetProcessPackageName(const char *package_name)
194     {
195         if (package_name == nullptr) {
196             process_package_name_.clear();
197         } else {
198             process_package_name_ = package_name;
199         }
200     }
201 
GetProcessDataDirectory()202     const std::string &GetProcessDataDirectory() const
203     {
204         return process_data_directory_;
205     }
206 
SetProcessDataDirectory(const char * data_dir)207     void SetProcessDataDirectory(const char *data_dir)
208     {
209         if (data_dir == nullptr) {
210             process_data_directory_.clear();
211         } else {
212             process_data_directory_ = data_dir;
213         }
214     }
215 
GetPandaPath()216     std::string GetPandaPath()
217     {
218         return panda_path_string_;
219     }
220 
221     void UpdateProcessState(int state);
222 
IsZygote()223     bool IsZygote() const
224     {
225         return is_zygote_;
226     }
227 
IsInitialized()228     bool IsInitialized() const
229     {
230         return is_initialized_;
231     }
232 
GetVersion()233     static const char *GetVersion()
234     {
235         return "1.0.0";
236     }
237 
GetFingerprint()238     PandaString GetFingerprint()
239     {
240         return fingerPrint_;
241     }
242 
243     [[noreturn]] static void Halt(int32_t status);
244 
SetExitHook(ExitHook exit_hook)245     void SetExitHook(ExitHook exit_hook)
246     {
247         ASSERT(exit_ == nullptr);
248         exit_ = exit_hook;
249     }
250 
SetAbortHook(AbortHook abort_hook)251     void SetAbortHook(AbortHook abort_hook)
252     {
253         ASSERT(abort_ == nullptr);
254         abort_ = abort_hook;
255     }
256 
257     [[noreturn]] static void Abort(const char *message = nullptr);
258 
259     Expected<Method *, Error> ResolveEntryPoint(std::string_view entry_point);
260 
261     void RegisterSensitiveThread() const;
262 
GetPandaVM()263     PandaVM *GetPandaVM() const
264     {
265         return panda_vm_;
266     }
267 
GetPtLangExt()268     tooling::PtLangExt *GetPtLangExt() const
269     {
270         return pt_lang_ext_;
271     }
272 
GetVerificationOptions()273     const panda::verifier::VerificationOptions &GetVerificationOptions() const
274     {
275         return VerificationOptions_;
276     }
277 
GetVerificationOptions()278     panda::verifier::VerificationOptions &GetVerificationOptions()
279     {
280         return VerificationOptions_;
281     }
282 
283     void DumpForSigQuit(std::ostream &os);
284 
IsDumpNativeCrash()285     bool IsDumpNativeCrash()
286     {
287         return is_dump_native_crash_;
288     }
289 
IsChecksSuspend()290     bool IsChecksSuspend() const
291     {
292         return checks_suspend_;
293     }
294 
IsChecksStack()295     bool IsChecksStack() const
296     {
297         return checks_stack_;
298     }
299 
IsChecksNullptr()300     bool IsChecksNullptr() const
301     {
302         return checks_nullptr_;
303     }
304 
IsStacktrace()305     bool IsStacktrace() const
306     {
307         return is_stacktrace_;
308     }
309 
GetSignalManager()310     SignalManager *GetSignalManager()
311     {
312         return signal_manager_;
313     }
314 
315     Trace *CreateTrace(LanguageContext ctx, PandaUniquePtr<os::unix::file::File> trace_file, size_t buffer_size);
316 
317     void SetPtLangExt(tooling::PtLangExt *pt_lang_ext);
318 
319     static mem::GCType GetGCType(const RuntimeOptions &options);
320 
321     bool AttachDebugger();
322 
GetInternalAllocator()323     mem::InternalAllocatorPtr GetInternalAllocator() const
324     {
325         return internal_allocator_;
326     }
327 
328     PandaString GetMemoryStatistics();
329     PandaString GetFinalStatistics();
330 
331     Expected<LanguageContext, Error> ExtractLanguageContext(const panda_file::File *pf, std::string_view entry_point);
332 
333 private:
334     void NotifyAboutLoadedModules();
335 
336     std::optional<Error> CreateApplicationClassLinkerContext(std::string_view filename, std::string_view entry_point);
337 
338     bool LoadVerificationConfig();
339 
340     bool CreatePandaVM(std::string_view runtime_type);
341 
342     bool InitializePandaVM();
343 
344     bool CheckOptionsConsistency();
345 
346     void SetPandaPath();
347 
348     bool Initialize();
349 
350     bool Shutdown();
351 
352     bool LoadBootPandaFiles(panda_file::File::OpenMode open_mode);
353 
354     bool StartDebugger(const std::string &library_path);
355 
356     bool IsEnableMemoryHooks() const;
357 
358     static void CreateDfxController(const RuntimeOptions &options);
359 
360     static void BlockSignals();
361 
362     inline void InitializeVerificationResultCache(const RuntimeOptions &options);
363 
364     Runtime(const RuntimeOptions &options, mem::InternalAllocatorPtr internal_allocator,
365             const std::vector<LanguageContextBase *> &ctxs);
366 
367     ~Runtime();
368 
369     static Runtime *instance;
370     static RuntimeOptions options_;
371     static os::memory::Mutex mutex;
372 
373     mem::InternalAllocatorPtr internal_allocator_;
374     RuntimeNotificationManager *notification_manager_;
375     ClassLinker *class_linker_;
376     DProfiler *dprofiler_ = nullptr;
377 
378     PandaVM *panda_vm_ = nullptr;
379 
380     SignalManager *signal_manager_ {nullptr};
381 
382     // Language context
383     static constexpr size_t LANG_EXTENSIONS_COUNT = static_cast<size_t>(panda_file::SourceLang::LAST) + 1;
384     std::array<LanguageContextBase *, LANG_EXTENSIONS_COUNT> language_contexts_ {nullptr};
385 
386     // For IDE is really connected.
387     bool is_debug_mode_ {false};
388     bool is_debugger_connected_ {false};
389     tooling::PtLangExt *pt_lang_ext_ {nullptr};
390     tooling::DebugInterface *debugger_ {nullptr};
391     os::library_loader::LibraryHandle debugger_library_;
392 
393     // Additional VMInfo
394     std::string process_package_name_;
395     std::string process_data_directory_;
396 
397     // For saving class path.
398     std::string panda_path_string_;
399 
400     AbortHook abort_ = nullptr;
401     ExitHook exit_ = nullptr;
402 
403     bool zygote_no_threads_;
404     bool is_zygote_;
405     bool is_initialized_ {false};
406 
407     bool save_profiling_info_;
408 
409     bool checks_suspend_ {false};
410     bool checks_stack_ {true};
411     bool checks_nullptr_ {true};
412     bool is_stacktrace_ {false};
413 
414     bool is_dump_native_crash_ {true};
415 
416     PandaString fingerPrint_ = "unknown";
417 
418     // Verification
419     panda::verifier::VerificationOptions VerificationOptions_;
420 
421     struct AppContext {
422         ClassLinkerContext *ctx {nullptr};
423         std::optional<panda_file::SourceLang> lang;
424     };
425     AppContext app_context_ {};
426 
427     NO_COPY_SEMANTIC(Runtime);
428     NO_MOVE_SEMANTIC(Runtime);
429 };
430 
GetInternalAllocatorAdapter(const Runtime * runtime)431 inline mem::AllocatorAdapter<void> GetInternalAllocatorAdapter(const Runtime *runtime)
432 {
433     return runtime->GetInternalAllocator()->Adapter();
434 }
435 
436 void InitSignals();
437 
438 }  // namespace panda
439 
440 #endif  // PANDA_RUNTIME_INCLUDE_RUNTIME_H_
441