• 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 #include "ecmascript/ecma_vm.h"
17 
18 #include "ecmascript/builtins/builtins_ark_tools.h"
19 #ifdef ARK_SUPPORT_INTL
20 #include "ecmascript/builtins/builtins_collator.h"
21 #include "ecmascript/builtins/builtins_date_time_format.h"
22 #include "ecmascript/builtins/builtins_number_format.h"
23 #endif
24 #include "ecmascript/builtins/builtins_global.h"
25 #include "ecmascript/builtins/builtins_object.h"
26 #include "ecmascript/builtins/builtins_promise_handler.h"
27 #include "ecmascript/builtins/builtins_proxy.h"
28 #include "ecmascript/jit/jit_task.h"
29 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
30 #include "ecmascript/dfx/cpu_profiler/cpu_profiler.h"
31 #endif
32 #if !WIN_OR_MAC_OR_IOS_PLATFORM
33 #include "ecmascript/dfx/hprof/heap_profiler.h"
34 #include "ecmascript/dfx/hprof/heap_profiler_interface.h"
35 #endif
36 #include "ecmascript/dfx/tracing/tracing.h"
37 #include "ecmascript/dfx/vmstat/function_call_timer.h"
38 #include "ecmascript/mem/shared_heap/shared_concurrent_marker.h"
39 #include "ecmascript/module/module_logger.h"
40 #include "ecmascript/pgo_profiler/pgo_trace.h"
41 #include "ecmascript/snapshot/mem/snapshot.h"
42 #include "ecmascript/stubs/runtime_stubs.h"
43 #include "ecmascript/ohos/jit_tools.h"
44 #include "ecmascript/ohos/aot_tools.h"
45 #include "ecmascript/checkpoint/thread_state_transition.h"
46 #include "ecmascript/mem/heap-inl.h"
47 #include "ecmascript/dfx/stackinfo/async_stack_trace.h"
48 
49 #if defined(PANDA_TARGET_OHOS) && !defined(STANDALONE_MODE)
50 #include "parameters.h"
51 #endif
52 
53 namespace panda::ecmascript {
54 using RandomGenerator = base::RandomGenerator;
55 using PGOProfilerManager = pgo::PGOProfilerManager;
56 using JitTools = ohos::JitTools;
57 AOTFileManager *JsStackInfo::loader = nullptr;
58 bool EcmaVM::multiThreadCheck_ = false;
59 bool EcmaVM::errorInfoEnhanced_ = false;
60 
Create(const JSRuntimeOptions & options)61 EcmaVM *EcmaVM::Create(const JSRuntimeOptions &options)
62 {
63     Runtime::CreateIfFirstVm(options);
64     auto heapType = options.IsWorker() ? EcmaParamConfiguration::HeapType::WORKER_HEAP :
65         EcmaParamConfiguration::HeapType::DEFAULT_HEAP;
66     size_t heapSize = options.GetHeapSize();
67 #if defined(PANDA_TARGET_OHOS) && !defined(STANDALONE_MODE)
68     switch (heapType) {
69         case EcmaParamConfiguration::HeapType::WORKER_HEAP:
70             heapSize = OHOS::system::GetUintParameter<size_t>("persist.ark.heap.workersize", 0) * 1_MB;
71             break;
72         default:
73             heapSize = OHOS::system::GetUintParameter<size_t>("persist.ark.heap.defaultsize", 0) * 1_MB;
74             break;
75     }
76 #endif
77     auto config = EcmaParamConfiguration(heapType,
78                                          MemMapAllocator::GetInstance()->GetCapacity(),
79                                          heapSize);
80     JSRuntimeOptions newOptions = options;
81     // only define SUPPORT_ENABLE_ASM_INTERP can enable asm-interpreter
82 #if !defined(SUPPORT_ENABLE_ASM_INTERP)
83     newOptions.SetEnableAsmInterpreter(false);
84 #endif
85     auto vm = new EcmaVM(newOptions, config);
86     auto jsThread = JSThread::Create(vm);
87     vm->thread_ = jsThread;
88     Runtime::GetInstance()->InitializeIfFirstVm(vm);
89     if (JsStackInfo::loader == nullptr) {
90         JsStackInfo::loader = vm->GetAOTFileManager();
91     }
92 #if defined(PANDA_TARGET_OHOS) && !defined(STANDALONE_MODE)
93     int arkProperties = OHOS::system::GetIntParameter<int>("persist.ark.properties", -1);
94     vm->GetJSOptions().SetArkProperties(arkProperties);
95 #endif
96     return vm;
97 }
98 
99 // static
Destroy(EcmaVM * vm)100 bool EcmaVM::Destroy(EcmaVM *vm)
101 {
102     if (UNLIKELY(vm == nullptr)) {
103         return false;
104     }
105     delete vm;
106     Runtime::DestroyIfLastVm();
107     return true;
108 }
109 
PreFork()110 void EcmaVM::PreFork()
111 {
112     heap_->CompactHeapBeforeFork();
113     heap_->AdjustSpaceSizeForAppSpawn();
114     heap_->GetReadOnlySpace()->SetReadOnly();
115     heap_->DisableParallelGC();
116     SetPostForked(false);
117 
118     auto sHeap = SharedHeap::GetInstance();
119     sHeap->CompactHeapBeforeFork(thread_);
120     sHeap->DisableParallelGC(thread_);
121     heap_->GetWorkManager()->FinishInPreFork();
122     sHeap->GetWorkManager()->FinishInPreFork();
123     Jit::GetInstance()->PreFork();
124 }
125 
PostFork()126 void EcmaVM::PostFork()
127 {
128     RandomGenerator::InitRandom(GetAssociatedJSThread());
129     heap_->SetHeapMode(HeapMode::SHARE);
130     GetAssociatedJSThread()->PostFork();
131     DaemonThread::GetInstance()->StartRunning();
132     Taskpool::GetCurrentTaskpool()->Initialize();
133     heap_->GetWorkManager()->InitializeInPostFork();
134     auto sHeap = SharedHeap::GetInstance();
135     sHeap->GetWorkManager()->InitializeInPostFork();
136     SetPostForked(true);
137     LOG_ECMA(INFO) << "multi-thread check enabled: " << GetThreadCheckStatus();
138     SignalAllReg();
139     SharedHeap::GetInstance()->EnableParallelGC(GetJSOptions());
140     heap_->EnableParallelGC();
141     options_.SetPgoForceDump(false);
142     std::string bundleName = PGOProfilerManager::GetInstance()->GetBundleName();
143     pgo::PGOTrace::GetInstance()->SetEnable(ohos::AotTools::GetPgoTraceEnable());
144     AotCrashInfo::GetInstance().SetOptionPGOProfiler(&options_, bundleName);
145     ResetPGOProfiler();
146     processStartRealtime_ = InitializeStartRealTime();
147 
148     Jit::GetInstance()->SetJitEnablePostFork(this, bundleName);
149 #if defined(PANDA_TARGET_OHOS) && !defined(STANDALONE_MODE)
150     int arkProperties = OHOS::system::GetIntParameter<int>("persist.ark.properties", -1);
151     GetJSOptions().SetArkProperties(arkProperties);
152 #endif
153 #ifdef ENABLE_POSTFORK_FORCEEXPAND
154     heap_->NotifyPostFork();
155     heap_->NotifyFinishColdStartSoon();
156 #endif
157     DaemonThread::GetInstance()->EnsureRunning();
158 }
159 
EcmaVM(JSRuntimeOptions options,EcmaParamConfiguration config)160 EcmaVM::EcmaVM(JSRuntimeOptions options, EcmaParamConfiguration config)
161     : nativeAreaAllocator_(std::make_unique<NativeAreaAllocator>()),
162       heapRegionAllocator_(std::make_unique<HeapRegionAllocator>(options)),
163       chunk_(nativeAreaAllocator_.get()),
164       ecmaParamConfiguration_(std::move(config))
165 {
166     options_ = std::move(options);
167     LOG_ECMA(DEBUG) << "multi-thread check enabled: " << GetThreadCheckStatus();
168     icEnabled_ = options_.EnableIC();
169     optionalLogEnabled_ = options_.EnableOptionalLog();
170     options_.ParseAsmInterOption();
171     SetEnableOsr(options_.IsEnableOSR() && options_.IsEnableJIT() && options_.GetEnableAsmInterpreter());
172     processStartRealtime_ = InitializeStartRealTime();
173 }
174 
175 // for jit
EcmaVM()176 EcmaVM::EcmaVM()
177     : nativeAreaAllocator_(std::make_unique<NativeAreaAllocator>()),
178       heapRegionAllocator_(nullptr),
179       chunk_(nativeAreaAllocator_.get()) {}
180 
InitializeForJit(JitThread * jitThread)181 void EcmaVM::InitializeForJit(JitThread *jitThread)
182 {
183     thread_ = jitThread;
184     stringTable_ = Runtime::GetInstance()->GetEcmaStringTable();
185     ASSERT(stringTable_);
186     // ObjectFactory only sypport alloc string in sharedheap
187     factory_ = chunk_.New<ObjectFactory>(thread_, nullptr, SharedHeap::GetInstance());
188     SetIsJitCompileVM(true);
189 }
190 
InitializePGOProfiler()191 void EcmaVM::InitializePGOProfiler()
192 {
193     LOG_PGO(INFO) << "initializing pgo profiler, pgo is " << (IsEnablePGOProfiler() ? "enabled" : "disabled")
194                   << ", worker is " << (options_.IsWorker() ? "enabled" : "disabled")
195                   << ", profiler: " << pgoProfiler_;
196     bool isEnablePGOProfiler = IsEnablePGOProfiler();
197     if (pgoProfiler_ == nullptr) {
198         pgoProfiler_ = PGOProfilerManager::GetInstance()->BuildProfiler(this, isEnablePGOProfiler);
199     }
200     pgo::PGOTrace::GetInstance()->SetEnable(options_.GetPGOTrace() || ohos::AotTools::GetPgoTraceEnable());
201     thread_->SetPGOProfilerEnable(isEnablePGOProfiler);
202 }
203 
ResetPGOProfiler()204 void EcmaVM::ResetPGOProfiler()
205 {
206     if (pgoProfiler_ != nullptr) {
207         bool isEnablePGOProfiler = IsEnablePGOProfiler();
208         PGOProfilerManager::GetInstance()->Reset(pgoProfiler_, isEnablePGOProfiler);
209         thread_->SetPGOProfilerEnable(isEnablePGOProfiler);
210         thread_->CheckOrSwitchPGOStubs();
211     }
212 }
213 
DisablePGOProfilerWithAOTFile(const std::string & aotFileName)214 void EcmaVM::DisablePGOProfilerWithAOTFile(const std::string &aotFileName)
215 {
216     if (AOTFileManager::AOTFileExist(aotFileName, AOTFileManager::FILE_EXTENSION_AN) ||
217         AOTFileManager::AOTFileExist(aotFileName, AOTFileManager::FILE_EXTENSION_AI)) {
218         LOG_PGO(INFO) << "disable pgo profiler due to aot file exist: " << aotFileName;
219         options_.SetEnablePGOProfiler(false);
220         PGOProfilerManager::GetInstance()->SetDisablePGO(true);
221         ResetPGOProfiler();
222     }
223 }
224 
IsEnablePGOProfiler() const225 bool EcmaVM::IsEnablePGOProfiler() const
226 {
227     if (options_.IsWorker()) {
228         return PGOProfilerManager::GetInstance()->IsEnable();
229     }
230     return options_.GetEnableAsmInterpreter() && options_.IsEnablePGOProfiler();
231 }
232 
IsEnableMutantArray() const233 bool EcmaVM::IsEnableMutantArray() const
234 {
235     return options_.GetEnableAsmInterpreter() && options_.IsEnableMutantArray();
236 }
237 
IsEnableElementsKind() const238 bool EcmaVM::IsEnableElementsKind() const
239 {
240     return options_.GetEnableAsmInterpreter() && options_.IsEnableElementsKind();
241 }
242 
IsEnableFastJit() const243 bool EcmaVM::IsEnableFastJit() const
244 {
245     return GetJit()->IsEnableFastJit();
246 }
247 
IsEnableBaselineJit() const248 bool EcmaVM::IsEnableBaselineJit() const
249 {
250     return GetJit()->IsEnableBaselineJit();
251 }
252 
GetTid() const253 uint32_t EcmaVM::GetTid() const
254 {
255     return thread_->GetThreadId();
256 }
257 
GetJit() const258 Jit *EcmaVM::GetJit() const
259 {
260     return Jit::GetInstance();
261 }
262 
Initialize()263 bool EcmaVM::Initialize()
264 {
265     ECMA_BYTRACE_NAME(HITRACE_TAG_ARK, "EcmaVM::Initialize");
266     stringTable_ = Runtime::GetInstance()->GetEcmaStringTable();
267     InitializePGOProfiler();
268     Taskpool::GetCurrentTaskpool()->Initialize();
269 #ifndef PANDA_TARGET_WINDOWS
270     RuntimeStubs::Initialize(thread_);
271 #endif
272     heap_ = new Heap(this);
273     heap_->Initialize();
274     gcStats_ = chunk_.New<GCStats>(heap_, options_.GetLongPauseTime());
275     gcKeyStats_ = chunk_.New<GCKeyStats>(heap_, gcStats_);
276     factory_ = chunk_.New<ObjectFactory>(thread_, heap_, SharedHeap::GetInstance());
277     if (UNLIKELY(factory_ == nullptr)) {
278         LOG_FULL(FATAL) << "alloc factory_ failed";
279         UNREACHABLE();
280     }
281     debuggerManager_ = new tooling::JsDebuggerManager(this);
282     asyncStackTrace_ = new AsyncStackTrace(this);
283     aotFileManager_ = new AOTFileManager(this);
284     auto context = new EcmaContext(thread_);
285     thread_->PushContext(context);
286     [[maybe_unused]] EcmaHandleScope scope(thread_);
287     thread_->SetReadyForGCIterating(true);
288     thread_->SetSharedMarkStatus(DaemonThread::GetInstance()->GetSharedMarkStatus());
289     snapshotEnv_ = new SnapshotEnv(this);
290     context->Initialize();
291     snapshotEnv_->AddGlobalConstToMap();
292     thread_->SetGlueGlobalEnv(reinterpret_cast<GlobalEnv *>(context->GetGlobalEnv().GetTaggedType()));
293     thread_->SetGlobalObject(GetGlobalEnv()->GetGlobalObject());
294     thread_->SetCurrentEcmaContext(context);
295     GenerateInternalNativeMethods();
296     quickFixManager_ = new QuickFixManager();
297     if (options_.GetEnableAsmInterpreter()) {
298         thread_->GetCurrentEcmaContext()->LoadStubFile();
299     }
300 
301     callTimer_ = new FunctionCallTimer();
302     strategy_ = new ThroughputJSObjectResizingStrategy();
303     if (IsEnableFastJit() || IsEnableBaselineJit()) {
304         Jit::GetInstance()->ConfigJit(this);
305     }
306     initialized_ = true;
307     return true;
308 }
309 
~EcmaVM()310 EcmaVM::~EcmaVM()
311 {
312     if (isJitCompileVM_) {
313         if (factory_ != nullptr) {
314             chunk_.Delete(factory_);
315             factory_ = nullptr;
316         }
317         stringTable_ = nullptr;
318         thread_ = nullptr;
319         return;
320     }
321 #if ECMASCRIPT_ENABLE_THREAD_STATE_CHECK
322     if (UNLIKELY(!thread_->IsInRunningStateOrProfiling())) {
323         LOG_ECMA(FATAL) << "Destruct VM must be in jsthread running state";
324         UNREACHABLE();
325     }
326 #endif
327     initialized_ = false;
328 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
329     if (profiler_ != nullptr) {
330         if (profiler_->GetOutToFile()) {
331             DFXJSNApi::StopCpuProfilerForFile(this);
332         } else {
333             DFXJSNApi::StopCpuProfilerForInfo(this);
334         }
335     }
336     if (profiler_ != nullptr) {
337         delete profiler_;
338         profiler_ = nullptr;
339     }
340 #endif
341 #if defined(ECMASCRIPT_SUPPORT_HEAPPROFILER)
342     DeleteHeapProfile();
343 #endif
344     if (IsEnableFastJit() || IsEnableBaselineJit()) {
345         GetJit()->ClearTaskWithVm(this);
346     }
347     // clear c_address: c++ pointer delete
348     ClearBufferData();
349     heap_->WaitAllTasksFinished();
350     Taskpool::GetCurrentTaskpool()->Destroy(thread_->GetThreadId());
351 
352     if (pgoProfiler_ != nullptr) {
353         PGOProfilerManager::GetInstance()->Destroy(pgoProfiler_);
354         pgoProfiler_ = nullptr;
355     }
356 
357 #if ECMASCRIPT_ENABLE_FUNCTION_CALL_TIMER
358     DumpCallTimeInfo();
359 #endif
360 
361 #if defined(ECMASCRIPT_SUPPORT_TRACING)
362     if (tracing_) {
363         DFXJSNApi::StopTracing(this);
364     }
365 #endif
366 
367     thread_->GetCurrentEcmaContext()->GetModuleManager()->NativeObjDestory();
368 
369     if (!isBundlePack_) {
370         std::shared_ptr<JSPandaFile> jsPandaFile = JSPandaFileManager::GetInstance()->FindJSPandaFile(assetPath_);
371         if (jsPandaFile != nullptr) {
372             jsPandaFile->DeleteParsedConstpoolVM(this);
373         }
374     }
375 
376     if (gcStats_ != nullptr) {
377         if (options_.EnableGCStatsPrint()) {
378             gcStats_->PrintStatisticResult();
379         }
380         chunk_.Delete(gcStats_);
381         gcStats_ = nullptr;
382     }
383 
384     if (gcKeyStats_ != nullptr) {
385         chunk_.Delete(gcKeyStats_);
386         gcKeyStats_ = nullptr;
387     }
388 
389     if (JsStackInfo::loader == aotFileManager_) {
390         JsStackInfo::loader = nullptr;
391     }
392 
393     if (heap_ != nullptr) {
394         heap_->Destroy();
395         delete heap_;
396         heap_ = nullptr;
397     }
398 
399     SharedHeap *sHeap = SharedHeap::GetInstance();
400     const Heap *heap = Runtime::GetInstance()->GetMainThread()->GetEcmaVM()->GetHeap();
401     if (IsWorkerThread() && Runtime::SharedGCRequest()) {
402         // destory workervm to release mem.
403         thread_->SetReadyForGCIterating(false);
404         if (sHeap->CheckCanTriggerConcurrentMarking(thread_)) {
405             sHeap->TriggerConcurrentMarking<TriggerGCType::SHARED_GC, GCReason::WORKER_DESTRUCTION>(thread_);
406         } else if (heap && !heap->InSensitiveStatus() && !sHeap->GetConcurrentMarker()->IsEnabled()) {
407             sHeap->CollectGarbage<TriggerGCType::SHARED_GC, GCReason::WORKER_DESTRUCTION>(thread_);
408         }
409     }
410 
411     intlCache_.ClearIcuCache(this);
412 
413     if (runtimeStat_ != nullptr) {
414         chunk_.Delete(runtimeStat_);
415         runtimeStat_ = nullptr;
416     }
417 
418     if (debuggerManager_ != nullptr) {
419         delete debuggerManager_;
420         debuggerManager_ = nullptr;
421     }
422 
423     if (asyncStackTrace_ != nullptr) {
424         delete asyncStackTrace_;
425         asyncStackTrace_ = nullptr;
426     }
427 
428     if (aotFileManager_ != nullptr) {
429         delete aotFileManager_;
430         aotFileManager_ = nullptr;
431     }
432 
433     if (factory_ != nullptr) {
434         chunk_.Delete(factory_);
435         factory_ = nullptr;
436     }
437 
438     if (stringTable_ != nullptr) {
439         stringTable_ = nullptr;
440     }
441 
442     if (quickFixManager_ != nullptr) {
443         delete quickFixManager_;
444         quickFixManager_ = nullptr;
445     }
446 
447     if (snapshotEnv_ != nullptr) {
448         snapshotEnv_->ClearEnvMap();
449         delete snapshotEnv_;
450         snapshotEnv_ = nullptr;
451     }
452 
453     if (callTimer_ != nullptr) {
454         delete callTimer_;
455         callTimer_ = nullptr;
456     }
457 
458     if (strategy_ != nullptr) {
459         delete strategy_;
460         strategy_ = nullptr;
461     }
462 
463     if (thread_ != nullptr) {
464         delete thread_;
465         thread_ = nullptr;
466     }
467 }
468 
InitializeEcmaScriptRunStat()469 void EcmaVM::InitializeEcmaScriptRunStat()
470 {
471     // NOLINTNEXTLINE(modernize-avoid-c-arrays)
472     static const char *runtimeCallerNames[] = {
473 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
474 #define INTERPRETER_CALLER_NAME(name) "Interpreter::" #name,
475     INTERPRETER_CALLER_LIST(INTERPRETER_CALLER_NAME)  // NOLINTNEXTLINE(bugprone-suspicious-missing-comma)
476 #undef INTERPRETER_CALLER_NAME
477 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
478 #define BUILTINS_API_NAME(class, name) "BuiltinsApi::" #class "_" #name,
479     BUILTINS_API_LIST(BUILTINS_API_NAME)
480 #undef BUILTINS_API_NAME
481 #define ABSTRACT_OPERATION_NAME(class, name) "AbstractOperation::" #class "_" #name,
482     ABSTRACT_OPERATION_LIST(ABSTRACT_OPERATION_NAME)
483 #undef ABSTRACT_OPERATION_NAME
484 #define MEM_ALLOCATE_AND_GC_NAME(name) "Memory::" #name,
485     MEM_ALLOCATE_AND_GC_LIST(MEM_ALLOCATE_AND_GC_NAME)
486 #undef MEM_ALLOCATE_AND_GC_NAME
487 #define DEF_RUNTIME_ID(name) "Runtime::" #name,
488     RUNTIME_STUB_WITH_GC_LIST(DEF_RUNTIME_ID)
489     RUNTIME_STUB_WITH_DFX(DEF_RUNTIME_ID)
490 #undef DEF_RUNTIME_ID
491     };
492     static_assert(sizeof(runtimeCallerNames) == sizeof(const char *) * ecmascript::RUNTIME_CALLER_NUMBER,
493                   "Invalid runtime caller number");
494     runtimeStat_ = chunk_.New<EcmaRuntimeStat>(runtimeCallerNames, ecmascript::RUNTIME_CALLER_NUMBER);
495     if (UNLIKELY(runtimeStat_ == nullptr)) {
496         LOG_FULL(FATAL) << "alloc runtimeStat_ failed";
497         UNREACHABLE();
498     }
499 }
500 
SetRuntimeStatEnable(bool flag)501 void EcmaVM::SetRuntimeStatEnable(bool flag)
502 {
503     static uint64_t start = 0;
504     if (flag) {
505         start = PandaRuntimeTimer::Now();
506         if (runtimeStat_ == nullptr) {
507             InitializeEcmaScriptRunStat();
508         }
509     } else {
510         LOG_ECMA(INFO) << "Runtime State duration:" << PandaRuntimeTimer::Now() - start << "(ns)";
511         if (runtimeStat_ != nullptr && runtimeStat_->IsRuntimeStatEnabled()) {
512             runtimeStat_->Print();
513             runtimeStat_->ResetAllCount();
514         }
515     }
516     if (runtimeStat_ != nullptr) {
517         runtimeStat_->SetRuntimeStatEnabled(flag);
518     }
519 }
520 
GetGlobalEnv() const521 JSHandle<GlobalEnv> EcmaVM::GetGlobalEnv() const
522 {
523     return thread_->GetCurrentEcmaContext()->GetGlobalEnv();
524 }
525 
CheckThread() const526 void EcmaVM::CheckThread() const
527 {
528     // Exclude GC thread
529     if (thread_ == nullptr) {
530         LOG_FULL(FATAL) << "Fatal: ecma_vm has been destructed! vm address is: " << this;
531         UNREACHABLE();
532     }
533     if (!Taskpool::GetCurrentTaskpool()->IsDaemonThreadOrInThreadPool(std::this_thread::get_id()) &&
534         thread_->CheckMultiThread()) {
535             LOG_FULL(FATAL) << "Fatal: ecma_vm cannot run in multi-thread!"
536                                 << " thread:" << thread_->GetThreadId()
537                                 << " currentThread:" << JSThread::GetCurrentThreadId();
538         UNREACHABLE();
539     }
540 }
541 
GetAndFastCheckJSThread() const542 JSThread *EcmaVM::GetAndFastCheckJSThread() const
543 {
544     if (thread_ == nullptr) {
545         LOG_FULL(FATAL) << "Fatal: ecma_vm has been destructed! vm address is: " << this;
546     }
547     if (thread_->CheckMultiThread()) {
548         LOG_FULL(FATAL) << "Fatal: ecma_vm cannot run in multi-thread!"
549                                 << " thread:" << thread_->GetThreadId()
550                                 << " currentThread:" << JSThread::GetCurrentThreadId();
551     }
552     return thread_;
553 }
554 
CheckSingleThread() const555 bool EcmaVM::CheckSingleThread() const
556 {
557     if (thread_ == nullptr) {
558         LOG_FULL(FATAL) << "Fatal: ecma_vm has been destructed! vm address is: " << this;
559         return false;
560     }
561     if (thread_->GetThreadId() != JSThread::GetCurrentThreadId()) {
562         LOG_FULL(FATAL) << "Fatal: ecma_vm cannot run in multi-thread!"
563                         << " thread:" << thread_->GetThreadId()
564                         << " currentThread:" << JSThread::GetCurrentThreadId();
565         return false;
566     }
567     return true;
568 }
569 
FastCallAot(size_t actualNumArgs,JSTaggedType * args,const JSTaggedType * prevFp)570 JSTaggedValue EcmaVM::FastCallAot(size_t actualNumArgs, JSTaggedType *args, const JSTaggedType *prevFp)
571 {
572     INTERPRETER_TRACE(thread_, ExecuteAot);
573     ASSERT(thread_->IsInManagedState());
574     auto entry = thread_->GetRTInterface(kungfu::RuntimeStubCSigns::ID_OptimizedFastCallEntry);
575     // entry of aot
576     auto res = reinterpret_cast<FastCallAotEntryType>(entry)(thread_->GetGlueAddr(),
577                                                              actualNumArgs,
578                                                              args,
579                                                              reinterpret_cast<uintptr_t>(prevFp));
580     return res;
581 }
582 
CheckStartCpuProfiler()583 void EcmaVM::CheckStartCpuProfiler()
584 {
585 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
586     if (options_.EnableCpuProfilerColdStartMainThread() && options_.GetArkBundleName().compare(bundleName_) == 0 &&
587         !options_.IsWorker() && profiler_ == nullptr) {
588         std::string fileName = options_.GetArkBundleName() + ".cpuprofile";
589         if (!builtins::BuiltinsArkTools::CreateFile(fileName)) {
590             LOG_ECMA(ERROR) << "createFile failed " << fileName;
591             return;
592         } else {
593             DFXJSNApi::StartCpuProfilerForFile(this, fileName, CpuProfiler::INTERVAL_OF_INNER_START);
594             return;
595         }
596     }
597 
598     if (options_.EnableCpuProfilerColdStartWorkerThread() && options_.GetArkBundleName().compare(bundleName_) == 0 &&
599         options_.IsWorker() && profiler_ == nullptr) {
600         std::string fileName = options_.GetArkBundleName() + "_"
601                                + std::to_string(thread_->GetThreadId()) + ".cpuprofile";
602         if (!builtins::BuiltinsArkTools::CreateFile(fileName)) {
603             LOG_ECMA(ERROR) << "createFile failed " << fileName;
604             return;
605         } else {
606             DFXJSNApi::StartCpuProfilerForFile(this, fileName, CpuProfiler::INTERVAL_OF_INNER_START);
607             return;
608         }
609     }
610 #endif
611 }
612 
GetAndClearEcmaUncaughtException() const613 JSHandle<JSTaggedValue> EcmaVM::GetAndClearEcmaUncaughtException() const
614 {
615     JSHandle<JSTaggedValue> exceptionHandle = GetEcmaUncaughtException();
616     thread_->ClearException();  // clear for ohos app
617     return exceptionHandle;
618 }
619 
GetEcmaUncaughtException() const620 JSHandle<JSTaggedValue> EcmaVM::GetEcmaUncaughtException() const
621 {
622     if (!thread_->HasPendingException()) {
623         return JSHandle<JSTaggedValue>();
624     }
625     JSHandle<JSTaggedValue> exceptionHandle(thread_, thread_->GetException());
626     return exceptionHandle;
627 }
628 
629 #if ECMASCRIPT_ENABLE_COLLECTING_OPCODES
PrintCollectedByteCode()630 void EcmaVM::PrintCollectedByteCode()
631 {
632     std::unordered_map<BytecodeInstruction::Opcode, int> bytecodeStatsMap_ = bytecodeStatsStack_.top();
633     LOG_ECMA(ERROR) << "panda runtime stat:";
634     static constexpr int nameRightAdjustment = 45;
635     static constexpr int numberRightAdjustment = 12;
636     LOG_ECMA(ERROR) << std::right << std::setw(nameRightAdjustment) << "Hotness Function ByteCode"
637                    << std::setw(numberRightAdjustment) << "Count";
638     LOG_ECMA(ERROR) << "============================================================"
639                       << "=========================================================";
640     std::vector<std::pair<std::string, int>> bytecodeStatsVector;
641     for (auto& iter: bytecodeStatsMap_) {
642         bytecodeStatsVector.push_back(
643             std::make_pair(kungfu::GetEcmaOpcodeStr(static_cast<EcmaOpcode>(iter.first)), iter.second));
644     }
645     std::sort(bytecodeStatsVector.begin(), bytecodeStatsVector.end(),
646               [](std::pair<std::string, int> &a, std::pair<std::string, int> &b) {
647         return a.second > b.second;
648     });
649     for (size_t i = 0; i < bytecodeStatsVector.size(); ++i) {
650         LOG_ECMA(ERROR) << std::right << std::setw(nameRightAdjustment) << bytecodeStatsVector[i].first
651                        << std::setw(numberRightAdjustment) << bytecodeStatsVector[i].second;
652     }
653     LOG_ECMA(ERROR) << "============================================================"
654                       << "=========================================================";
655 }
656 #endif
657 
PrintAOTSnapShotStats()658 void EcmaVM::PrintAOTSnapShotStats()
659 {
660     static constexpr int nameRightAdjustment = 30;
661     static constexpr int numberRightAdjustment = 30;
662     LOG_ECMA(ERROR) << std::right << std::setw(nameRightAdjustment) << "AOT Snapshot Genre"
663                     << std::setw(numberRightAdjustment) << "Count";
664     LOG_ECMA(ERROR) << "==========================================================================";
665     for (const auto &iter: aotSnapShotStatsMap_) {
666         LOG_ECMA(ERROR) << std::right << std::setw(nameRightAdjustment) << iter.first
667                         << std::setw(numberRightAdjustment) << iter.second;
668     }
669     LOG_ECMA(ERROR) << "==========================================================================";
670     aotSnapShotStatsMap_.clear();
671 }
672 
PrintJSErrorInfo(const JSHandle<JSTaggedValue> & exceptionInfo) const673 void EcmaVM::PrintJSErrorInfo(const JSHandle<JSTaggedValue> &exceptionInfo) const
674 {
675     EcmaContext::PrintJSErrorInfo(thread_, exceptionInfo);
676 }
677 
ProcessNativeDelete(const WeakRootVisitor & visitor)678 void EcmaVM::ProcessNativeDelete(const WeakRootVisitor& visitor)
679 {
680     heap_->ProcessNativeDelete(visitor);
681 }
682 
ProcessReferences(const WeakRootVisitor & visitor)683 void EcmaVM::ProcessReferences(const WeakRootVisitor& visitor)
684 {
685     heap_->ProcessReferences(visitor);
686     GetPGOProfiler()->ProcessReferences(visitor);
687 }
688 
PushToNativePointerList(JSNativePointer * pointer,Concurrent isConcurrent)689 void EcmaVM::PushToNativePointerList(JSNativePointer* pointer, Concurrent isConcurrent)
690 {
691     heap_->PushToNativePointerList(pointer, isConcurrent == Concurrent::YES);
692 }
693 
RemoveFromNativePointerList(JSNativePointer * pointer)694 void EcmaVM::RemoveFromNativePointerList(JSNativePointer* pointer)
695 {
696     heap_->RemoveFromNativePointerList(pointer);
697 }
698 
PushToDeregisterModuleList(const CString & module)699 void EcmaVM::PushToDeregisterModuleList(const CString &module)
700 {
701     deregisterModuleList_.emplace_back(module);
702 }
703 
RemoveFromDeregisterModuleList(CString module)704 void EcmaVM::RemoveFromDeregisterModuleList(CString module)
705 {
706     auto iter = std::find(deregisterModuleList_.begin(), deregisterModuleList_.end(), module);
707     if (iter != deregisterModuleList_.end()) {
708         deregisterModuleList_.erase(iter);
709     }
710 }
711 
ContainInDeregisterModuleList(CString module)712 bool EcmaVM::ContainInDeregisterModuleList(CString module)
713 {
714     return (std::find(deregisterModuleList_.begin(), deregisterModuleList_.end(), module)
715         != deregisterModuleList_.end());
716 }
717 
ClearBufferData()718 void EcmaVM::ClearBufferData()
719 {
720     heap_->ClearNativePointerList();
721     thread_->GetCurrentEcmaContext()->ClearBufferData();
722     internalNativeMethods_.clear();
723     workerList_.clear();
724     deregisterModuleList_.clear();
725 }
726 
CollectGarbage(TriggerGCType gcType,panda::ecmascript::GCReason reason) const727 void EcmaVM::CollectGarbage(TriggerGCType gcType, panda::ecmascript::GCReason reason) const
728 {
729     heap_->CollectGarbage(gcType, reason);
730 }
731 
Iterate(RootVisitor & v,VMRootVisitType type)732 void EcmaVM::Iterate(RootVisitor &v, VMRootVisitType type)
733 {
734     v.VisitRangeRoot(Root::ROOT_VM, ObjectSlot(ToUintPtr(&internalNativeMethods_.front())),
735         ObjectSlot(ToUintPtr(&internalNativeMethods_.back()) + JSTaggedValue::TaggedTypeSize()));
736     if (!WIN_OR_MAC_OR_IOS_PLATFORM && snapshotEnv_!= nullptr) {
737         snapshotEnv_->Iterate(v, type);
738     }
739     if (pgoProfiler_ != nullptr) {
740         pgoProfiler_->Iterate(v);
741     }
742     if (aotFileManager_) {
743         aotFileManager_->Iterate(v);
744     }
745 }
746 
747 #if defined(ECMASCRIPT_SUPPORT_HEAPPROFILER)
DeleteHeapProfile()748 void EcmaVM::DeleteHeapProfile()
749 {
750     if (heapProfile_ == nullptr) {
751         return;
752     }
753     delete heapProfile_;
754     heapProfile_ = nullptr;
755 }
756 
GetHeapProfile()757 HeapProfilerInterface *EcmaVM::GetHeapProfile()
758 {
759     if (heapProfile_ != nullptr) {
760         return heapProfile_;
761     }
762     return nullptr;
763 }
764 
GetOrNewHeapProfile()765 HeapProfilerInterface *EcmaVM::GetOrNewHeapProfile()
766 {
767     if (heapProfile_ != nullptr) {
768         return heapProfile_;
769     }
770     heapProfile_ = new HeapProfiler(this);
771     ASSERT(heapProfile_ != nullptr);
772     return heapProfile_;
773 }
774 
StartHeapTracking()775 void EcmaVM::StartHeapTracking()
776 {
777     heap_->StartHeapTracking();
778 }
779 
StopHeapTracking()780 void EcmaVM::StopHeapTracking()
781 {
782     heap_->StopHeapTracking();
783 }
784 #endif
785 
786 // NOLINTNEXTLINE(modernize-avoid-c-arrays)
787 void *EcmaVM::InternalMethodTable[] = {
788     reinterpret_cast<void *>(builtins::BuiltinsGlobal::CallJsBoundFunction),
789     reinterpret_cast<void *>(builtins::BuiltinsGlobal::CallJsProxy),
790     reinterpret_cast<void *>(builtins::BuiltinsObject::CreateDataPropertyOnObjectFunctions),
791 #ifdef ARK_SUPPORT_INTL
792     reinterpret_cast<void *>(builtins::BuiltinsCollator::AnonymousCollator),
793     reinterpret_cast<void *>(builtins::BuiltinsDateTimeFormat::AnonymousDateTimeFormat),
794     reinterpret_cast<void *>(builtins::BuiltinsNumberFormat::NumberFormatInternalFormatNumber),
795 #endif
796     reinterpret_cast<void *>(builtins::BuiltinsProxy::InvalidateProxyFunction),
797     reinterpret_cast<void *>(builtins::BuiltinsPromiseHandler::AsyncAwaitFulfilled),
798     reinterpret_cast<void *>(builtins::BuiltinsPromiseHandler::AsyncAwaitRejected),
799     reinterpret_cast<void *>(builtins::BuiltinsPromiseHandler::ResolveElementFunction),
800     reinterpret_cast<void *>(builtins::BuiltinsPromiseHandler::Resolve),
801     reinterpret_cast<void *>(builtins::BuiltinsPromiseHandler::Reject),
802     reinterpret_cast<void *>(builtins::BuiltinsPromiseHandler::Executor),
803     reinterpret_cast<void *>(builtins::BuiltinsPromiseHandler::AnyRejectElementFunction),
804     reinterpret_cast<void *>(builtins::BuiltinsPromiseHandler::AllSettledResolveElementFunction),
805     reinterpret_cast<void *>(builtins::BuiltinsPromiseHandler::AllSettledRejectElementFunction),
806     reinterpret_cast<void *>(builtins::BuiltinsPromiseHandler::ThenFinally),
807     reinterpret_cast<void *>(builtins::BuiltinsPromiseHandler::CatchFinally),
808     reinterpret_cast<void *>(builtins::BuiltinsPromiseHandler::valueThunkFunction),
809     reinterpret_cast<void *>(builtins::BuiltinsPromiseHandler::throwerFunction),
810     reinterpret_cast<void *>(JSAsyncGeneratorObject::ProcessorFulfilledFunc),
811     reinterpret_cast<void *>(JSAsyncGeneratorObject::ProcessorRejectedFunc),
812     reinterpret_cast<void *>(JSAsyncFromSyncIterator::AsyncFromSyncIterUnwarpFunction),
813     reinterpret_cast<void *>(SourceTextModule::AsyncModuleFulfilledFunc),
814     reinterpret_cast<void *>(SourceTextModule::AsyncModuleRejectedFunc)
815 };
816 
GenerateInternalNativeMethods()817 void EcmaVM::GenerateInternalNativeMethods()
818 {
819     size_t length = static_cast<size_t>(MethodIndex::METHOD_END);
820     constexpr uint32_t numArgs = 2;  // function object and this
821     for (size_t i = 0; i < length; i++) {
822         auto method = factory_->NewSMethod(nullptr, MemSpaceType::SHARED_NON_MOVABLE);
823         method->SetNativePointer(InternalMethodTable[i]);
824         method->SetNativeBit(true);
825         method->SetNumArgsWithCallField(numArgs);
826         method->SetFunctionKind(FunctionKind::NORMAL_FUNCTION);
827         internalNativeMethods_.emplace_back(method.GetTaggedValue());
828     }
829     // cache to global constants shared because context may change
830     CacheToGlobalConstants(GetMethodByIndex(MethodIndex::BUILTINS_GLOBAL_CALL_JS_BOUND_FUNCTION),
831                            ConstantIndex::BOUND_FUNCTION_METHOD_INDEX);
832     CacheToGlobalConstants(GetMethodByIndex(MethodIndex::BUILTINS_GLOBAL_CALL_JS_PROXY),
833                            ConstantIndex::PROXY_METHOD_INDEX);
834 }
835 
CacheToGlobalConstants(JSTaggedValue value,ConstantIndex idx)836 void EcmaVM::CacheToGlobalConstants(JSTaggedValue value, ConstantIndex idx)
837 {
838     auto thread = GetJSThread();
839     auto context = thread->GetCurrentEcmaContext();
840     auto constants = const_cast<GlobalEnvConstants *>(context->GlobalConstants());
841     constants->SetConstant(idx, value);
842 }
843 
GetMethodByIndex(MethodIndex idx)844 JSTaggedValue EcmaVM::GetMethodByIndex(MethodIndex idx)
845 {
846     auto index = static_cast<uint8_t>(idx);
847     ASSERT(index < internalNativeMethods_.size());
848     return internalNativeMethods_[index];
849 }
850 
TriggerConcurrentCallback(JSTaggedValue result,JSTaggedValue hint)851 void EcmaVM::TriggerConcurrentCallback(JSTaggedValue result, JSTaggedValue hint)
852 {
853     if (concurrentCallback_ == nullptr) {
854         LOG_ECMA(DEBUG) << "Only trigger concurrent callback in taskpool thread";
855         return;
856     }
857 
858     bool success = true;
859     if (result.IsJSPromise()) {
860         // Async concurrent will return Promise
861         auto promise = JSPromise::Cast(result.GetTaggedObject());
862         auto status = promise->GetPromiseState();
863         if (status == PromiseState::PENDING) {
864             result = JSHandle<JSTaggedValue>::Cast(factory_->GetJSError(
865                 ErrorType::ERROR, "Can't return Promise in pending state", StackCheck::NO)).GetTaggedValue();
866         } else {
867             result = promise->GetPromiseResult();
868         }
869 
870         if (status != PromiseState::FULFILLED) {
871             success = false;
872         }
873     }
874 
875     JSHandle<JSTaggedValue> functionValue(thread_, hint);
876     if (!functionValue->IsJSFunction()) {
877         LOG_ECMA(ERROR) << "TriggerConcurrentCallback hint is not function";
878         return;
879     }
880     JSHandle<JSFunction> functionInfo(functionValue);
881     if (!functionInfo->GetTaskConcurrentFuncFlag()) {
882         LOG_ECMA(INFO) << "Function is not Concurrent Function";
883         return;
884     }
885 
886     void *taskInfo = reinterpret_cast<void*>(thread_->GetTaskInfo());
887     if (UNLIKELY(taskInfo == nullptr)) {
888         JSTaggedValue extraInfoValue = functionInfo->GetFunctionExtraInfo();
889         if (!extraInfoValue.IsJSNativePointer()) {
890             LOG_ECMA(INFO) << "FunctionExtraInfo is not JSNativePointer";
891             return;
892         }
893         JSHandle<JSNativePointer> extraInfo(thread_, extraInfoValue);
894         taskInfo = extraInfo->GetData();
895     }
896     // clear the taskInfo when return, which can prevent the callback to get it
897     thread_->SetTaskInfo(reinterpret_cast<uintptr_t>(nullptr));
898     auto localResultRef = JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread_, result));
899     ThreadNativeScope nativeScope(thread_);
900     concurrentCallback_(localResultRef, success, taskInfo, concurrentData_);
901 }
902 
DumpCallTimeInfo()903 void EcmaVM::DumpCallTimeInfo()
904 {
905     if (callTimer_ != nullptr) {
906         callTimer_->PrintAllStats();
907     }
908 }
909 
WorkersetInfo(EcmaVM * workerVm)910 void EcmaVM::WorkersetInfo(EcmaVM *workerVm)
911 {
912     LockHolder lock(mutex_);
913     auto thread = workerVm->GetJSThread();
914     if (thread != nullptr) {
915         auto tid = thread->GetThreadId();
916         if (tid != 0) {
917             workerList_.emplace(tid, workerVm);
918         }
919     }
920 }
921 
GetWorkerVm(uint32_t tid)922 EcmaVM *EcmaVM::GetWorkerVm(uint32_t tid)
923 {
924     LockHolder lock(mutex_);
925     EcmaVM *workerVm = nullptr;
926     if (!workerList_.empty()) {
927         auto iter = workerList_.find(tid);
928         if (iter != workerList_.end()) {
929             workerVm = iter->second;
930         }
931     }
932     return workerVm;
933 }
934 
DeleteWorker(EcmaVM * workerVm)935 bool EcmaVM::DeleteWorker(EcmaVM *workerVm)
936 {
937     LockHolder lock(mutex_);
938     auto thread = workerVm->GetJSThread();
939     if (thread != nullptr) {
940         auto tid = thread->GetThreadId();
941         if (tid == 0) {
942             return false;
943         }
944         auto iter = workerList_.find(tid);
945         if (iter != workerList_.end()) {
946             workerList_.erase(iter);
947             return true;
948         }
949         return false;
950     }
951     return false;
952 }
953 
SuspendWorkerVm(uint32_t tid)954 bool EcmaVM::SuspendWorkerVm(uint32_t tid)
955 {
956     LockHolder lock(mutex_);
957     if (!workerList_.empty()) {
958         auto iter = workerList_.find(tid);
959         if (iter != workerList_.end()) {
960             return DFXJSNApi::SuspendVM(iter->second);
961         }
962     }
963     return false;
964 }
965 
ResumeWorkerVm(uint32_t tid)966 void EcmaVM::ResumeWorkerVm(uint32_t tid)
967 {
968     LockHolder lock(mutex_);
969     if (!workerList_.empty()) {
970         auto iter = workerList_.find(tid);
971         if (iter != workerList_.end()) {
972             DFXJSNApi::ResumeVM(iter->second);
973         }
974     }
975 }
976 
977 /*  This moduleName is a readOnly variable for napi, represent which abc is running in current vm.
978 *   Get Current recordName: bundleName/moduleName/ets/xxx/xxx
979 *                           pkg_modules@xxx/xxx/xxx
980 *   Get Current fileName: /data/storage/el1/bundle/moduleName/ets/modules.abc
981 *   output: moduleName: moduleName
982 *   if needRecordName then fileName is: moduleName/ets/modules.abc
983 */
GetCurrentModuleInfo(bool needRecordName)984 std::pair<std::string, std::string> EcmaVM::GetCurrentModuleInfo(bool needRecordName)
985 {
986     std::pair<CString, CString> moduleInfo = EcmaInterpreter::GetCurrentEntryPoint(thread_);
987     RETURN_VALUE_IF_ABRUPT_COMPLETION(thread_, std::make_pair("", ""));
988     CString recordName = moduleInfo.first;
989     CString fileName = moduleInfo.second;
990     LOG_FULL(INFO) << "Current recordName is " << recordName <<", current fileName is " << fileName;
991     if (needRecordName) {
992         if (fileName.length() > ModulePathHelper::BUNDLE_INSTALL_PATH_LEN &&
993             fileName.find(ModulePathHelper::BUNDLE_INSTALL_PATH) == 0) {
994             fileName = fileName.substr(ModulePathHelper::BUNDLE_INSTALL_PATH_LEN);
995         } else {
996             LOG_FULL(ERROR) << " GetCurrentModuleName Fail, fileName is " << fileName;
997         }
998         return std::make_pair(recordName.c_str(), fileName.c_str());
999     }
1000     CString moduleName;
1001     if (IsNormalizedOhmUrlPack()) {
1002         moduleName = ModulePathHelper::GetModuleNameWithNormalizedName(recordName);
1003     } else {
1004         moduleName = ModulePathHelper::GetModuleName(recordName);
1005     }
1006     if (moduleName.empty()) {
1007         LOG_FULL(ERROR) << " GetCurrentModuleName Fail, recordName is " << recordName;
1008     }
1009     return std::make_pair(moduleName.c_str(), fileName.c_str());
1010 }
1011 
SetHmsModuleList(const std::vector<panda::HmsMap> & list)1012 void EcmaVM::SetHmsModuleList(const std::vector<panda::HmsMap> &list)
1013 {
1014     for (size_t i = 0; i < list.size(); i++) {
1015         HmsMap hmsMap = list[i];
1016         hmsModuleList_.emplace(hmsMap.originalPath.c_str(), hmsMap);
1017     }
1018 }
1019 
GetHmsModule(const CString & module) const1020 CString EcmaVM::GetHmsModule(const CString &module) const
1021 {
1022     auto it = hmsModuleList_.find(module);
1023     if (it == hmsModuleList_.end()) {
1024         LOG_ECMA(FATAL) << " Get Hms Module failed";
1025     }
1026     HmsMap hmsMap = it->second;
1027     return hmsMap.targetPath.c_str();
1028 }
1029 
IsHmsModule(const CString & moduleStr) const1030 bool EcmaVM::IsHmsModule(const CString &moduleStr) const
1031 {
1032     if (hmsModuleList_.empty()) {
1033         return false;
1034     }
1035     auto it = hmsModuleList_.find(moduleStr);
1036     if (it == hmsModuleList_.end()) {
1037         return false;
1038     }
1039     return true;
1040 }
1041 
SetpkgContextInfoList(const CMap<CString,CMap<CString,CVector<CString>>> & list)1042 void EcmaVM::SetpkgContextInfoList(const CMap<CString, CMap<CString, CVector<CString>>> &list)
1043 {
1044     WriteLockHolder lock(pkgContextInfoLock_);
1045     pkgContextInfoList_ = list;
1046 }
1047 
StopPreLoadSoOrAbc()1048 void EcmaVM::StopPreLoadSoOrAbc()
1049 {
1050     if (!stopPreLoadCallbacks_.empty()) {
1051         for (StopPreLoadSoCallback &cb: stopPreLoadCallbacks_) {
1052             if (cb != nullptr) {
1053                 cb();
1054             }
1055         }
1056         stopPreLoadCallbacks_.clear();
1057     }
1058 }
1059 
1060 // Initialize IcuData Path
InitializeIcuData(const JSRuntimeOptions & options)1061 void EcmaVM::InitializeIcuData(const JSRuntimeOptions &options)
1062 {
1063     std::string icuPath = options.GetIcuDataPath();
1064     if (icuPath == "default") {
1065 #if !WIN_OR_MAC_OR_IOS_PLATFORM && !defined(PANDA_TARGET_LINUX)
1066         SetHwIcuDirectory();
1067 #endif
1068     } else {
1069         std::string absPath;
1070         if (ecmascript::RealPath(icuPath, absPath)) {
1071             u_setDataDirectory(absPath.c_str());
1072         }
1073     }
1074 }
1075 
1076 // Initialize Process StartRealTime
InitializeStartRealTime()1077 int EcmaVM::InitializeStartRealTime()
1078 {
1079     int startRealTime = 0;
1080     struct timespec timespro = {0, 0};
1081     struct timespec timessys = {0, 0};
1082     auto res = clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &timespro);
1083     if (res) {
1084         return startRealTime;
1085     }
1086     auto res1 = clock_gettime(CLOCK_MONOTONIC, &timessys);
1087     if (res1) {
1088         return startRealTime;
1089     }
1090 
1091     int whenpro = int(timespro.tv_sec * 1000) + int(timespro.tv_nsec / 1000000);
1092     int whensys = int(timessys.tv_sec * 1000) + int(timessys.tv_nsec / 1000000);
1093     startRealTime = (whensys - whenpro);
1094     return startRealTime;
1095 }
1096 
GetAsyncTaskId()1097 uint32_t EcmaVM::GetAsyncTaskId()
1098 {
1099     return asyncStackTrace_->GetAsyncTaskId();
1100 }
1101 
InsertAsyncStackTrace(const JSHandle<JSPromise> & promise)1102 bool EcmaVM::InsertAsyncStackTrace(const JSHandle<JSPromise> &promise)
1103 {
1104     return asyncStackTrace_->InsertAsyncStackTrace(promise);
1105 }
1106 
RemoveAsyncStackTrace(const JSHandle<JSPromise> & promise)1107 bool EcmaVM::RemoveAsyncStackTrace(const JSHandle<JSPromise> &promise)
1108 {
1109     return asyncStackTrace_->RemoveAsyncStackTrace(promise);
1110 }
1111 }  // namespace panda::ecmascript
1112