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