• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2024 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 ECMASCRIPT_ECMA_VM_H
17 #define ECMASCRIPT_ECMA_VM_H
18 
19 #include <mutex>
20 
21 #include "ecmascript/base/config.h"
22 #include "ecmascript/builtins/builtins_method_index.h"
23 #include "ecmascript/js_runtime_options.h"
24 #include "ecmascript/mem/c_containers.h"
25 #include "ecmascript/mem/c_string.h"
26 #include "ecmascript/mem/gc_stats.h"
27 #include "ecmascript/mem/gc_key_stats.h"
28 #include "ecmascript/mem/heap_region_allocator.h"
29 #include "ecmascript/napi/include/dfx_jsnapi.h"
30 #include "ecmascript/napi/include/jsnapi.h"
31 #include "ecmascript/taskpool/taskpool.h"
32 #include "libpandafile/bytecode_instruction-inl.h"
33 
34 namespace panda {
35 class JSNApi;
36 struct HmsMap;
37 namespace panda_file {
38 class File;
39 }  // namespace panda_file
40 
41 namespace ecmascript {
42 class GlobalEnv;
43 class ObjectFactory;
44 class RegExpParserCache;
45 class EcmaRuntimeStat;
46 class Heap;
47 class HeapTracker;
48 class JSNativePointer;
49 class Program;
50 class GCStats;
51 class GCKeyStats;
52 class CpuProfiler;
53 class Tracing;
54 class AsyncStackTrace;
55 class RegExpExecResultCache;
56 class JSPromise;
57 enum class PromiseRejectionEvent : uint8_t;
58 enum class Concurrent { YES, NO };
59 class JSPandaFileManager;
60 class JSPandaFile;
61 class EcmaStringTable;
62 class SnapshotEnv;
63 class SnapshotSerialize;
64 class SnapshotProcessor;
65 class JSThread;
66 
67 namespace pgo {
68     class PGOProfiler;
69 } // namespace pgo
70 
71 using PGOProfiler = pgo::PGOProfiler;
72 #if !WIN_OR_MAC_OR_IOS_PLATFORM
73 class HeapProfilerInterface;
74 class HeapProfiler;
75 #endif
76 namespace job {
77 class MicroJobQueue;
78 }  // namespace job
79 
80 namespace tooling {
81 class JsDebuggerManager;
82 }  // namespace tooling
83 
84 template<typename T>
85 class JSHandle;
86 class JSArrayBuffer;
87 class JSFunction;
88 class SourceTextModule;
89 class Program;
90 class AOTFileManager;
91 class SlowRuntimeStub;
92 class RequireManager;
93 class QuickFixManager;
94 class ConstantPool;
95 class FunctionCallTimer;
96 class EcmaStringTable;
97 class JSObjectResizingStrategy;
98 class Jit;
99 class JitThread;
100 enum class CompareStringsOption : uint8_t;
101 
102 using NativePtrGetter = void* (*)(void* info);
103 using SourceMapCallback = std::function<std::string(const std::string& rawStack)>;
104 using SourceMapTranslateCallback = std::function<bool(std::string& url, int& line, int& column,
105     std::string &packageName)>;
106 using ResolveBufferCallback =
107     std::function<bool(std::string dirPath, uint8_t **buff, size_t *buffSize, std::string &errorMsg)>;
108 using TimerCallbackFunc = void (*)(void *data);
109 using TimerTaskCallback = void* (*)(EcmaVM *vm, void *data, TimerCallbackFunc func, uint64_t timeout, bool repeat);
110 using CancelTimerCallback = void (*)(void *timerCallbackInfo);
111 using UnloadNativeModuleCallback = std::function<bool(const std::string &moduleKey)>;
112 using RequestAotCallback =
113     std::function<int32_t(const std::string &bundleName, const std::string &moduleName, int32_t triggerMode)>;
114 using SearchHapPathCallBack = std::function<bool(const std::string moduleName, std::string &hapPath)>;
115 using DeviceDisconnectCallback = std::function<bool()>;
116 using UncatchableErrorHandler = std::function<void(panda::TryCatch&)>;
117 using OnErrorCallback = std::function<void(Local<ObjectRef> value, void *data)>;
118 using StopPreLoadSoCallback = std::function<void()>;
119 
120 enum class IcuFormatterType: uint8_t {
121     SIMPLE_DATE_FORMAT_DEFAULT,
122     SIMPLE_DATE_FORMAT_DATE,
123     SIMPLE_DATE_FORMAT_TIME,
124     NUMBER_FORMATTER,
125     COLLATOR,
126     ICU_FORMATTER_TYPE_COUNT
127 };
128 
129 class IntlCache {
130 public:
131     IntlCache() = default;
132 
SetDefaultLocale(const std::string & locale)133     void SetDefaultLocale(const std::string& locale)
134     {
135         defaultLocale_ = locale;
136     }
137 
GetDefaultLocale()138     const std::string& GetDefaultLocale() const
139     {
140         return defaultLocale_;
141     }
142 
SetDefaultCompareStringsOption(const CompareStringsOption csOption)143     void SetDefaultCompareStringsOption(const CompareStringsOption csOption)
144     {
145         defaultCompareStringsOption_ = csOption;
146     }
147 
GetDefaultCompareStringsOption()148     std::optional<CompareStringsOption> GetDefaultCompareStringsOption() const
149     {
150         return defaultCompareStringsOption_;
151     }
152 
153     void SetIcuFormatterToCache(IcuFormatterType type, const std::string& locale, void* icuObj,
154                                 NativePointerCallback deleteEntry = nullptr)
155     {
156         icuObjCache_[static_cast<int>(type)] = IcuFormatter(locale, icuObj, deleteEntry);
157     }
158 
GetIcuFormatterFromCache(IcuFormatterType type,const std::string & locale)159     void* GetIcuFormatterFromCache(IcuFormatterType type, const std::string& locale) const
160     {
161         const auto& icuFormatter = icuObjCache_[static_cast<int>(type)];
162         return icuFormatter.locale == locale ? icuFormatter.icuObj : nullptr;
163     }
164 
ClearIcuCache(void * vmPtr)165     void ClearIcuCache(void* vmPtr)
166     {
167         for (uint32_t i = 0; i < static_cast<uint32_t>(IcuFormatterType::ICU_FORMATTER_TYPE_COUNT); ++i) {
168             auto& icuFormatter = icuObjCache_[i];
169             if (icuFormatter.deleteEntry != nullptr) {
170                 // Fill nullptr into the IcuDeleteEntry's unused env (specifically for napi) field.
171                 icuFormatter.deleteEntry(nullptr, icuFormatter.icuObj, vmPtr);
172             }
173         }
174     }
175 
176 private:
177     class IcuFormatter {
178     public:
179         std::string locale;
180         void* icuObj {nullptr};
181         NativePointerCallback deleteEntry {nullptr};
182 
183         IcuFormatter() = default;
184         IcuFormatter(const std::string& locale, void* icuObj, NativePointerCallback deleteEntry = nullptr)
locale(locale)185             : locale(locale), icuObj(icuObj), deleteEntry(deleteEntry) {}
186     };
187 
188     std::string defaultLocale_;
189     std::optional<CompareStringsOption> defaultCompareStringsOption_ {std::nullopt};
190     IcuFormatter icuObjCache_[static_cast<uint32_t>(IcuFormatterType::ICU_FORMATTER_TYPE_COUNT)];
191 };
192 
193 class EcmaVM {
194 public:
195     static EcmaVM *Create(const JSRuntimeOptions &options);
196 
197     static bool Destroy(EcmaVM *vm);
198 
199     EcmaVM(JSRuntimeOptions options, EcmaParamConfiguration config);
200 
201     EcmaVM();
202 
203     ~EcmaVM();
204 
SetLoop(void * loop)205     void SetLoop(void *loop)
206     {
207         loop_ = loop;
208     }
209 
GetLoop()210     void *GetLoop() const
211     {
212         return loop_;
213     }
214 
IsInitialized()215     bool IsInitialized() const
216     {
217         return initialized_;
218     }
219 
SetPostForked(bool isPostForked)220     void SetPostForked(bool isPostForked)
221     {
222         isPostForked_ = isPostForked;
223     }
224 
IsPostForked()225     bool IsPostForked() const
226     {
227         return isPostForked_;
228     }
229 
SetAgentCanSuspend(bool agentCanSuspend)230     void SetAgentCanSuspend(bool agentCanSuspend)
231     {
232         agentCanSuspend_ = agentCanSuspend;
233     }
234 
GetAgentCanSuspend()235     bool GetAgentCanSuspend() const
236     {
237         return agentCanSuspend_;
238     }
239 
IsAsynTranslateClasses()240     bool IsAsynTranslateClasses()
241     {
242         if (!GetJSOptions().IsAsyncLoadAbcTest()) {
243             return IsPostForked() && GetJSOptions().IsAsyncLoadAbc();
244         }
245         return GetJSOptions().IsAsyncLoadAbc();
246     }
247 
GetFactory()248     ObjectFactory *GetFactory() const
249     {
250         return factory_;
251     }
252 
253     void InitializePGOProfiler();
254     void ResetPGOProfiler();
255     void DisablePGOProfilerWithAOTFile(const std::string &aotFileName);
256 
257     bool PUBLIC_API IsEnablePGOProfiler() const;
258     bool PUBLIC_API IsEnableMutantArray() const;
259     bool PUBLIC_API IsEnableElementsKind() const;
260 
261     bool Initialize();
262     void InitializeForJit(JitThread *thread);
263 
GetEcmaGCStats()264     GCStats *GetEcmaGCStats() const
265     {
266         return gcStats_;
267     }
268 
GetEcmaGCKeyStats()269     GCKeyStats *GetEcmaGCKeyStats() const
270     {
271         return gcKeyStats_;
272     }
273 
GetAssociatedJSThread()274     JSThread *GetAssociatedJSThread() const
275     {
276         return thread_;
277     }
278 
GetJSOptions()279     JSRuntimeOptions &GetJSOptions()
280     {
281         return options_;
282     }
283 
GetEcmaParamConfiguration()284     const EcmaParamConfiguration &GetEcmaParamConfiguration() const
285     {
286         return ecmaParamConfiguration_;
287     }
288 
289     JSHandle<GlobalEnv> PUBLIC_API GetGlobalEnv() const;
290 
ConstCast(const EcmaVM * vm)291     static EcmaVM *ConstCast(const EcmaVM *vm)
292     {
293         return const_cast<EcmaVM *>(vm);
294     }
295 
296     void PUBLIC_API CheckThread() const;
297     JSThread *GetAndFastCheckJSThread() const;
298     bool CheckSingleThread() const;
299 
GetThreadCheckStatus()300     ARK_INLINE bool GetThreadCheckStatus() const
301     {
302         return options_.EnableThreadCheck() || EcmaVM::GetMultiThreadCheck();
303     }
304 
GetJSThread()305     ARK_INLINE JSThread *GetJSThread() const
306     {
307         // default enable multi-thread check in asan
308 #ifdef ECMASCRIPT_ENABLE_ASAN_THREAD_CHECK
309         CheckThread();
310 #else
311         if (GetThreadCheckStatus()) {
312             CheckThread();
313         }
314 #endif
315         return thread_;
316     }
317 
GetJSThreadNoCheck()318     JSThread *GetJSThreadNoCheck() const
319     {
320         return thread_;
321     }
322 
ICEnabled()323     bool ICEnabled() const
324     {
325         return icEnabled_;
326     }
327 
328     void PushToNativePointerList(JSNativePointer *pointer, Concurrent isConcurrent = Concurrent::NO);
329     void RemoveFromNativePointerList(JSNativePointer *pointer);
330     void PushToDeregisterModuleList(const CString &module);
331     void RemoveFromDeregisterModuleList(CString module);
332     bool ContainInDeregisterModuleList(CString module);
333     JSHandle<ecmascript::JSTaggedValue> GetAndClearEcmaUncaughtException() const;
334     JSHandle<ecmascript::JSTaggedValue> GetEcmaUncaughtException() const;
335 
GetRuntimeStat()336     EcmaRuntimeStat *GetRuntimeStat() const
337     {
338         return runtimeStat_;
339     }
340 
341     void InitializeEcmaScriptRunStat();
342     void SetRuntimeStatEnable(bool flag);
343 
IsOptionalLogEnabled()344     bool IsOptionalLogEnabled() const
345     {
346         return optionalLogEnabled_;
347     }
348 
349     void Iterate(RootVisitor &v, VMRootVisitType type);
350 
GetHeap()351     const Heap *GetHeap() const
352     {
353         return heap_;
354     }
355     void CollectGarbage(TriggerGCType gcType, GCReason reason = GCReason::OTHER) const;
356 
GetNativeAreaAllocator()357     NativeAreaAllocator *GetNativeAreaAllocator() const
358     {
359         return nativeAreaAllocator_.get();
360     }
361 
GetHeapRegionAllocator()362     HeapRegionAllocator *GetHeapRegionAllocator() const
363     {
364         return heapRegionAllocator_.get();
365     }
366 
GetChunk()367     Chunk *GetChunk() const
368     {
369         return const_cast<Chunk *>(&chunk_);
370     }
371     void ProcessNativeDelete(const WeakRootVisitor &visitor);
372     void ProcessReferences(const WeakRootVisitor &visitor);
373 
GetAsyncStackTrace()374     AsyncStackTrace *GetAsyncStackTrace() const
375     {
376         return asyncStackTrace_;
377     }
378 
379     uint32_t GetAsyncTaskId();
380 
381     bool InsertAsyncStackTrace(const JSHandle<JSPromise> &promise);
382 
383     bool RemoveAsyncStackTrace(const JSHandle<JSPromise> &promise);
384 
GetSnapshotEnv()385     SnapshotEnv *GetSnapshotEnv() const
386     {
387         return snapshotEnv_;
388     }
389 
GetJsDebuggerManager()390     tooling::JsDebuggerManager *GetJsDebuggerManager() const
391     {
392         return debuggerManager_;
393     }
394 
SetDeviceDisconnectCallback(DeviceDisconnectCallback cb)395     void SetDeviceDisconnectCallback(DeviceDisconnectCallback cb)
396     {
397         deviceDisconnectCallback_ = cb;
398     }
399 
GetDeviceDisconnectCallback()400     DeviceDisconnectCallback GetDeviceDisconnectCallback() const
401     {
402         return deviceDisconnectCallback_;
403     }
404 
SetEnableForceGC(bool enable)405     void SetEnableForceGC(bool enable)
406     {
407         options_.SetEnableForceGC(enable);
408     }
409 
SetNativePtrGetter(NativePtrGetter cb)410     void SetNativePtrGetter(NativePtrGetter cb)
411     {
412         nativePtrGetter_ = cb;
413     }
414 
GetNativePtrGetter()415     NativePtrGetter GetNativePtrGetter() const
416     {
417         return nativePtrGetter_;
418     }
419 
SetSourceMapCallback(SourceMapCallback cb)420     void SetSourceMapCallback(SourceMapCallback cb)
421     {
422         sourceMapCallback_ = cb;
423     }
424 
GetSourceMapCallback()425     SourceMapCallback GetSourceMapCallback() const
426     {
427         return sourceMapCallback_;
428     }
429 
SetSourceMapTranslateCallback(SourceMapTranslateCallback cb)430     void SetSourceMapTranslateCallback(SourceMapTranslateCallback cb)
431     {
432         sourceMapTranslateCallback_ = cb;
433     }
434 
GetSourceMapTranslateCallback()435     SourceMapTranslateCallback GetSourceMapTranslateCallback() const
436     {
437         return sourceMapTranslateCallback_;
438     }
439 
SetResolveBufferCallback(ResolveBufferCallback cb)440     void SetResolveBufferCallback(ResolveBufferCallback cb)
441     {
442         resolveBufferCallback_ = cb;
443     }
444 
GetResolveBufferCallback()445     ResolveBufferCallback GetResolveBufferCallback() const
446     {
447         return resolveBufferCallback_;
448     }
449 
SetTimerTaskCallback(TimerTaskCallback callback)450     void SetTimerTaskCallback(TimerTaskCallback callback)
451     {
452         timerTaskCallback_ = callback;
453     }
454 
GetTimerTaskCallback()455     TimerTaskCallback GetTimerTaskCallback() const
456     {
457         return timerTaskCallback_;
458     }
459 
SetCancelTimerCallback(CancelTimerCallback callback)460     void SetCancelTimerCallback(CancelTimerCallback callback)
461     {
462         cancelTimerCallback_ = callback;
463     }
464 
GetCancelTimerCallback()465     CancelTimerCallback GetCancelTimerCallback() const
466     {
467         return cancelTimerCallback_;
468     }
469 
SetSearchHapPathCallBack(SearchHapPathCallBack cb)470     void SetSearchHapPathCallBack(SearchHapPathCallBack cb)
471     {
472         SearchHapPathCallBack_ = cb;
473     }
474 
GetSearchHapPathCallBack()475     SearchHapPathCallBack GetSearchHapPathCallBack() const
476     {
477         return SearchHapPathCallBack_;
478     }
479 
SetUnloadNativeModuleCallback(const UnloadNativeModuleCallback & cb)480     void SetUnloadNativeModuleCallback(const UnloadNativeModuleCallback &cb)
481     {
482         unloadNativeModuleCallback_ = cb;
483     }
484 
GetUnloadNativeModuleCallback()485     UnloadNativeModuleCallback GetUnloadNativeModuleCallback() const
486     {
487         return unloadNativeModuleCallback_;
488     }
489 
SetConcurrentCallback(ConcurrentCallback callback,void * data)490     void SetConcurrentCallback(ConcurrentCallback callback, void *data)
491     {
492         concurrentCallback_ = callback;
493         concurrentData_ = data;
494     }
495 
SetOnErrorCallback(OnErrorCallback callback,void * data)496     void SetOnErrorCallback(OnErrorCallback callback, void* data)
497     {
498         onErrorCallback_ = callback;
499         onErrorData_ = data;
500     }
501 
GetOnErrorCallback()502     OnErrorCallback GetOnErrorCallback()
503     {
504         return onErrorCallback_;
505     }
506 
GetOnAllData()507     void* GetOnAllData()
508     {
509         return onErrorData_;
510     }
511 
AddStopPreLoadCallback(const StopPreLoadSoCallback & cb)512     void AddStopPreLoadCallback(const StopPreLoadSoCallback &cb)
513     {
514         stopPreLoadCallbacks_.emplace_back(cb);
515     }
516 
GetStopPreLoadCallbacks()517     CVector<StopPreLoadSoCallback> GetStopPreLoadCallbacks() const
518     {
519         return stopPreLoadCallbacks_;
520     }
521 
522     void StopPreLoadSoOrAbc();
523 
524     void TriggerConcurrentCallback(JSTaggedValue result, JSTaggedValue hint);
525 
526     void WorkersetInfo(EcmaVM *workerVm);
527 
528     EcmaVM *GetWorkerVm(uint32_t tid);
529 
530     bool DeleteWorker(EcmaVM *workerVm);
531 
532     bool SuspendWorkerVm(uint32_t tid);
533 
534     void ResumeWorkerVm(uint32_t tid);
535 
536     template<typename Callback>
EnumerateWorkerVm(Callback cb)537     void EnumerateWorkerVm(Callback cb)
538     {
539         // since there is a lock, so cannot mark function const
540         LockHolder lock(mutex_);
541         for (const auto &item : workerList_) {
542             cb(item.second);
543         }
544     }
545 
IsWorkerThread()546     bool IsWorkerThread() const
547     {
548         return options_.IsWorker();
549     }
550 
IsRestrictedWorkerThread()551     bool IsRestrictedWorkerThread() const
552     {
553         return options_.IsRestrictedWorker();
554     }
555 
IsBundlePack()556     bool IsBundlePack() const
557     {
558         return isBundlePack_;
559     }
560 
SetIsBundlePack(bool value)561     void SetIsBundlePack(bool value)
562     {
563         isBundlePack_ = value;
564     }
565 
566     // UnifiedOhmUrlPack means app compiles ohmurl using old format like "@bundle:",
567     // or new unified rules like "@normalize:"
568     // if pkgContextInfoList is empty, means use old ohmurl packing.
IsNormalizedOhmUrlPack()569     bool IsNormalizedOhmUrlPack()
570     {
571         ReadLockHolder lock(pkgContextInfoLock_);
572         return !pkgContextInfoList_.empty();
573     }
574 
SetPkgNameList(const CMap<CString,CString> & list)575     void SetPkgNameList(const CMap<CString, CString> &list)
576     {
577         WriteLockHolder lock(pkgNameListLock_);
578         pkgNameList_ = list;
579     }
580 
UpdatePkgNameList(const CMap<CString,CString> & list)581     void UpdatePkgNameList(const CMap<CString, CString> &list)
582     {
583         WriteLockHolder lock(pkgNameListLock_);
584         pkgNameList_.insert(list.begin(), list.end());
585     }
586 
GetPkgNameList()587     CMap<CString, CString> GetPkgNameList()
588     {
589         ReadLockHolder lock(pkgNameListLock_);
590         return pkgNameList_;
591     }
592 
GetPkgName(const CString & moduleName)593     inline CString GetPkgName(const CString &moduleName)
594     {
595         ReadLockHolder lock(pkgNameListLock_);
596         auto it = pkgNameList_.find(moduleName);
597         if (it == pkgNameList_.end()) {
598             LOG_ECMA(INFO) << " Get Pkg Name failed";
599             return moduleName;
600         }
601         return it->second;
602     }
603 
UpdatePkgContextInfoList(const CMap<CString,CMap<CString,CVector<CString>>> & list)604     void UpdatePkgContextInfoList(const CMap<CString, CMap<CString, CVector<CString>>> &list)
605     {
606         WriteLockHolder lock(pkgContextInfoLock_);
607         pkgContextInfoList_.insert(list.begin(), list.end());
608     }
609 
GetPkgContextInfoList()610     inline CMap<CString, CMap<CString, CVector<CString>>> GetPkgContextInfoList()
611     {
612         ReadLockHolder lock(pkgContextInfoLock_);
613         return pkgContextInfoList_;
614     }
615 
GetPkgNameWithAlias(const CString & alias)616     inline CString GetPkgNameWithAlias(const CString &alias)
617     {
618         ReadLockHolder lock(pkgAliasListLock_);
619         auto it = pkgAliasList_.find(alias);
620         if (it == pkgAliasList_.end()) {
621             return alias;
622         }
623         return it->second;
624     }
625 
SetPkgAliasList(const CMap<CString,CString> & list)626     void SetPkgAliasList(const CMap<CString, CString> &list)
627     {
628         WriteLockHolder lock(pkgAliasListLock_);
629         pkgAliasList_ = list;
630     }
631 
UpdatePkgAliasList(const CMap<CString,CString> & list)632     void UpdatePkgAliasList(const CMap<CString, CString> &list)
633     {
634         WriteLockHolder lock(pkgAliasListLock_);
635         pkgAliasList_.insert(list.begin(), list.end());
636     }
637 
GetPkgAliasList()638     CMap<CString, CString> GetPkgAliasList()
639     {
640         ReadLockHolder lock(pkgAliasListLock_);
641         return pkgAliasList_;
642     }
643 
SetMockModuleList(const std::map<std::string,std::string> & list)644     void SetMockModuleList(const std::map<std::string, std::string> &list)
645     {
646         for (auto it = list.begin(); it != list.end(); ++it) {
647             mockModuleList_.emplace(it->first.c_str(), it->second.c_str());
648         }
649     }
650 
IsMockModule(const CString & moduleStr)651     inline bool IsMockModule(const CString &moduleStr) const
652     {
653         if (mockModuleList_.empty()) {
654             return false;
655         }
656         auto it = mockModuleList_.find(moduleStr);
657         if (it == mockModuleList_.end()) {
658             return false;
659         }
660         return true;
661     }
662 
GetMockModule(const CString & module)663     inline CString GetMockModule(const CString &module) const
664     {
665         auto it = mockModuleList_.find(module);
666         if (it == mockModuleList_.end()) {
667             LOG_ECMA(FATAL) << " Get Mock Module failed";
668         }
669         return it->second;
670     }
671 
672 #if defined(ECMASCRIPT_SUPPORT_HEAPPROFILER)
673     void DeleteHeapProfile();
674     HeapProfilerInterface *GetHeapProfile();
SetHeapProfile(HeapProfilerInterface * heapProfile)675     void  SetHeapProfile(HeapProfilerInterface *heapProfile) { heapProfile_ = heapProfile; }
676     HeapProfilerInterface *GetOrNewHeapProfile();
677     void StartHeapTracking();
678     void StopHeapTracking();
679 #endif
680 
SetAssetPath(const CString & assetPath)681     void SetAssetPath(const CString &assetPath)
682     {
683         assetPath_ = assetPath;
684     }
685 
GetAssetPath()686     CString GetAssetPath() const
687     {
688         return assetPath_;
689     }
690 
SetBundleName(const CString & bundleName)691     void SetBundleName(const CString &bundleName)
692     {
693         bundleName_ = bundleName;
694     }
695 
GetBundleName()696     CString GetBundleName() const
697     {
698         return bundleName_;
699     }
700 
SetModuleName(const CString & moduleName)701     void SetModuleName(const CString &moduleName)
702     {
703         moduleName_ = moduleName;
704     }
705 
GetModuleName()706     CString GetModuleName() const
707     {
708         return moduleName_;
709     }
710 
711     std::pair<std::string, std::string> GetCurrentModuleInfo(bool needRecordName = false);
712 
713     void SetHmsModuleList(const std::vector<panda::HmsMap> &list);
714 
715     bool IsHmsModule(const CString &moduleStr) const;
716 
717     CString GetHmsModule(const CString &module) const;
718 
719     void SetpkgContextInfoList(const CMap<CString, CMap<CString, CVector<CString>>> &list);
720 
721 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
GetProfiler()722     CpuProfiler *GetProfiler() const
723     {
724         return profiler_;
725     }
726 
SetProfiler(CpuProfiler * profiler)727     void SetProfiler(CpuProfiler *profiler)
728     {
729         profiler_ = profiler;
730     }
731 #endif
732 
733 #if defined(ECMASCRIPT_SUPPORT_TRACING)
GetTracing()734     Tracing *GetTracing() const
735     {
736         return tracing_;
737     }
738 
SetTracing(Tracing * tracing)739     void SetTracing(Tracing *tracing)
740     {
741         tracing_ = tracing;
742     }
743 #endif
744 
GetPGOProfiler()745     std::shared_ptr<PGOProfiler> GetPGOProfiler() const
746     {
747         return pgoProfiler_;
748     }
749 
750     void PreFork();
751     void PostFork();
752 
753     // For Internal Native MethodLiteral.
754     JSTaggedValue GetMethodByIndex(MethodIndex idx);
755 
GetQuickFixManager()756     QuickFixManager *GetQuickFixManager() const
757     {
758         return quickFixManager_;
759     }
760 
761     JSTaggedValue FastCallAot(size_t actualNumArgs, JSTaggedType *args, const JSTaggedType *prevFp);
762 
RegisterUncatchableErrorHandler(const UncatchableErrorHandler & uncatchableErrorHandler)763     void RegisterUncatchableErrorHandler(const UncatchableErrorHandler &uncatchableErrorHandler)
764     {
765         uncatchableErrorHandler_ = uncatchableErrorHandler;
766     }
767 
768     // handle uncatchable errors, such as oom
HandleUncatchableError()769     void HandleUncatchableError()
770     {
771         if (uncatchableErrorHandler_ != nullptr) {
772             panda::TryCatch trycatch(this);
773             uncatchableErrorHandler_(trycatch);
774         }
775         LOG_ECMA_MEM(FATAL) << "Out of Memory";
776     }
777 
778     void DumpCallTimeInfo();
779 
GetCallTimer()780     FunctionCallTimer *GetCallTimer() const
781     {
782         return callTimer_;
783     }
784 
GetEcmaStringTable()785     EcmaStringTable *GetEcmaStringTable() const
786     {
787         ASSERT(stringTable_ != nullptr);
788         return stringTable_;
789     }
790 
IncreaseCallDepth()791     void IncreaseCallDepth()
792     {
793         callDepth_++;
794     }
795 
DecreaseCallDepth()796     void DecreaseCallDepth()
797     {
798         ASSERT(callDepth_ > 0);
799         callDepth_--;
800     }
801 
IsTopLevelCallDepth()802     bool IsTopLevelCallDepth()
803     {
804         return callDepth_ == 0;
805     }
806 
SetProfilerState(bool state)807     void SetProfilerState(bool state)
808     {
809         isProfiling_ = state;
810     }
811 
GetProfilerState()812     bool GetProfilerState()
813     {
814         return isProfiling_;
815     }
816 
GetJSObjectResizingStrategy()817     JSObjectResizingStrategy *GetJSObjectResizingStrategy()
818     {
819         return strategy_;
820     }
821 
GetWorkList()822     CMap<uint32_t, EcmaVM *> GetWorkList() const
823     {
824         return workerList_;
825     }
826 
GetProcessStartRealtime()827     int GetProcessStartRealtime() const
828     {
829         return processStartRealtime_;
830     }
831 
SetProcessStartRealtime(int value)832     void SetProcessStartRealtime(int value)
833     {
834         processStartRealtime_ = value;
835     }
836 
837     Jit *GetJit() const;
838     bool PUBLIC_API IsEnableFastJit() const;
839     bool PUBLIC_API IsEnableBaselineJit() const;
840 
IsEnableOsr()841     bool IsEnableOsr() const
842     {
843         return isEnableOsr_;
844     }
845 
SetEnableOsr(bool state)846     void SetEnableOsr(bool state)
847     {
848         isEnableOsr_ = state;
849     }
850 
GetAOTFileManager()851     AOTFileManager *GetAOTFileManager() const
852     {
853         return aotFileManager_;
854     }
855 
856     uint32_t GetTid() const;
857 
GetConcurrentNativePointerCallbacks()858     std::vector<NativePointerCallbackData> &GetConcurrentNativePointerCallbacks()
859     {
860         return concurrentNativeCallbacks_;
861     }
862 
GetAsyncNativePointerCallbacksPack()863     AsyncNativeCallbacksPack &GetAsyncNativePointerCallbacksPack()
864     {
865         return asyncNativeCallbacksPack_;
866     }
867 
SetIsJitCompileVM(bool isJitCompileVM)868     void SetIsJitCompileVM(bool isJitCompileVM)
869     {
870         isJitCompileVM_ = isJitCompileVM;
871     }
872 
IsJitCompileVM()873     bool IsJitCompileVM() const
874     {
875         return isJitCompileVM_;
876     }
877 
SetMultiThreadCheck(bool multiThreadCheck)878     static void SetMultiThreadCheck(bool multiThreadCheck)
879     {
880         multiThreadCheck_ = multiThreadCheck;
881     }
882 
GetMultiThreadCheck()883     PUBLIC_API static bool GetMultiThreadCheck()
884     {
885         return multiThreadCheck_;
886     }
887 
SetErrorInfoEnhance(bool errorInfoEnhance)888     static void SetErrorInfoEnhance(bool errorInfoEnhance)
889     {
890         errorInfoEnhanced_ = errorInfoEnhance;
891     }
892 
GetErrorInfoEnhance()893     static bool GetErrorInfoEnhance()
894     {
895         return errorInfoEnhanced_;
896     }
897 
898     static void InitializeIcuData(const JSRuntimeOptions &options);
899 
900     static int InitializeStartRealTime();
901 
902 #if ECMASCRIPT_ENABLE_SCOPE_LOCK_STAT
ResetScopeLockStats()903     void ResetScopeLockStats()
904     {
905         enterThreadManagedScopeCount_ = 0;
906         enterJsiNativeScopeCount_ = 0;
907         enterFastNativeScopeCount_ = 0;
908         updateThreadStateTransCount_ = 0;
909         stringTableLockCount_ = 0;
910     }
911 
IsCollectingScopeLockStats()912     bool IsCollectingScopeLockStats() const
913     {
914         return isCollectingScopeLockStats_;
915     }
916 
StartCollectingScopeLockStats()917     void StartCollectingScopeLockStats()
918     {
919         isCollectingScopeLockStats_ = true;
920     }
921 
StopCollectingScopeLockStats()922     void StopCollectingScopeLockStats()
923     {
924         isCollectingScopeLockStats_ = false;
925     }
926 
GetEnterThreadManagedScopeCount()927     int GetEnterThreadManagedScopeCount() const
928     {
929         return enterThreadManagedScopeCount_;
930     }
931 
IncreaseEnterThreadManagedScopeCount()932     void IncreaseEnterThreadManagedScopeCount()
933     {
934         enterThreadManagedScopeCount_++;
935     }
936 
GetEnterFastNativeScopeCount()937     int GetEnterFastNativeScopeCount() const
938     {
939         return enterFastNativeScopeCount_;
940     }
941 
IncreaseEnterFastNativeScopeCount()942     void IncreaseEnterFastNativeScopeCount()
943     {
944         enterFastNativeScopeCount_++;
945     }
946 
GetEnterJsiNativeScopeCount()947     int GetEnterJsiNativeScopeCount() const
948     {
949         return enterJsiNativeScopeCount_;
950     }
951 
IncreaseEnterJsiNativeScopeCount()952     void IncreaseEnterJsiNativeScopeCount()
953     {
954         enterJsiNativeScopeCount_++;
955     }
956 
GetUpdateThreadStateTransCount()957     int GetUpdateThreadStateTransCount() const
958     {
959         return updateThreadStateTransCount_;
960     }
961 
IncreaseUpdateThreadStateTransCount()962     void IncreaseUpdateThreadStateTransCount()
963     {
964         updateThreadStateTransCount_++;
965     }
966 
GetStringTableLockCount()967     int GetStringTableLockCount() const
968     {
969         return stringTableLockCount_;
970     }
971 
IncreaseStringTableLockCount()972     void IncreaseStringTableLockCount()
973     {
974         stringTableLockCount_++;
975     }
976 #endif
977 
GetEnableJitLogSkip()978     bool GetEnableJitLogSkip() const
979     {
980         return enableJitLogSkip_;
981     }
982 
SetEnableJitLogSkip(bool flag)983     void SetEnableJitLogSkip(bool flag)
984     {
985         enableJitLogSkip_ = flag;
986     }
987 
988     void AddAOTSnapShotStats(std::string tag, uint32_t count = 1)
989     {
990         aotSnapShotStatsMap_[tag] += count;
991     }
992 
GetIntlCache()993     IntlCache& GetIntlCache()
994     {
995         return intlCache_;
996     }
997 
998     void PUBLIC_API PrintAOTSnapShotStats();
999 
SetVMAPIVersion(uint32_t APIVersion)1000     void SetVMAPIVersion(uint32_t APIVersion)
1001     {
1002         apiVersion_ = APIVersion;
1003     }
1004 
GetVMAPIVersion()1005     uint32_t GetVMAPIVersion()
1006     {
1007         return apiVersion_;
1008     }
1009 
1010 #if ECMASCRIPT_ENABLE_COLLECTING_OPCODES
SetBytecodeStatsStack(std::unordered_map<BytecodeInstruction::Opcode,int> & bytecodeStatsMap)1011     void SetBytecodeStatsStack(std::unordered_map<BytecodeInstruction::Opcode, int> &bytecodeStatsMap)
1012     {
1013         bytecodeStatsStack_.push(bytecodeStatsMap);
1014     }
1015 
GetBytecodeStatsStack()1016     std::stack<std::unordered_map<BytecodeInstruction::Opcode, int>>& GetBytecodeStatsStack()
1017     {
1018         return bytecodeStatsStack_;
1019     }
1020 
1021     void PrintCollectedByteCode();
1022 #endif
1023 
1024 protected:
1025 
1026     void PrintJSErrorInfo(const JSHandle<JSTaggedValue> &exceptionInfo) const;
1027 
1028 private:
1029     void ClearBufferData();
1030     void CheckStartCpuProfiler();
1031 
1032     // For Internal Native MethodLiteral.
1033     void GenerateInternalNativeMethods();
1034     void CacheToGlobalConstants(JSTaggedValue value, ConstantIndex constant);
1035 
1036     NO_MOVE_SEMANTIC(EcmaVM);
1037     NO_COPY_SEMANTIC(EcmaVM);
1038 
1039     // VM startup states.
1040     JSRuntimeOptions options_;
1041     bool icEnabled_ {true};
1042     bool initialized_ {false};
1043     bool isPostForked_ {false};
1044     bool agentCanSuspend_ {true};
1045     GCStats *gcStats_ {nullptr};
1046     GCKeyStats *gcKeyStats_ {nullptr};
1047     EcmaStringTable *stringTable_ {nullptr};
1048     PUBLIC_API static bool multiThreadCheck_;
1049     static bool errorInfoEnhanced_;
1050 
1051     //apiVersion states
1052     uint32_t apiVersion_ = 8;
1053 
1054     // VM memory management.
1055     std::unique_ptr<NativeAreaAllocator> nativeAreaAllocator_;
1056     std::unique_ptr<HeapRegionAllocator> heapRegionAllocator_;
1057     Chunk chunk_;
1058     Heap *heap_ {nullptr};
1059     ObjectFactory *factory_ {nullptr};
1060 
1061     std::vector<NativePointerCallbackData> concurrentNativeCallbacks_ {};
1062     AsyncNativeCallbacksPack asyncNativeCallbacksPack_ {};
1063     // VM execution states.
1064     JSThread *thread_ {nullptr};
1065 
1066     EcmaRuntimeStat *runtimeStat_ {nullptr};
1067 
1068     CUnorderedMap<std::string, uint32_t> aotSnapShotStatsMap_;
1069 
1070     // VM resources.
1071     SnapshotEnv *snapshotEnv_ {nullptr};
1072     bool optionalLogEnabled_ {false};
1073     // Debugger
1074     tooling::JsDebuggerManager *debuggerManager_ {nullptr};
1075 
1076     // DFX
1077     AsyncStackTrace *asyncStackTrace_ {nullptr};
1078 
1079     // isBundle means app compile mode is JSBundle
1080     bool isBundlePack_ {true};
1081 #if !WIN_OR_MAC_OR_IOS_PLATFORM
1082     HeapProfilerInterface *heapProfile_ {nullptr};
1083 #endif
1084     CString assetPath_;
1085     CString bundleName_;
1086     CString moduleName_;
1087     CList<CString> deregisterModuleList_;
1088     CMap<CString, CString> mockModuleList_;
1089     std::map<CString, HmsMap> hmsModuleList_;
1090     CMap<CString, CString> pkgNameList_;
1091     CMap<CString, CMap<CString, CVector<CString>>> pkgContextInfoList_;
1092     CMap<CString, CString> pkgAliasList_;
1093     RWLock pkgContextInfoLock_;
1094     RWLock pkgAliasListLock_;
1095     RWLock pkgNameListLock_;
1096 
1097     CVector<StopPreLoadSoCallback> stopPreLoadCallbacks_;
1098     NativePtrGetter nativePtrGetter_ {nullptr};
1099     SourceMapCallback sourceMapCallback_ {nullptr};
1100     SourceMapTranslateCallback sourceMapTranslateCallback_ {nullptr};
1101     void *loop_ {nullptr};
1102 
1103     // resolve path to get abc's buffer
1104     ResolveBufferCallback resolveBufferCallback_ {nullptr};
1105 
1106     // set timer task to execute callback on time
1107     TimerTaskCallback timerTaskCallback_ {nullptr};
1108     // set cancel timer task to execute callback on time
1109     CancelTimerCallback cancelTimerCallback_ {nullptr};
1110 
1111     // delete the native module and dlclose so from NativeModuleManager
1112     UnloadNativeModuleCallback unloadNativeModuleCallback_ {nullptr};
1113 
1114     // Concurrent taskpool callback and data
1115     ConcurrentCallback concurrentCallback_ {nullptr};
1116     void *concurrentData_ {nullptr};
1117 
1118     // Error callback
1119     OnErrorCallback onErrorCallback_ {nullptr};
1120     void *onErrorData_ {nullptr};
1121 
1122     // serch happath callback
1123     SearchHapPathCallBack SearchHapPathCallBack_ {nullptr};
1124 
1125     // vm parameter configurations
1126     EcmaParamConfiguration ecmaParamConfiguration_;
1127 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
1128     CpuProfiler *profiler_ {nullptr};
1129 #endif
1130 #if defined(ECMASCRIPT_SUPPORT_TRACING)
1131     Tracing *tracing_ {nullptr};
1132 #endif
1133     FunctionCallTimer *callTimer_ {nullptr};
1134     JSObjectResizingStrategy *strategy_ {nullptr};
1135 
1136     // For Native MethodLiteral
1137     static void *InternalMethodTable[static_cast<uint8_t>(MethodIndex::METHOD_END)];
1138     CVector<JSTaggedValue> internalNativeMethods_;
1139 
1140     // For repair patch.
1141     QuickFixManager *quickFixManager_ {nullptr};
1142 
1143     // PGO Profiler
1144     std::shared_ptr<PGOProfiler> pgoProfiler_ {nullptr};
1145 
1146     //AOT File Manager
1147     AOTFileManager *aotFileManager_ {nullptr};
1148 
1149     // c++ call js
1150     size_t callDepth_ {0};
1151 
1152     bool isProfiling_ {false};
1153 
1154     DeviceDisconnectCallback deviceDisconnectCallback_ {nullptr};
1155 
1156     UncatchableErrorHandler uncatchableErrorHandler_ {nullptr};
1157 
1158     IntlCache intlCache_;
1159 
1160     friend class Snapshot;
1161     friend class SnapshotProcessor;
1162     friend class ObjectFactory;
1163     friend class ValueSerializer;
1164     friend class panda::JSNApi;
1165     friend class JSPandaFileExecutor;
1166     friend class EcmaContext;
1167     friend class JitVM;
1168     CMap<uint32_t, EcmaVM *> workerList_ {};
1169     Mutex mutex_;
1170     bool isEnableOsr_ {false};
1171     bool isJitCompileVM_ {false};
1172 
1173     // process StartRealTime
1174     int processStartRealtime_ = 0;
1175 
1176     bool enableJitLogSkip_ = true;
1177 
1178 #if ECMASCRIPT_ENABLE_SCOPE_LOCK_STAT
1179     // Stats for Thread-State-Transition and String-Table Locks
1180     bool isCollectingScopeLockStats_ = false;
1181     int enterThreadManagedScopeCount_ = 0;
1182     int enterFastNativeScopeCount_ = 0;
1183     int enterJsiNativeScopeCount_ = 0;
1184     int updateThreadStateTransCount_ = 0;
1185     int stringTableLockCount_ = 0;
1186 #endif
1187 
1188 #if ECMASCRIPT_ENABLE_COLLECTING_OPCODES
1189     std::stack<std::unordered_map<BytecodeInstruction::Opcode, int>> bytecodeStatsStack_;
1190 #endif
1191 };
1192 }  // namespace ecmascript
1193 }  // namespace panda
1194 
1195 #endif
1196