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, ×pro);
1083 if (res) {
1084 return startRealTime;
1085 }
1086 auto res1 = clock_gettime(CLOCK_MONOTONIC, ×sys);
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