• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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/jspandafile/js_pandafile.h"
17 
18 #include "common_components/taskpool/taskpool.h"
19 #include "ecmascript/jspandafile/program_object.h"
20 #include "ecmascript/runtime.h"
21 
22 namespace panda::ecmascript {
23 namespace {
24 const CString OHOS_PKG_ABC_PATH_ROOT = "/ets/";  // abc file always under /ets/ dir in HAP/HSP
25 }  // namespace
JSPandaFile(const panda_file::File * pf,const CString & descriptor,CreateMode mode)26 JSPandaFile::JSPandaFile(const panda_file::File *pf, const CString &descriptor, CreateMode mode)
27     : pf_(pf), desc_(descriptor), mode_(mode)
28 {
29     ASSERT(pf_ != nullptr);
30     CheckIsBundlePack();
31     if (isBundlePack_) {
32         InitializeUnMergedPF();
33     } else {
34         InitializeMergedPF();
35     }
36     checksum_ = pf->GetHeader()->checksum;
37     isNewVersion_ = pf_->GetHeader()->version > OLD_VERSION;
38 }
39 
CheckIsBundlePack()40 void JSPandaFile::CheckIsBundlePack()
41 {
42     Span<const uint32_t> classIndexes = pf_->GetClasses();
43     for (const uint32_t index : classIndexes) {
44         panda_file::File::EntityId classId(index);
45         if (pf_->IsExternal(classId)) {
46             continue;
47         }
48         panda_file::ClassDataAccessor cda(*pf_, classId);
49         cda.EnumerateFields([&](panda_file::FieldDataAccessor &fieldAccessor) -> void {
50             panda_file::File::EntityId fieldNameId = fieldAccessor.GetNameId();
51             panda_file::File::StringData sd = GetStringData(fieldNameId);
52             std::string_view fieldName(utf::Mutf8AsCString(sd.data), sd.utf16_length);
53             if ((IS_COMMON_JS == fieldName) || (MODULE_RECORD_IDX == fieldName)) {
54                 isBundlePack_ = false;
55             }
56         });
57         if (!isBundlePack_) {
58             return;
59         }
60     }
61 }
62 
CheckIsRecordWithBundleName(const CString & entry)63 void JSPandaFile::CheckIsRecordWithBundleName(const CString &entry)
64 {
65     size_t pos = entry.find('/');
66     if (pos == CString::npos) {
67         LOG_FULL(FATAL) << "CheckIsRecordWithBundleName Invalid parameter entry";
68     }
69 
70     CString bundleName = entry.substr(0, pos);
71     size_t bundleNameLen = bundleName.length();
72     for (auto &[recordName, _] : jsRecordInfo_) {
73         if (recordName.find(PACKAGE_PATH_SEGMENT) != std::string_view::npos ||
74             recordName.find(NPM_PATH_SEGMENT) != std::string_view::npos) {
75             continue;
76         }
77         // Confirm whether the current record is new or old by judging whether the recordName has a bundleName
78         if (!(recordName.length() > bundleNameLen && (recordName.compare(0, bundleNameLen, bundleName) == 0))) {
79             isRecordWithBundleName_ = false;
80         }
81         return;
82     }
83 }
84 
~JSPandaFile()85 JSPandaFile::~JSPandaFile()
86 {
87     for (auto& each : jsRecordInfo_) {
88         delete each.second;
89     }
90     jsRecordInfo_.clear();
91 
92     if (pf_ != nullptr) {
93         delete pf_;
94         CallReleaseSecureMemFunc(fileMapper_);
95         pf_ = nullptr;
96         fileMapper_ = nullptr;
97     }
98 
99     constpoolMap_.clear();
100     methodLiteralMap_.clear();
101     ClearNameMap();
102     if (methodLiterals_ != nullptr) {
103         JSPandaFileManager::FreeBuffer(methodLiterals_, sizeof(MethodLiteral) * numMethods_, isBundlePack_, mode_);
104         methodLiterals_ = nullptr;
105     }
106 }
107 
GetOrInsertConstantPool(ConstPoolType type,uint32_t offset,const CUnorderedMap<uint32_t,uint64_t> * constpoolMap)108 uint32_t JSPandaFile::GetOrInsertConstantPool(ConstPoolType type, uint32_t offset,
109                                               const CUnorderedMap<uint32_t, uint64_t> *constpoolMap)
110 {
111     CUnorderedMap<uint32_t, uint64_t> *map = nullptr;
112     if (constpoolMap != nullptr && !IsBundlePack()) {
113         map = const_cast<CUnorderedMap<uint32_t, uint64_t> *>(constpoolMap);
114     } else {
115         map = &constpoolMap_;
116     }
117     auto it = map->find(offset);
118     if (it != map->cend()) {
119         ConstPoolValue value(it->second);
120         return value.GetConstpoolIndex();
121     }
122     ASSERT(constpoolIndex_ != UINT32_MAX);
123     uint32_t index = constpoolIndex_++;
124     ConstPoolValue value(type, index);
125     map->emplace(offset, value.GetValue());
126     return index;
127 }
128 
InitializeUnMergedPF()129 void JSPandaFile::InitializeUnMergedPF()
130 {
131     Span<const uint32_t> classIndexes = pf_->GetClasses();
132     numClasses_ = classIndexes.size();
133     JSRecordInfo* info = new JSRecordInfo();
134     for (const uint32_t index : classIndexes) {
135         panda_file::File::EntityId classId(index);
136         if (pf_->IsExternal(classId)) {
137             continue;
138         }
139         panda_file::ClassDataAccessor cda(*pf_, classId);
140         numMethods_ += cda.GetMethodsNumber();
141         std::string_view desc(utf::Mutf8AsCString(cda.GetDescriptor()));
142         if (info->moduleRecordIdx == -1 && MODULE_CLASS == desc) {
143             cda.EnumerateFields([&](panda_file::FieldDataAccessor &fieldAccessor) -> void {
144                 panda_file::File::EntityId fieldNameId = fieldAccessor.GetNameId();
145                 panda_file::File::StringData sd = GetStringData(fieldNameId);
146                 std::string_view fieldName(utf::Mutf8AsCString(sd.data), sd.utf16_length);
147                 if (fieldName != desc_) {
148                     info->moduleRecordIdx = fieldAccessor.GetValue<int32_t>().value();
149                     info->classId = index;
150                     return;
151                 }
152             });
153         }
154         if (!info->isCjs && COMMONJS_CLASS == desc) {
155             info->classId = index;
156             info->isCjs = true;
157         }
158         if (!info->isSharedModule && IS_SHARED_MODULE == desc) {
159             info->isSharedModule = true;
160         }
161         if (!info->hasTopLevelAwait && HASTLA_CLASS == desc) {
162             info->hasTopLevelAwait = true;
163         }
164     }
165     jsRecordInfo_.insert({JSPandaFile::ENTRY_FUNCTION_NAME, info});
166     methodLiterals_ = static_cast<MethodLiteral *>(
167         JSPandaFileManager::AllocateBuffer(sizeof(MethodLiteral) * numMethods_, isBundlePack_, mode_));
168     methodLiteralMap_.reserve(numMethods_);
169 }
170 
InitializeMergedPF()171 void JSPandaFile::InitializeMergedPF()
172 {
173     Span<const uint32_t> classIndexes = pf_->GetClasses();
174     numClasses_ = classIndexes.size();
175     CString traceInfo = "JSPandaFile::InitializeMergedPF:" + ToCString(numClasses_);
176     ECMA_BYTRACE_NAME(HITRACE_LEVEL_COMMERCIAL, HITRACE_TAG_ARK, traceInfo.c_str(), "");
177     jsRecordInfo_.reserve(numClasses_);
178     for (const uint32_t index : classIndexes) {
179         panda_file::File::EntityId classId(index);
180         if (pf_->IsExternal(classId)) {
181             continue;
182         }
183         panda_file::ClassDataAccessor cda(*pf_, classId);
184         numMethods_ += cda.GetMethodsNumber();
185         JSRecordInfo* info = new JSRecordInfo();
186         info->classId = index;
187         bool hasCjsFiled = false;
188         bool hasJsonFiled = false;
189         std::string_view desc = utf::Mutf8AsCString(cda.GetDescriptor());
190         std::string_view recordName = ParseEntryPoint(desc);
191         cda.EnumerateFields([&](panda_file::FieldDataAccessor &fieldAccessor) -> void {
192             panda_file::File::EntityId fieldNameId = fieldAccessor.GetNameId();
193             panda_file::File::StringData sd = GetStringData(fieldNameId);
194             std::string_view fieldName(utf::Mutf8AsCString(sd.data), sd.utf16_length);
195             if (IS_COMMON_JS == fieldName) {
196                 hasCjsFiled = true;
197                 info->isCjs = fieldAccessor.GetValue<bool>().value();
198             } else if (IS_JSON_CONTENT == fieldName) {
199                 hasJsonFiled = true;
200                 info->isJson = true;
201                 info->jsonStringId = fieldAccessor.GetValue<uint32_t>().value();
202             } else if (MODULE_RECORD_IDX == fieldName) {
203                 info->moduleRecordIdx = fieldAccessor.GetValue<int32_t>().value();
204             } else if (IS_SHARED_MODULE == fieldName) {
205                 info->isSharedModule = fieldAccessor.GetValue<bool>().value();
206             } else if (HAS_TOP_LEVEL_AWAIT == fieldName) {
207                 info->hasTopLevelAwait = fieldAccessor.GetValue<bool>().value();
208             } else if (LAZY_IMPORT == fieldName) {
209                 info->lazyImportIdx = fieldAccessor.GetValue<uint32_t>().value();
210             } else if (sd.utf16_length > PACKAGE_NAME_LEN &&
211                        fieldName.substr(0, PACKAGE_NAME_LEN) == PACKAGE_NAME) {
212                 std::string_view packageSuffix = fieldName.substr(PACKAGE_NAME_LEN);
213                 info->npmPackageName = CString(packageSuffix);
214             } else {
215                 npmEntries_.emplace(recordName, fieldName);
216             }
217         });
218         if (hasCjsFiled || hasJsonFiled) {
219             jsRecordInfo_.emplace(recordName, info);
220         } else {
221             delete info;
222         }
223     }
224     methodLiterals_ = static_cast<MethodLiteral *>(
225         JSPandaFileManager::AllocateBuffer(sizeof(MethodLiteral) * numMethods_, isBundlePack_, mode_));
226     methodLiteralMap_.reserve(numMethods_);
227 }
228 
GetEntryPoint(const CString & recordName) const229 CString JSPandaFile::GetEntryPoint(const CString &recordName) const
230 {
231     CString entryPoint;
232     if (FindOhmUrlInPF(recordName, entryPoint) && HasRecord(entryPoint)) {
233         return entryPoint;
234     }
235     return CString();
236 }
237 
GetRecordName(const CString & entryPoint) const238 CString JSPandaFile::GetRecordName(const CString &entryPoint) const
239 {
240     if (entryPoint.empty() || entryPoint == JSPandaFile::ENTRY_FUNCTION_NAME) {
241         return GetJSPandaFileDesc();
242     }
243     return entryPoint;
244 }
245 
FindOhmUrlInPF(const CString & recordName,CString & entryPoint) const246 bool JSPandaFile::FindOhmUrlInPF(const CString &recordName, CString &entryPoint) const
247 {
248     auto info = npmEntries_.find(std::string_view(recordName.c_str(), recordName.size()));
249     if (info != npmEntries_.end()) {
250         entryPoint = info->second;
251         return true;
252     }
253     return false;
254 }
255 
GetFunctionKind(panda_file::FunctionKind funcKind)256 FunctionKind JSPandaFile::GetFunctionKind(panda_file::FunctionKind funcKind)
257 {
258     FunctionKind kind;
259     if ((static_cast<uint32_t>(funcKind) & SENDABLE_FUNCTION_MASK) != 0) {
260         funcKind = static_cast<panda_file::FunctionKind>(static_cast<uint32_t>(funcKind) & (~SENDABLE_FUNCTION_MASK));
261     }
262     switch (funcKind) {
263         case panda_file::FunctionKind::NONE:
264             kind = FunctionKind::NONE_FUNCTION;
265             break;
266         case panda_file::FunctionKind::FUNCTION:
267             kind = FunctionKind::BASE_CONSTRUCTOR;
268             break;
269         case panda_file::FunctionKind::NC_FUNCTION:
270             kind = FunctionKind::ARROW_FUNCTION;
271             break;
272         case panda_file::FunctionKind::GENERATOR_FUNCTION:
273             kind = FunctionKind::GENERATOR_FUNCTION;
274             break;
275         case panda_file::FunctionKind::ASYNC_FUNCTION:
276             kind = FunctionKind::ASYNC_FUNCTION;
277             break;
278         case panda_file::FunctionKind::ASYNC_GENERATOR_FUNCTION:
279             kind = FunctionKind::ASYNC_GENERATOR_FUNCTION;
280             break;
281         case panda_file::FunctionKind::ASYNC_NC_FUNCTION:
282             kind = FunctionKind::ASYNC_ARROW_FUNCTION;
283             break;
284         case panda_file::FunctionKind::CONCURRENT_FUNCTION:
285             kind = FunctionKind::CONCURRENT_FUNCTION;
286             break;
287         default:
288             LOG_ECMA(FATAL) << "this branch is unreachable";
289             UNREACHABLE();
290     }
291     return kind;
292 }
293 
GetFunctionKind(ConstPoolType type)294 FunctionKind JSPandaFile::GetFunctionKind(ConstPoolType type)
295 {
296     FunctionKind kind;
297     switch (type) {
298         case ConstPoolType::BASE_FUNCTION:
299             kind = FunctionKind::BASE_CONSTRUCTOR;
300             break;
301         case ConstPoolType::NC_FUNCTION:
302             kind = FunctionKind::ARROW_FUNCTION;
303             break;
304         case ConstPoolType::GENERATOR_FUNCTION:
305             kind = FunctionKind::GENERATOR_FUNCTION;
306             break;
307         case ConstPoolType::ASYNC_FUNCTION:
308             kind = FunctionKind::ASYNC_FUNCTION;
309             break;
310         case ConstPoolType::CLASS_FUNCTION:
311             kind = FunctionKind::CLASS_CONSTRUCTOR;
312             break;
313         case ConstPoolType::METHOD:
314             kind = FunctionKind::NORMAL_FUNCTION;
315             break;
316         case ConstPoolType::ASYNC_GENERATOR_FUNCTION:
317             kind = FunctionKind::ASYNC_GENERATOR_FUNCTION;
318             break;
319         default:
320             LOG_ECMA(FATAL) << "this branch is unreachable";
321             UNREACHABLE();
322     }
323     return kind;
324 }
325 
326 /*
327  handle desc like: case1: /data/storage/el1/bundle/entry/ets/modules.abc -> entry/ets/modules.abc
328  case2: /data/storage/el1/bundle/entry/ets/widgets.abc -> entry/ets/widgets.abc
329  case3: /data/app/el1/bundle/public/com.xx.xx/entry/ets/modules.abc -> entry/ets/modules.abc
330  case4: /data/app/el1/bundle/public/com.xx.xx/entry/ets/widgets.abc -> entry/ets/widgets.abc
331 */
GetNormalizedFileDesc(const CString & desc)332 CString JSPandaFile::GetNormalizedFileDesc(const CString &desc)
333 {
334     auto etsTokenPos = desc.rfind(OHOS_PKG_ABC_PATH_ROOT);
335     if (etsTokenPos == std::string::npos) {
336         // file not in OHOS package.
337         return desc;
338     }
339     auto ohosModulePos = desc.rfind('/', etsTokenPos - 1);
340     if (ohosModulePos == std::string::npos) {
341         LOG_ECMA(ERROR) << "Get abcPath from desc failed. desc: " << desc;
342         return desc;
343     }
344     // substring likes {ohosModuleName}/ets/modules.abc or {ohosModuleName}/ets/widgets.abc
345     return desc.substr(ohosModulePos + 1);
346 }
347 
GetNormalizedFileDesc() const348 CString JSPandaFile::GetNormalizedFileDesc() const
349 {
350     return GetNormalizedFileDesc(desc_);
351 }
352 
GetMethodName(EntityId methodId)353 std::pair<std::string_view, bool> JSPandaFile::GetMethodName(EntityId methodId)
354 {
355     LockHolder lock(methodNameMapMutex_);
356     uint32_t id = methodId.GetOffset();
357     auto iter = methodNameMap_.find(id);
358     if (iter != methodNameMap_.end()) {
359         panda_file::StringData sd = iter->second;
360         return {std::string_view(utf::Mutf8AsCString(sd.data), sd.utf16_length), sd.is_ascii};
361     }
362 
363     panda_file::MethodDataAccessor mda(*pf_, methodId);
364     auto sd = GetStringData(mda.GetNameId());
365     methodNameMap_.emplace(id, sd);
366     return {std::string_view(utf::Mutf8AsCString(sd.data), sd.utf16_length), sd.is_ascii};
367 }
368 
GetCpuProfilerMethodName(EntityId methodId) const369 std::pair<std::string_view, bool> JSPandaFile::GetCpuProfilerMethodName(EntityId methodId) const
370 {
371     panda_file::MethodDataAccessor mda(*pf_, methodId);
372     auto sd = GetStringData(mda.GetNameId());
373     std::string_view strView(utf::Mutf8AsCString(sd.data), sd.utf16_length);
374     return {strView, sd.is_ascii};
375 }
376 
GetRecordName(EntityId methodId)377 CString JSPandaFile::GetRecordName(EntityId methodId)
378 {
379     LockHolder lock(recordNameMapMutex_);
380     uint32_t id = methodId.GetOffset();
381     auto iter = recordNameMap_.find(id);
382     if (iter != recordNameMap_.end()) {
383         return iter->second;
384     }
385 
386     panda_file::MethodDataAccessor mda(*pf_, methodId);
387     panda_file::ClassDataAccessor cda(*pf_, mda.GetClassId());
388     CString desc = utf::Mutf8AsCString(cda.GetDescriptor());
389     auto name =  JSPandaFile::ParseEntryPoint(desc);
390     recordNameMap_.emplace(id, name);
391     return name;
392 }
393 
GetRecordNameWithBundlePack(EntityId methodIdx)394 CString JSPandaFile::GetRecordNameWithBundlePack(EntityId methodIdx)
395 {
396     CString recordName = IsBundlePack() ? ENTRY_FUNCTION_NAME : GetRecordName(methodIdx);
397     ASSERT(HasRecord(recordName));
398     return recordName;
399 }
400 
401 
ClearNameMap()402 void JSPandaFile::ClearNameMap()
403 {
404     {
405         LockHolder lock(methodNameMapMutex_);
406         methodNameMap_.clear();
407     }
408     {
409         LockHolder lock(recordNameMapMutex_);
410         recordNameMap_.clear();
411     }
412 }
413 
GetClassAndMethodIndexes(ClassTranslateWork & indexes)414 void JSPandaFile::GetClassAndMethodIndexes(ClassTranslateWork &indexes)
415 {
416     // Each thread gets 128 classes each time. If less than 128, it gets 2 classes.
417     indexes.clear();
418     LockHolder lock(classIndexMutex_);
419     if (classIndex_ >= numClasses_) {
420         return;
421     }
422     uint32_t cnts = ASYN_TRANSLATE_CLSSS_COUNT;
423     if (numClasses_ - classIndex_ < ASYN_TRANSLATE_CLSSS_COUNT) {
424         cnts = ASYN_TRANSLATE_CLSSS_MIN_COUNT;
425     }
426     for (uint32_t i = 0; i < cnts; i++) {
427         uint32_t classIdx = 0;
428         uint32_t methodIdx = 0;
429         Span<const uint32_t> classIndexes = GetClasses();
430         uint32_t index = 0;
431         do {
432             classIdx = classIndex_++;
433             if (classIdx >= numClasses_) {
434                 return;
435             }
436             index = classIndexes[classIdx];
437         } while (IsExternal(panda_file::File::EntityId(index)));
438 
439         methodIdx = methodIndex_;
440         panda_file::File::EntityId classId(classIndexes[classIdx]);
441         panda_file::ClassDataAccessor cda(*pf_, classId);
442         methodIndex_ += cda.GetMethodsNumber();
443         indexes.emplace_back(methodIdx, classIdx);
444     }
445 }
446 
Run(uint32_t threadIndex)447 bool JSPandaFile::TranslateClassesTask::Run([[maybe_unused]] uint32_t threadIndex)
448 {
449     jsPandaFile_->TranslateClassInSubThread(thread_, *methodNamePtr_, curTranslateWorks_);
450     jsPandaFile_->ReduceTaskCount();
451     return true;
452 }
453 
TranslateClassInMainThread(JSThread * thread,const CString & methodName)454 void JSPandaFile::TranslateClassInMainThread(JSThread *thread, const CString &methodName)
455 {
456     ECMA_BYTRACE_NAME(HITRACE_LEVEL_COMMERCIAL, HITRACE_TAG_ARK, "JSPandaFile::TranslateClassInMainThread", "");
457     ClassTranslateWork indexes;
458     indexes.reserve(ASYN_TRANSLATE_CLSSS_COUNT);
459     do {
460         GetClassAndMethodIndexes(indexes);
461         uint32_t size = indexes.size();
462         for (uint32_t i = 0; i < size; i++) {
463             PandaFileTranslator::TranslateClass(thread, this, methodName, indexes[i].first, indexes[i].second);
464         }
465     } while (!indexes.empty());
466 }
467 
TranslateClassInSubThread(JSThread * thread,const CString & methodName,CurClassTranslateWork & curTranslateWorks)468 void JSPandaFile::TranslateClassInSubThread(JSThread *thread, const CString &methodName,
469                                             CurClassTranslateWork &curTranslateWorks)
470 {
471     ECMA_BYTRACE_NAME(HITRACE_LEVEL_COMMERCIAL, HITRACE_TAG_ARK, "JSPandaFile::TranslateClassInSubThread", "");
472     ClassTranslateWork &indexes = curTranslateWorks.second;
473     indexes.reserve(ASYN_TRANSLATE_CLSSS_COUNT);
474     do {
475         GetClassAndMethodIndexes(indexes);
476         uint32_t size = indexes.size();
477         for (uint32_t i = 0; i < size; i++) {
478             // Stop the ongoning translating work, and leave it to the main thead to avoid waiting too long.
479             if (waitingFinish_.load(std::memory_order_acquire)) {
480                 curTranslateWorks.first = i;
481                 return;
482             }
483             PandaFileTranslator::TranslateClass(thread, this, methodName, indexes[i].first, indexes[i].second);
484         }
485     } while (!indexes.empty());
486 }
487 
PostInitializeMethodTask(JSThread * thread,const std::shared_ptr<CString> & methodNamePtr,CurClassTranslateWork & curTranslateWorks)488 void JSPandaFile::PostInitializeMethodTask(JSThread *thread, const std::shared_ptr<CString> &methodNamePtr,
489                                            CurClassTranslateWork &curTranslateWorks)
490 {
491     IncreaseTaskCount();
492     common::Taskpool::GetCurrentTaskpool()->PostTask(
493         std::make_unique<TranslateClassesTask>(thread->GetThreadId(), thread, this, methodNamePtr, curTranslateWorks));
494 }
495 
IncreaseTaskCount()496 void JSPandaFile::IncreaseTaskCount()
497 {
498     LockHolder holder(waitTranslateClassFinishedMutex_);
499     runningTaskCount_++;
500 }
501 
WaitTranslateClassTaskFinished()502 void JSPandaFile::WaitTranslateClassTaskFinished()
503 {
504     LockHolder holder(waitTranslateClassFinishedMutex_);
505     while (runningTaskCount_ > 0) {
506         waitingFinish_.store(true, std::memory_order_release);
507         waitTranslateClassFinishedCV_.Wait(&waitTranslateClassFinishedMutex_);
508     }
509 }
510 
ReduceTaskCount()511 void JSPandaFile::ReduceTaskCount()
512 {
513     LockHolder holder(waitTranslateClassFinishedMutex_);
514     runningTaskCount_--;
515     if (runningTaskCount_ == 0) {
516         waitTranslateClassFinishedCV_.SignalAll();
517     }
518 }
519 
SetAllMethodLiteralToMap()520 void JSPandaFile::SetAllMethodLiteralToMap()
521 {
522     // async to optimize SetAllMethodLiteralToMap later
523     CString traceInfo = "JSPandaFile::SetAllMethodLiteralToMap:" + ToCString(numMethods_);
524     ECMA_BYTRACE_NAME(HITRACE_LEVEL_COMMERCIAL, HITRACE_TAG_ARK, traceInfo.c_str(), "");
525     MethodLiteral *methodLiterals = GetMethodLiterals();
526     size_t methodIdx = 0;
527     while (methodIdx < numMethods_) {
528         MethodLiteral *methodLiteral = methodLiterals + (methodIdx++);
529         SetMethodLiteralToMap(methodLiteral);
530     }
531 }
532 
CheckOngoingClassTranslating(JSThread * thread,const CString & methodName,const AllClassTranslateWork & remainingTranslateWorks)533 void JSPandaFile::CheckOngoingClassTranslating(JSThread *thread, const CString &methodName,
534                                                const AllClassTranslateWork &remainingTranslateWorks)
535 {
536     WaitTranslateClassTaskFinished();
537     ECMA_BYTRACE_NAME(HITRACE_LEVEL_MAX, HITRACE_TAG_ARK, "TranslateRemainingClasses", "");
538     for (const auto &[startIndex, indexes]: remainingTranslateWorks) {
539         auto size = indexes.size();
540         for (uint32_t i = startIndex; i < size; i++) {
541             PandaFileTranslator::TranslateClass(thread, this, methodName, indexes[i].first, indexes[i].second);
542         }
543     }
544 }
545 
TranslateClasses(JSThread * thread,const CString & methodName)546 void JSPandaFile::TranslateClasses(JSThread *thread, const CString &methodName)
547 {
548     auto numThreads = common::Taskpool::GetCurrentTaskpool()->GetTotalThreadNum();
549     AllClassTranslateWork remainingTranslateWorks(numThreads);
550     const std::shared_ptr<CString> methodNamePtr = std::make_shared<CString>(methodName);
551     bool useTaskpool = numClasses_ >= USING_TASKPOOL_MIN_CLASS_COUNT;
552     if LIKELY(useTaskpool) {
553         for (uint32_t i = 0; i < numThreads; i++) {
554             PostInitializeMethodTask(thread, methodNamePtr, remainingTranslateWorks[i]);
555         }
556         common::Taskpool::GetCurrentTaskpool()->SetThreadPriority(common::PriorityMode::STW);
557         TranslateClassInMainThread(thread, methodName);
558         CheckOngoingClassTranslating(thread, methodName, remainingTranslateWorks);
559         common::Taskpool::GetCurrentTaskpool()->SetThreadPriority(common::PriorityMode::FOREGROUND);
560     } else {
561         TranslateClassInMainThread(thread, methodName);
562     }
563     SetAllMethodLiteralToMap();
564 }
565 
CallReleaseSecureMemFunc(void * fileMapper)566 void JSPandaFile::CallReleaseSecureMemFunc(void* fileMapper)
567 {
568     if (fileMapper == nullptr) {
569         return;
570     }
571     ReleaseSecureMemCallback releaseSecureMemCallBack = Runtime::GetInstance()->GetReleaseSecureMemCallback();
572     if (releaseSecureMemCallBack != nullptr) {
573         releaseSecureMemCallBack(fileMapper);
574         return;
575     }
576     LOG_ECMA(ERROR) << "JSPandaFile::CallReleaseSecureMemFunc release secure memory failed.";
577 }
578 }  // namespace panda::ecmascript
579