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