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 <cstdint>
17 #include <fstream>
18 #include <memory>
19 #include <sstream>
20 #include <string>
21 #include <unordered_map>
22 #include <utility>
23 
24 #include "ecmascript/base/file_header.h"
25 #include "ecmascript/elements.h"
26 #include "ecmascript/js_symbol.h"
27 #include "ecmascript/log_wrapper.h"
28 #include "ecmascript/object_factory.h"
29 #include "ecmascript/pgo_profiler/ap_file/pgo_file_info.h"
30 #include "ecmascript/pgo_profiler/pgo_context.h"
31 #include "ecmascript/pgo_profiler/pgo_profiler_encoder.h"
32 #include "ecmascript/pgo_profiler/types/pgo_profile_type.h"
33 #include "ecmascript/pgo_profiler/types/pgo_profiler_type.h"
34 #include "ecmascript/pgo_profiler/pgo_utils.h"
35 #include "ecmascript/platform/file.h"
36 #include "gtest/gtest.h"
37 
38 #include "assembler/assembly-emitter.h"
39 #include "assembler/assembly-parser.h"
40 #include "ecmascript/ecma_vm.h"
41 #include "ecmascript/js_thread.h"
42 #include "ecmascript/jspandafile/js_pandafile.h"
43 #include "ecmascript/jspandafile/js_pandafile_manager.h"
44 #include "ecmascript/jspandafile/method_literal.h"
45 #include "ecmascript/jspandafile/program_object.h"
46 #include "ecmascript/napi/include/jsnapi.h"
47 #include "ecmascript/pgo_profiler/ap_file/pgo_method_type_set.h"
48 #include "ecmascript/pgo_profiler/pgo_profiler_decoder.h"
49 #include "ecmascript/pgo_profiler/pgo_profiler_info.h"
50 #include "ecmascript/pgo_profiler/pgo_profiler_manager.h"
51 #include "ecmascript/pgo_profiler/tests/pgo_context_mock.h"
52 #include "ecmascript/pgo_profiler/tests/pgo_encoder_mock.h"
53 #include "ecmascript/tests/test_helper.h"
54 #include "ecmascript/napi/include/jsnapi_expo.h"
55 
56 using namespace panda;
57 using namespace panda::ecmascript;
58 using namespace panda::ecmascript::pgo;
59 using namespace panda::panda_file;
60 using namespace panda::pandasm;
61 
62 namespace panda::test {
63 class PGOProfilerTest : public testing::Test {
64 public:
65     using ApGenMode = PGOProfilerEncoder::ApGenMode;
SetUpTestCase()66     static void SetUpTestCase()
67     {
68         GTEST_LOG_(INFO) << "SetUpTestCase";
69     }
70 
TearDownTestCase()71     static void TearDownTestCase()
72     {
73         GTEST_LOG_(INFO) << "TearDownCase";
74     }
75 
76     void SetUp() override
77     {
78         strictMatch_ = PGOProfilerHeader::IsStrictMatch();
79     }
80 
81     void TearDown() override
82     {
83         JSPandaFileManager::GetInstance()->RemoveJSPandaFile(pf_.get());
84         vm_ = nullptr;
85         pf_.reset();
86         PGOProfilerManager::GetInstance()->SetDisablePGO(false);
87         PGOProfilerManager::GetInstance()->Destroy();
88         PGOProfilerHeader::SetStrictMatch(strictMatch_);
89     }
90 
91 protected:
CreateJSPandaFile(const CString filename, std::vector<MethodLiteral *> &methodLiterals)92     void CreateJSPandaFile(const CString filename, std::vector<MethodLiteral *> &methodLiterals)
93     {
94         std::string targetAbcPath = std::string(TARGET_ABC_PATH) + filename.c_str();
95         auto pfPtr = panda_file::OpenPandaFileOrZip(targetAbcPath, panda_file::File::READ_WRITE);
96         JSPandaFileManager *pfManager = JSPandaFileManager::GetInstance();
97         pf_ = pfManager->NewJSPandaFile(pfPtr.release(), filename);
98 
99         const File *file = pf_->GetPandaFile();
100         auto classes = pf_->GetClasses();
101 
102         for (size_t i = 0; i < classes.Size(); i++) {
103             panda_file::File::EntityId classId(classes[i]);
104             if (!classId.IsValid() || pf_->IsExternal(classId)) {
105                 continue;
106             }
107             ClassDataAccessor cda(*file, classId);
108             cda.EnumerateMethods([&](panda_file::MethodDataAccessor &mda) {
109                 auto *methodLiteral = new MethodLiteral(mda.GetMethodId());
110                 methodLiteral->Initialize(pf_.get());
111                 pf_->SetMethodLiteralToMap(methodLiteral);
112                 methodLiterals.push_back(methodLiteral);
113             });
114         }
115     }
116 
CreateJSPandaFile(const char *source, const CString filename, std::vector<MethodLiteral *> &methodLiterals)117     void CreateJSPandaFile(const char *source, const CString filename, std::vector<MethodLiteral *> &methodLiterals)
118     {
119         Parser parser;
120         const std::string fn = "SRC.abc";  // test file name : "SRC.abc"
121         auto res = parser.Parse(source, fn);
122 
123         std::unique_ptr<const File> pfPtr = pandasm::AsmEmitter::Emit(res.Value());
124         JSPandaFileManager *pfManager = JSPandaFileManager::GetInstance();
125         pf_ = pfManager->NewJSPandaFile(pfPtr.release(), filename);
126 
127         const File *file = pf_->GetPandaFile();
128         const uint8_t *typeDesc = utf::CStringAsMutf8("L_GLOBAL;");
129         File::EntityId classId = file->GetClassId(typeDesc);
130         EXPECT_TRUE(classId.IsValid());
131 
132         ClassDataAccessor cda(*file, classId);
133         cda.EnumerateMethods([&](panda_file::MethodDataAccessor &mda) {
134             auto *methodLiteral = new MethodLiteral(mda.GetMethodId());
135             methodLiteral->Initialize(pf_.get());
136             pf_->SetMethodLiteralToMap(methodLiteral);
137             methodLiterals.push_back(methodLiteral);
138         });
139     }
140 
ExecuteAndLoadJSPandaFile(std::string profDir, std::string recordName)141     void ExecuteAndLoadJSPandaFile(std::string profDir, std::string recordName)
142     {
143         RuntimeOption option;
144         option.SetLogLevel(LOG_LEVEL::INFO);
145         option.SetEnableProfile(true);
146         option.SetProfileDir(profDir);
147         vm_ = JSNApi::CreateJSVM(option);
148         JSNApi::EnableUserUncaughtErrorHandler(vm_);
149 
150         std::string targetAbcPath = TARGET_ABC_PATH + recordName + ".abc";
151         auto result = JSNApi::Execute(vm_, targetAbcPath, recordName, false);
152         EXPECT_TRUE(result);
153 
154         pf_ = JSPandaFileManager::GetInstance()->FindJSPandaFile(CString(targetAbcPath));
155 
156         JSNApi::DestroyJSVM(vm_);
157     }
158 
ParseRelatedPandaFileMethods( PGOProfilerDecoder &loader, std::unordered_map<std::string, std::unordered_map<std::string, std::vector<PGOMethodId>>> &methodIdInAp)159     void ParseRelatedPandaFileMethods(
160         PGOProfilerDecoder &loader,
161         std::unordered_map<std::string, std::unordered_map<std::string, std::vector<PGOMethodId>>> &methodIdInAp)
162     {
163         std::shared_ptr<PGOAbcFilePool> abcFilePool = std::make_shared<PGOAbcFilePool>();
164         ASSERT_TRUE(loader.LoadFull(abcFilePool));
165         for (const auto &recordInfo : loader.GetRecordDetailInfos().GetRecordInfos()) {
166             auto recordProfile = recordInfo.first;
167             ASSERT_EQ(recordProfile.GetKind(), ProfileType::Kind::RecordClassId);
168             if (recordProfile.IsNone()) {
169                 continue;
170             }
171             LOG_ECMA(ERROR) << "recordProfile: " << recordProfile.GetTypeString();
172             const auto *recordName =
173                 loader.GetRecordDetailInfos().GetRecordPool()->GetName(recordProfile);
174             ASSERT(recordName != nullptr);
175             const auto abcNormalizedDesc =
176                 JSPandaFile::GetNormalizedFileDesc(abcFilePool->GetEntry(recordProfile.GetAbcId())->GetData());
177             if (abcNormalizedDesc.empty()) {
178                 continue;
179             }
180 
181             const auto *info = recordInfo.second;
182             for (const auto &method : info->GetMethodInfos()) {
183                 // add ap entry info
184                 methodIdInAp[abcNormalizedDesc.c_str()][recordName].emplace_back(method.first);
185             }
186         };
187     }
188 
CheckApMethods( std::unordered_map<std::string, std::unordered_map<std::string, std::vector<PGOMethodId>>> &methodIdInAp)189     void CheckApMethods(
190         std::unordered_map<std::string, std::unordered_map<std::string, std::vector<PGOMethodId>>> &methodIdInAp)
191     {
192         for (auto abcIter = methodIdInAp.begin(); abcIter != methodIdInAp.end();) {
193             std::string fileName(abcIter->first.c_str());
194             auto lastDirToken = fileName.find_last_of('/');
195             if (lastDirToken != std::string::npos) {
196                 fileName = fileName.substr(lastDirToken + 1);
197             }
198             std::unordered_map<std::string, std::vector<PGOMethodId>> &recordMethodList = abcIter->second;
199             CheckApMethodsInApFiles(fileName, recordMethodList);
200             if (recordMethodList.empty()) {
201                 abcIter = methodIdInAp.erase(abcIter);
202             } else {
203                 abcIter++;
204             }
205         }
206         ASSERT_TRUE(methodIdInAp.empty());
207     }
208 
CheckApMethodsInApFiles(const std::string &fileName, std::unordered_map<std::string, std::vector<PGOMethodId>> &recordMethodList)209     void CheckApMethodsInApFiles(const std::string &fileName,
210                                  std::unordered_map<std::string, std::vector<PGOMethodId>> &recordMethodList)
211     {
212         std::vector<MethodLiteral *> methodLiterals {};
213         CreateJSPandaFile(fileName.c_str(), methodLiterals);
214         for (auto &methodLiteral : methodLiterals) {
215             auto methodName = MethodLiteral::GetRecordName(pf_.get(), methodLiteral->GetMethodId());
216             auto recordEntry = recordMethodList.find(methodName.c_str());
217             if (recordEntry == recordMethodList.end()) {
218                 continue;
219             }
220             for (size_t index = 0; index < recordEntry->second.size(); ++index) {
221                 if (!(recordEntry->second.at(index) == methodLiteral->GetMethodId())) {
222                     continue;
223                 }
224                 // Remove matched entry
225                 recordEntry->second.erase(recordEntry->second.begin() + index);
226                 if (recordEntry->second.empty()) {
227                     recordEntry = recordMethodList.erase(recordEntry);
228                 }
229                 break;
230             }
231         }
232     }
233 
234     static constexpr uint32_t DECODER_THRESHOLD = 2;
235     EcmaVM *vm_ = nullptr;
236     bool strictMatch_ = false;
237     std::shared_ptr<JSPandaFile> pf_;
238 };
239 
HWTEST_F_L0(PGOProfilerTest, Sample)240 HWTEST_F_L0(PGOProfilerTest, Sample)
241 {
242     std::vector<MethodLiteral *> methodLiterals {};
243     CreateJSPandaFile("sample_test.abc", methodLiterals);
244 
245     mkdir("ark-profiler/", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
246     RuntimeOption option;
247     option.SetEnableProfile(true);
248     option.SetProfileDir("ark-profiler/");
249     vm_ = JSNApi::CreateJSVM(option);
250     vm_->GetJSThread()->ManagedCodeBegin();
251     JSHandle<ConstantPool> constPool = vm_->GetFactory()->NewSConstantPool(4);
252     constPool->SetJSPandaFile(pf_.get());
253     uint32_t checksum = 304293;
254     PGOProfilerManager::GetInstance()->SamplePandaFileInfo(checksum, "ark-profiler.abc");
255     ASSERT_TRUE(vm_ != nullptr) << "Cannot create Runtime";
256 
257     JSHandle<Method> method = vm_->GetFactory()->NewSMethod(methodLiterals[0]);
258     method->SetConstantPool(vm_->GetJSThread(), constPool.GetTaggedValue());
259     JSHandle<JSTaggedValue> recordName(vm_->GetFactory()->NewFromStdString("test"));
260     JSHandle<JSFunction> func = vm_->GetFactory()->NewJSFunction(vm_->GetGlobalEnv(), method);
261     func->SetModule(vm_->GetJSThread(), recordName);
262     vm_->GetPGOProfiler()->SetSaveTimestamp(std::chrono::system_clock::now());
263     vm_->GetJSThread()->ManagedCodeEnd();
264     JSNApi::DestroyJSVM(vm_);
265     // Loader
266     PGOProfilerDecoder loader("ark-profiler/modules.ap", DECODER_THRESHOLD);
267     CString expectRecordName = "sample_test";
268 #if defined(SUPPORT_ENABLE_ASM_INTERP)
269     ASSERT_TRUE(loader.LoadAndVerify(checksum));
270     ASSERT_TRUE(!loader.Match(pf_.get(), expectRecordName, methodLiterals[0]->GetMethodId()));
271 #else
272     ASSERT_TRUE(!loader.LoadAndVerify(checksum));
273     ASSERT_TRUE(loader.Match(pf_.get(), expectRecordName, methodLiterals[0]->GetMethodId()));
274 #endif
275     unlink("ark-profiler/modules.ap");
276     rmdir("ark-profiler/");
277 }
278 
HWTEST_F_L0(PGOProfilerTest, Sample1)279 HWTEST_F_L0(PGOProfilerTest, Sample1)
280 {
281     mkdir("ark-profiler1/", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
282     std::vector<MethodLiteral *> methodLiterals {};
283     CreateJSPandaFile("sample_test.abc", methodLiterals);
284 
285     mkdir("ark-profiler1/", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
286     RuntimeOption option;
287     option.SetEnableProfile(true);
288     option.SetProfileDir("ark-profiler1/");
289     vm_ = JSNApi::CreateJSVM(option);
290     vm_->GetJSThread()->ManagedCodeBegin();
291     JSHandle<ConstantPool> constPool = vm_->GetFactory()->NewSConstantPool(4);
292     constPool->SetJSPandaFile(pf_.get());
293     uint32_t checksum = 304293;
294     PGOProfilerManager::GetInstance()->SamplePandaFileInfo(checksum, "ark-profiler1.abc");
295     ASSERT_TRUE(vm_ != nullptr) << "Cannot create Runtime";
296 
297     JSHandle<Method> method = vm_->GetFactory()->NewSMethod(methodLiterals[0]);
298     JSHandle<Method> method1 = vm_->GetFactory()->NewSMethod(methodLiterals[1]);
299     JSHandle<Method> method2 = vm_->GetFactory()->NewSMethod(methodLiterals[2]);
300     method->SetConstantPool(vm_->GetJSThread(), constPool.GetTaggedValue());
301     method1->SetConstantPool(vm_->GetJSThread(), constPool.GetTaggedValue());
302     method2->SetConstantPool(vm_->GetJSThread(), constPool.GetTaggedValue());
303 
304     JSHandle<JSFunction> func = vm_->GetFactory()->NewJSFunction(vm_->GetGlobalEnv(), method);
305     JSHandle<JSFunction> func1 = vm_->GetFactory()->NewJSFunction(vm_->GetGlobalEnv(), method1);
306     JSHandle<JSFunction> func2 = vm_->GetFactory()->NewJSFunction(vm_->GetGlobalEnv(), method2);
307     JSHandle<JSTaggedValue> recordName(vm_->GetFactory()->NewFromStdString("test"));
308     func->SetModule(vm_->GetJSThread(), recordName);
309     func1->SetModule(vm_->GetJSThread(), recordName);
310     func2->SetModule(vm_->GetJSThread(), recordName);
311     vm_->GetJSThread()->ManagedCodeEnd();
312     JSNApi::DestroyJSVM(vm_);
313 
314     // Loader
315     PGOProfilerDecoder loader("ark-profiler1/modules.ap", DECODER_THRESHOLD);
316     CString expectRecordName = "sample_test";
317 #if defined(SUPPORT_ENABLE_ASM_INTERP)
318     ASSERT_TRUE(loader.LoadAndVerify(checksum));
319     for (uint32_t idx = 0; idx < 3; idx++) {
320         loader.MatchAndMarkMethod(pf_.get(), expectRecordName,
321                                  methodLiterals[idx]->GetMethodName(pf_.get(), methodLiterals[idx]->GetMethodId()),
322                                  methodLiterals[idx]->GetMethodId());
323     }
324     ASSERT_TRUE(!loader.Match(pf_.get(), expectRecordName, methodLiterals[0]->GetMethodId()));
325     ASSERT_TRUE(!loader.Match(pf_.get(), expectRecordName, methodLiterals[2]->GetMethodId()));
326     ASSERT_TRUE(!loader.Match(pf_.get(), expectRecordName, methodLiterals[1]->GetMethodId()));
327 #else
328     ASSERT_TRUE(!loader.LoadAndVerify(checksum));
329     ASSERT_TRUE(loader.Match(pf_.get(), expectRecordName, methodLiterals[1]->GetMethodId()));
330 #endif
331     unlink("ark-profiler1/modules.ap");
332     rmdir("ark-profiler1/");
333 }
334 
HWTEST_F_L0(PGOProfilerTest, Sample2)335 HWTEST_F_L0(PGOProfilerTest, Sample2)
336 {
337     mkdir("ark-profiler2/", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
338     std::vector<MethodLiteral *> methodLiterals {};
339     CreateJSPandaFile("sample_test.abc", methodLiterals);
340 
341     mkdir("ark-profiler2/", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
342     RuntimeOption option;
343     option.SetEnableProfile(true);
344     option.SetProfileDir("ark-profiler2/");
345     vm_ = JSNApi::CreateJSVM(option);
346     vm_->GetJSThread()->ManagedCodeBegin();
347     JSHandle<ConstantPool> constPool = vm_->GetFactory()->NewSConstantPool(4);
348     constPool->SetJSPandaFile(pf_.get());
349     ASSERT_TRUE(vm_ != nullptr) << "Cannot create Runtime";
350     uint32_t checksum = 304293;
351     PGOProfilerManager::GetInstance()->SamplePandaFileInfo(checksum, "ark-profiler2.abc");
352 
353     JSHandle<Method> method = vm_->GetFactory()->NewSMethod(methodLiterals[0]);
354     JSHandle<Method> method1 = vm_->GetFactory()->NewSMethod(methodLiterals[1]);
355 
356     method->SetConstantPool(vm_->GetJSThread(), constPool.GetTaggedValue());
357     method1->SetConstantPool(vm_->GetJSThread(), constPool.GetTaggedValue());
358     JSHandle<JSFunction> func = vm_->GetFactory()->NewJSFunction(vm_->GetGlobalEnv(), method);
359     JSHandle<JSTaggedValue> recordName(vm_->GetFactory()->NewFromStdString("test"));
360     func->SetModule(vm_->GetJSThread(), recordName);
361     JSHandle<JSFunction> func1 = vm_->GetFactory()->NewJSFunction(vm_->GetGlobalEnv(), method1);
362     JSHandle<JSTaggedValue> recordName1(vm_->GetFactory()->NewFromStdString("test1"));
363     func1->SetModule(vm_->GetJSThread(), recordName1);
364     vm_->GetJSThread()->ManagedCodeEnd();
365     JSNApi::DestroyJSVM(vm_);
366 
367     // Loader
368     PGOProfilerDecoder loader("ark-profiler2/modules.ap", DECODER_THRESHOLD);
369     CString expectRecordName = "sample_test";
370     CString expectRecordName1 = "sample_test";
371 #if defined(SUPPORT_ENABLE_ASM_INTERP)
372     ASSERT_TRUE(loader.LoadAndVerify(checksum));
373     for (uint32_t idx = 0; idx < 2; idx++) {
374         loader.MatchAndMarkMethod(pf_.get(), expectRecordName,
375                                  methodLiterals[idx]->GetMethodName(pf_.get(), methodLiterals[idx]->GetMethodId()),
376                                  methodLiterals[idx]->GetMethodId());
377         loader.MatchAndMarkMethod(pf_.get(), expectRecordName1,
378                                  methodLiterals[idx]->GetMethodName(pf_.get(), methodLiterals[idx]->GetMethodId()),
379                                  methodLiterals[idx]->GetMethodId());
380     }
381     ASSERT_TRUE(!loader.Match(pf_.get(), expectRecordName, methodLiterals[0]->GetMethodId()));
382     ASSERT_TRUE(!loader.Match(pf_.get(), expectRecordName1, methodLiterals[1]->GetMethodId()));
383 #else
384     ASSERT_TRUE(!loader.LoadAndVerify(checksum));
385     ASSERT_TRUE(loader.Match(pf_.get(), expectRecordName, methodLiterals[0]->GetMethodId()));
386     ASSERT_TRUE(loader.Match(pf_.get(), expectRecordName1, methodLiterals[1]->GetMethodId()));
387 #endif
388     unlink("ark-profiler2/modules.ap");
389     rmdir("ark-profiler2/");
390 }
391 
HWTEST_F_L0(PGOProfilerTest, DisEnableSample)392 HWTEST_F_L0(PGOProfilerTest, DisEnableSample)
393 {
394     std::vector<MethodLiteral *> methodLiterals {};
395     CreateJSPandaFile("sample_test.abc", methodLiterals);
396     EXPECT_GE(methodLiterals.size(), 1);
397     mkdir("ark-profiler3/", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
398     RuntimeOption option;
399     option.SetEnableProfile(false);
400     option.SetProfileDir("ark-profiler3/");
401     vm_ = JSNApi::CreateJSVM(option);
402     vm_->GetJSThread()->ManagedCodeBegin();
403     JSPandaFileManager::GetInstance()->AddJSPandaFile(pf_);
404     JSHandle<ConstantPool> constPool = vm_->GetFactory()->NewSConstantPool(4);
405     constPool->SetJSPandaFile(pf_.get());
406     uint32_t checksum = pf_->GetChecksum();
407     PGOProfilerManager::GetInstance()->SamplePandaFileInfo(checksum, "sample_test.abc");
408     ASSERT_TRUE(vm_ != nullptr) << "Cannot create Runtime";
409 
410     JSHandle<Method> method = vm_->GetFactory()->NewSMethod(methodLiterals[0]);
411 
412     method->SetConstantPool(vm_->GetJSThread(), constPool.GetTaggedValue());
413     JSHandle<JSFunction> func = vm_->GetFactory()->NewJSFunction(vm_->GetGlobalEnv(), method);
414     JSHandle<JSTaggedValue> recordName(vm_->GetFactory()->NewFromStdString("sample_test"));
415     func->SetModule(vm_->GetJSThread(), recordName);
416     vm_->GetJSThread()->ManagedCodeEnd();
417     JSNApi::DestroyJSVM(vm_);
418 
419     // Loader
420     ASSERT_FALSE(FileExist("ark-profiler3/modules.ap"));
421     PGOProfilerDecoder loader("ark-profiler3/modules.ap", DECODER_THRESHOLD);
422     ASSERT_TRUE(!loader.LoadAndVerify(checksum));
423     CString expectRecordName = "sample_test";
424     ASSERT_TRUE(loader.Match(pf_.get(), expectRecordName, methodLiterals[0]->GetMethodId()));
425     rmdir("ark-profiler3/");
426 }
427 
HWTEST_F_L0(PGOProfilerTest, PGOProfilerManagerInvalidPath)428 HWTEST_F_L0(PGOProfilerTest, PGOProfilerManagerInvalidPath)
429 {
430     RuntimeOption option;
431     option.SetEnableProfile(true);
432     option.SetProfileDir("ark-profiler4");
433     vm_ = JSNApi::CreateJSVM(option);
434     ASSERT_TRUE(vm_ != nullptr) << "Cannot create Runtime";
435     JSNApi::DestroyJSVM(vm_);
436 }
437 
HWTEST_F_L0(PGOProfilerTest, PGOProfilerManagerInitialize)438 HWTEST_F_L0(PGOProfilerTest, PGOProfilerManagerInitialize)
439 {
440     RuntimeOption option;
441     option.SetEnableProfile(true);
442     // outDir is empty
443     option.SetProfileDir("");
444     vm_ = JSNApi::CreateJSVM(option);
445     ASSERT_TRUE(vm_ != nullptr) << "Cannot create Runtime";
446 
447     JSNApi::DestroyJSVM(vm_);
448 }
449 
HWTEST_F_L0(PGOProfilerTest, PGOProfilerManagerSample)450 HWTEST_F_L0(PGOProfilerTest, PGOProfilerManagerSample)
451 {
452     RuntimeOption option;
453     option.SetEnableProfile(true);
454     char currentPath[PATH_MAX + 2];
455     if (memset_s(currentPath, PATH_MAX, 1, PATH_MAX) != EOK) {
456         ASSERT_TRUE(false);
457     }
458     currentPath[PATH_MAX + 1] = '\0';
459     option.SetProfileDir(currentPath);
460     vm_ = JSNApi::CreateJSVM(option);
461     vm_->GetJSThread()->ManagedCodeBegin();
462     uint32_t checksum = 304293;
463     PGOProfilerManager::GetInstance()->SamplePandaFileInfo(checksum, "");
464     ASSERT_TRUE(vm_ != nullptr) << "Cannot create Runtime";
465 
466     // RecordName is hole
467     MethodLiteral *methodLiteral = new MethodLiteral(EntityId(61));
468     JSHandle<Method> method = vm_->GetFactory()->NewSMethod(methodLiteral);
469     JSHandle<JSFunction> func = vm_->GetFactory()->NewJSFunction(vm_->GetGlobalEnv(), method);
470     func->SetModule(vm_->GetJSThread(), JSTaggedValue::Hole());
471     vm_->GetJSThread()->ManagedCodeEnd();
472     JSNApi::DestroyJSVM(vm_);
473 
474     PGOProfilerDecoder loader("", DECODER_THRESHOLD);
475     // path is empty()
476     ASSERT_TRUE(loader.LoadAndVerify(checksum));
477     // path size greater than PATH_MAX
478     char path[PATH_MAX + 1] = {'0'};
479     PGOProfilerDecoder loader1(path, 4);
480     ASSERT_TRUE(!loader1.LoadAndVerify(checksum));
481 }
482 
HWTEST_F_L0(PGOProfilerTest, PGOProfilerDoubleVM)483 HWTEST_F_L0(PGOProfilerTest, PGOProfilerDoubleVM)
484 {
485     mkdir("ark-profiler5/", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
486     std::vector<MethodLiteral *> methodLiterals {};
487     CreateJSPandaFile("sample_test.abc", methodLiterals);
488     EXPECT_GE(methodLiterals.size(), 2);  // number of methods
489     mkdir("ark-profiler5/", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
490     RuntimeOption option;
491     option.SetEnableProfile(true);
492     // outDir is empty
493     option.SetProfileDir("ark-profiler5/");
494     vm_ = JSNApi::CreateJSVM(option);
495     vm_->GetJSThread()->ManagedCodeBegin();
496     JSPandaFileManager::GetInstance()->AddJSPandaFile(pf_);
497     JSHandle<ConstantPool> constPool = vm_->GetFactory()->NewSConstantPool(4);
498     constPool->SetJSPandaFile(pf_.get());
499     uint32_t checksum = 304293;
500     PGOProfilerManager::GetInstance()->SamplePandaFileInfo(checksum, "sample_test.abc");
501     ASSERT_TRUE(vm_ != nullptr) << "Cannot create Runtime";
502     // worker vm read profile enable from PGOProfilerManager singleton
503     option.SetEnableProfile(false);
504 
505     std::thread t1([&]() {
506         auto vm2 = JSNApi::CreateJSVM(option);
507         vm2->GetJSThread()->ManagedCodeBegin();
508         JSHandle<ConstantPool> constPool2 = vm2->GetFactory()->NewSConstantPool(4);
509         constPool2->SetJSPandaFile(pf_.get());
510         PGOProfilerManager::GetInstance()->SamplePandaFileInfo(checksum, "sample_test.abc");
511         ASSERT_TRUE(vm2 != nullptr) << "Cannot create Runtime";
512 
513         JSHandle<Method> method = vm2->GetFactory()->NewSMethod(methodLiterals[0]);
514         method->SetConstantPool(vm2->GetJSThread(), constPool2.GetTaggedValue());
515         JSHandle<JSFunction> func = vm2->GetFactory()->NewJSFunction(vm_->GetGlobalEnv(), method);
516         JSHandle<JSTaggedValue> recordName(vm2->GetFactory()->NewFromStdString("sample_test"));
517         func->SetModule(vm2->GetJSThread(), recordName);
518         vm2->GetJSThread()->ManagedCodeEnd();
519         JSNApi::DestroyJSVM(vm2);
520     });
521     {
522         ThreadSuspensionScope scope(vm_->GetJSThread());
523         t1.join();
524     }
525     JSHandle<JSTaggedValue> recordName(vm_->GetFactory()->NewFromStdString("sample_test"));
526     JSHandle<Method> method1 = vm_->GetFactory()->NewSMethod(methodLiterals[0]);
527     JSHandle<Method> method2 = vm_->GetFactory()->NewSMethod(methodLiterals[1]);
528     method1->SetConstantPool(vm_->GetJSThread(), constPool.GetTaggedValue());
529     method2->SetConstantPool(vm_->GetJSThread(), constPool.GetTaggedValue());
530     JSHandle<JSFunction> func1 = vm_->GetFactory()->NewJSFunction(vm_->GetGlobalEnv(), method1);
531     JSHandle<JSFunction> func2 = vm_->GetFactory()->NewJSFunction(vm_->GetGlobalEnv(), method2);
532     JSHandle<JSTaggedValue> recordName1(vm_->GetFactory()->NewFromStdString("sample_test"));
533     func1->SetModule(vm_->GetJSThread(), recordName);
534     func2->SetModule(vm_->GetJSThread(), recordName);
535 
536     vm_->GetJSThread()->ManagedCodeEnd();
537     JSNApi::DestroyJSVM(vm_);
538 
539     PGOProfilerDecoder loader("ark-profiler5/profiler", DECODER_THRESHOLD);
540     mkdir("ark-profiler5/profiler", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
541     ASSERT_TRUE(!loader.LoadAndVerify(checksum));
542     CString expectRecordName = "sample_test";
543     ASSERT_TRUE(loader.Match(pf_.get(), expectRecordName, methodLiterals[1]->GetMethodId()));
544 
545     PGOProfilerDecoder loader1("ark-profiler5/modules.ap", DECODER_THRESHOLD);
546 #if defined(SUPPORT_ENABLE_ASM_INTERP)
547     ASSERT_TRUE(loader1.LoadAndVerify(checksum));
548     ASSERT_TRUE(!loader1.Match(pf_.get(), expectRecordName, methodLiterals[1]->GetMethodId()));
549 #else
550     ASSERT_TRUE(!loader1.LoadAndVerify(checksum));
551     ASSERT_TRUE(loader1.Match(pf_.get(), expectRecordName, methodLiterals[1]->GetMethodId()));
552 #endif
553 
554     unlink("ark-profiler5/modules.ap");
555     rmdir("ark-profiler5/profiler");
556     rmdir("ark-profiler5/");
557 }
558 
HWTEST_F_L0(PGOProfilerTest, PGOProfilerDecoderNoHotMethod)559 HWTEST_F_L0(PGOProfilerTest, PGOProfilerDecoderNoHotMethod)
560 {
561     std::vector<MethodLiteral *> methodLiterals {};
562     CreateJSPandaFile("sample_test.abc", methodLiterals);
563     EXPECT_GE(methodLiterals.size(), 1);  // number of methods
564     mkdir("ark-profiler8/", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
565     RuntimeOption option;
566     option.SetEnableProfile(true);
567     option.SetProfileDir("ark-profiler8/");
568     vm_ = JSNApi::CreateJSVM(option);
569     vm_->GetJSThread()->ManagedCodeBegin();
570     JSPandaFileManager::GetInstance()->AddJSPandaFile(pf_);
571     JSHandle<ConstantPool> constPool = vm_->GetFactory()->NewSConstantPool(4);
572     constPool->SetJSPandaFile(pf_.get());
573     uint32_t checksum = pf_->GetChecksum();
574     PGOProfilerManager::GetInstance()->SamplePandaFileInfo(checksum, "sample_test.abc");
575 
576     JSHandle<Method> method = vm_->GetFactory()->NewSMethod(methodLiterals[0]);
577 
578     method->SetConstantPool(vm_->GetJSThread(), constPool.GetTaggedValue());
579     JSHandle<JSFunction> func = vm_->GetFactory()->NewJSFunction(vm_->GetGlobalEnv(), method);
580     JSHandle<JSTaggedValue> recordName(vm_->GetFactory()->NewFromStdString("sample_test"));
581     func->SetModule(vm_->GetJSThread(), recordName);
582     vm_->GetJSThread()->ManagedCodeEnd();
583     JSNApi::DestroyJSVM(vm_);
584 
585     PGOProfilerDecoder loader("ark-profiler8/modules.ap", DECODER_THRESHOLD);
586     CString expectRecordName = "sample_test";
587 #if defined(SUPPORT_ENABLE_ASM_INTERP)
588     ASSERT_TRUE(loader.LoadAndVerify(checksum));
589     ASSERT_TRUE(!loader.Match(pf_.get(), expectRecordName, methodLiterals[0]->GetMethodId()));
590 #else
591     ASSERT_TRUE(!loader.LoadAndVerify(checksum));
592     ASSERT_TRUE(loader.Match(pf_.get(), expectRecordName, methodLiterals[0]->GetMethodId()));
593 #endif
594 
595     unlink("ark-profiler8/modules.ap");
596     rmdir("ark-profiler8/");
597 }
598 
HWTEST_F_L0(PGOProfilerTest, PGOProfilerPostTask)599 HWTEST_F_L0(PGOProfilerTest, PGOProfilerPostTask)
600 {
601     std::stringstream sourceStream;
602     sourceStream << "  .language ECMAScript" << std::endl;
603     for (uint32_t funcIdx = 0; funcIdx < 100; funcIdx++) {
604         sourceStream << "  .function void foo" << std::to_string(funcIdx) << "(any a0, any a1, any a2) {}" << std::endl;
605     }
606     std::vector<MethodLiteral *> methodLiterals {};
607     CreateJSPandaFile(sourceStream.str().c_str(), "ark-profiler9.abc", methodLiterals);
608     EXPECT_EQ(methodLiterals.size(), 100);  // number of methods
609     mkdir("ark-profiler9/", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
610     RuntimeOption option;
611     option.SetEnableProfile(true);
612     option.SetProfileDir("ark-profiler9/");
613     vm_ = JSNApi::CreateJSVM(option);
614     vm_->GetJSThread()->ManagedCodeBegin();
615     JSPandaFileManager::GetInstance()->AddJSPandaFile(pf_);
616     JSHandle<ConstantPool> constPool = vm_->GetFactory()->NewSConstantPool(4);
617     constPool->SetJSPandaFile(pf_.get());
618     uint32_t checksum = 304293;
619     PGOProfilerManager::GetInstance()->SetApGenMode(ApGenMode::OVERWRITE);
620     PGOProfilerManager::GetInstance()->SamplePandaFileInfo(checksum, "ark-profiler9.abc");
621 
622     JSHandle<JSTaggedValue> recordName(vm_->GetFactory()->NewFromStdString("ark-profiler9.abc"));
623     for (int i = 61; i < 91; i++) {
624         JSHandle<Method> method = vm_->GetFactory()->NewSMethod(methodLiterals[i]);
625         method->SetConstantPool(vm_->GetJSThread(), constPool.GetTaggedValue());
626         JSHandle<JSFunction> func = vm_->GetFactory()->NewJSFunction(vm_->GetGlobalEnv(), method);
627         func->SetModule(vm_->GetJSThread(), recordName);
628     }
629 
630     vm_->GetJSThread()->ManagedCodeEnd();
631     JSNApi::DestroyJSVM(vm_);
632 
633     PGOProfilerDecoder loader("ark-profiler9/modules.ap", DECODER_THRESHOLD);
634 #if defined(SUPPORT_ENABLE_ASM_INTERP)
635     ASSERT_TRUE(loader.LoadAndVerify(checksum));
636 #else
637     ASSERT_TRUE(!loader.LoadAndVerify(checksum));
638 #endif
639     CString expectRecordName = "ark-profiler9.abc";
640     for (int i = 0; i < 100; i++) {
641         EntityId methodId = methodLiterals[i]->GetMethodId();
642         loader.MatchAndMarkMethod(pf_.get(), expectRecordName,
643                                   methodLiterals[i]->GetMethodName(pf_.get(), methodId), methodId);
644     }
645     for (int i = 61; i < 91; i++) {
646 #if defined(SUPPORT_ENABLE_ASM_INTERP)
647         if (i % 3 == 0) {
648             ASSERT_TRUE(!loader.Match(pf_.get(), expectRecordName, methodLiterals[i]->GetMethodId()));
649         } else {
650             ASSERT_TRUE(!loader.Match(pf_.get(), expectRecordName, methodLiterals[i]->GetMethodId()));
651 #else
652         if (i % 3 == 0) {
653             ASSERT_TRUE(loader.Match(pf_.get(), expectRecordName, methodLiterals[i]->GetMethodId()));
654         } else {
655             ASSERT_TRUE(loader.Match(pf_.get(), expectRecordName, methodLiterals[i]->GetMethodId()));
656 #endif
657         }
658     }
659 
660     unlink("ark-profiler9/modules.ap");
661     rmdir("ark-profiler9/");
662 }
663 
664 HWTEST_F_L0(PGOProfilerTest, TextToBinary)
665 {
666     mkdir("ark-profiler10/", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
667 
668     std::ofstream file("ark-profiler10/modules.text");
669     std::string result = "Profiler Version: 0.0.0.1\n";
670     file.write(result.c_str(), result.size());
671     result = "\nPanda file sumcheck list: [ 413775942 ]\n";
672     file.write(result.c_str(), result.size());
673     result = "\nrecordName: [ 1232/3/CALL_MODE/hello, 234/100/HOTNESS_MODE/h#ello1 ]\n";
674     file.write(result.c_str(), result.size());
675     file.close();
676 
677     PGOProfilerHeader::SetStrictMatch(false);
678     ASSERT_TRUE(PGOProfilerManager::GetInstance()->TextToBinary("ark-profiler10/modules.text", "ark-profiler10/", 2,
679                                                                 ApGenMode::OVERWRITE));
680 
681     PGOProfilerDecoder loader("ark-profiler10/modules.ap", DECODER_THRESHOLD);
682     ASSERT_TRUE(loader.LoadAndVerify(413775942));
683 
684     unlink("ark-profiler10/modules.ap");
685     unlink("ark-profiler10/modules.text");
686     rmdir("ark-profiler10");
687 }
688 
689 HWTEST_F_L0(PGOProfilerTest, FailResetProfilerInWorker)
690 {
691     std::vector<MethodLiteral *> methodLiterals {};
692     CreateJSPandaFile("sample_test.abc", methodLiterals);
693     EXPECT_GE(methodLiterals.size(), 1);  // number of methods
694     mkdir("ark-profiler12/", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
695     RuntimeOption option;
696     // Although enableProfile is set in option, but it will not work when isWorker is set.
697     option.SetEnableProfile(true);
698     option.SetIsWorker();
699     option.SetProfileDir("ark-profiler12/");
700     // PgoProfiler is disabled as default.
701     vm_ = JSNApi::CreateJSVM(option);
702     vm_->GetJSThread()->ManagedCodeBegin();
703     JSPandaFileManager::GetInstance()->AddJSPandaFile(pf_);
704     uint32_t checksum = pf_->GetChecksum();
705     PGOProfilerManager::GetInstance()->SamplePandaFileInfo(checksum, "sample_test.abc");
706     ASSERT_TRUE(vm_ != nullptr) << "Cannot create Runtime";
707 
708     JSHandle<Method> method = vm_->GetFactory()->NewSMethod(methodLiterals[0]);
709 
710     JSHandle<ConstantPool> constPool = vm_->GetFactory()->NewSConstantPool(4);
711     constPool->SetJSPandaFile(pf_.get());
712     method->SetConstantPool(vm_->GetJSThread(), constPool.GetTaggedValue());
713     JSHandle<JSFunction> func = vm_->GetFactory()->NewJSFunction(vm_->GetGlobalEnv(), method);
714     JSHandle<JSTaggedValue> recordName(vm_->GetFactory()->NewFromStdString("sample_test"));
715     func->SetModule(vm_->GetJSThread(), recordName);
716     vm_->GetJSThread()->ManagedCodeEnd();
717     JSNApi::DestroyJSVM(vm_);
718 
719     // Loader
720     ASSERT_FALSE(FileExist("ark-profiler12/modules.ap"));
721     PGOProfilerDecoder loader("ark-profiler12/modules.ap", DECODER_THRESHOLD);
722     ASSERT_TRUE(!loader.LoadAndVerify(checksum));
723     CString expectRecordName = "sample_test";
724     ASSERT_TRUE(loader.Match(pf_.get(), expectRecordName, methodLiterals[0]->GetMethodId()));
725     rmdir("ark-profiler12/");
726 }
727 
728 #if defined(SUPPORT_ENABLE_ASM_INTERP)
729 HWTEST_F_L0(PGOProfilerTest, ProfileCallTest)
730 {
731     mkdir("ark-profiler13/", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
732     const char *targetRecordName = "call_test";
733     ExecuteAndLoadJSPandaFile("ark-profiler13/", targetRecordName);
734     ASSERT_NE(pf_, nullptr);
735     uint32_t checksum = pf_->GetChecksum();
736 
737     // Loader
738     PGOProfilerDecoder decoder("ark-profiler13/modules.ap", 1);
739     PGOProfilerDecoder decoder1("ark-profiler13/modules.ap", 10);
740     PGOProfilerDecoder decoder2("ark-profiler13/modules.ap", 11000);
741     ASSERT_TRUE(decoder.LoadAndVerify(checksum));
742     ASSERT_TRUE(decoder1.LoadAndVerify(checksum));
743     ASSERT_TRUE(decoder2.LoadAndVerify(checksum));
744     auto methodLiterals = pf_->GetMethodLiteralMap();
745     for (auto iter : methodLiterals) {
746         auto methodLiteral = iter.second;
747         auto methodId = methodLiteral->GetMethodId();
748         auto methodName = methodLiteral->GetMethodName(pf_.get(), methodId);
749         decoder.MatchAndMarkMethod(pf_.get(), targetRecordName, methodName, methodId);
750         decoder1.MatchAndMarkMethod(pf_.get(), targetRecordName, methodName, methodId);
751         decoder2.MatchAndMarkMethod(pf_.get(), targetRecordName, methodName, methodId);
752         // ASSERT_TRUE(decoder.Match(pf_.get(), targetRecordName, methodId))
753         if (std::string(methodName) == "Test") {
754             ASSERT_TRUE(decoder1.Match(pf_.get(), targetRecordName, methodId));
755             ASSERT_TRUE(decoder2.Match(pf_.get(), targetRecordName, methodId));
756         } else {
757             // ASSERT_TRUE(decoder1.Match(pf_.get(), targetRecordName, methodId))
758             // ASSERT_TRUE(decoder2.Match(pf_.get(), targetRecordName, methodId))
759         }
760     }
761     unlink("ark-profiler13/modules.ap");
762     rmdir("ark-profiler13/");
763 }
764 
765 HWTEST_F_L0(PGOProfilerTest, UseClassTypeTest)
766 {
767     mkdir("ark-profiler14/", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
768     const char *targetRecordName = "class_test";
769     ExecuteAndLoadJSPandaFile("ark-profiler14/", targetRecordName);
770     ASSERT_NE(pf_, nullptr);
771     uint32_t checksum = pf_->GetChecksum();
772 
773     // Loader
774     PGOProfilerDecoder decoder("ark-profiler14/modules.ap", 1);
775     ASSERT_TRUE(decoder.LoadAndVerify(checksum));
776     auto methodLiterals = pf_->GetMethodLiteralMap();
777     for (auto iter : methodLiterals) {
778         auto methodLiteral = iter.second;
779         auto methodId = methodLiteral->GetMethodId();
780         auto methodName = methodLiteral->GetMethodName(pf_.get(), methodId);
781         decoder.MatchAndMarkMethod(pf_.get(), targetRecordName, methodName, methodId);
782         ASSERT_TRUE(!decoder.Match(pf_.get(), targetRecordName, methodId));
783         auto callback = [methodName](uint32_t offset, const PGOType *type) {
784             ASSERT_NE(offset, 0);
785             if (type->IsScalarOpType()) {
786             } else if (type->IsRwOpType()) {
787                 auto pgoRWOpType = *reinterpret_cast<const PGORWOpType *>(type);
788                 if (std::string(methodName) == "Foot" || std::string(methodName) == "Arm") {
789                     ASSERT_TRUE(pgoRWOpType.GetCount() == 1);
790                 } else if (std::string(methodName) == "foo" || std::string(methodName) == "Body") {
791                     ASSERT_TRUE(pgoRWOpType.GetCount() == 3);
792                 }
793             } else {
794                 ASSERT_TRUE(true);
795             }
796         };
797         decoder.GetTypeInfo(pf_.get(), targetRecordName, methodLiteral,
798                             callback);
799     }
800     unlink("ark-profiler14/modules.ap");
801     rmdir("ark-profiler14/");
802 }
803 
804 HWTEST_F_L0(PGOProfilerTest, DefineClassTypeTest)
805 {
806     mkdir("ark-profiler15/", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
807     const char *targetRecordName = "class_test";
808     ExecuteAndLoadJSPandaFile("ark-profiler15/", targetRecordName);
809     ASSERT_NE(pf_, nullptr);
810     uint32_t checksum = pf_->GetChecksum();
811 
812     // Loader
813     PGOProfilerDecoder decoder("ark-profiler15/modules.ap", 1);
814     ASSERT_TRUE(decoder.LoadAndVerify(checksum));
815     auto methodLiterals = pf_->GetMethodLiteralMap();
816     for (auto iter : methodLiterals) {
817         auto methodLiteral = iter.second;
818         auto methodId = methodLiteral->GetMethodId();
819         auto methodName = methodLiteral->GetMethodName(pf_.get(), methodId);
820         decoder.MatchAndMarkMethod(pf_.get(), targetRecordName, methodName, methodId);
821         ASSERT_TRUE(!decoder.Match(pf_.get(), targetRecordName, methodId));
822         auto callback = [methodName, &decoder, jsPandaFile = pf_](uint32_t offset, const PGOType *type) {
823             ASSERT_NE(offset, 0);
824             if (type->IsScalarOpType()) {
825                 auto sampleType = *reinterpret_cast<const PGOSampleType *>(type);
826                 if (sampleType.IsProfileType()) {
827                     ASSERT_EQ(std::string(methodName), "func_main_0");
828                     PGOHClassTreeDesc *desc;
829                     if (!decoder.GetHClassTreeDesc(sampleType, &desc)) {
830                         return;
831                     }
832                     return;
833                     auto classId = EntityId(sampleType.GetProfileType().GetId());
834                     auto className = MethodLiteral::GetMethodName(jsPandaFile.get(), classId);
835                     if (std::string(className) == "Arm") {
836                         auto superClassId = EntityId(desc->GetProfileType().GetId());
837                         auto superClassName = MethodLiteral::GetMethodName(jsPandaFile.get(), superClassId);
838                         ASSERT_EQ(std::string(superClassName), "Body");
839                     } else if (std::string(className) == "Foot") {
840                         auto superClassId = EntityId(desc->GetProfileType().GetId());
841                         auto superClassName = MethodLiteral::GetMethodName(jsPandaFile.get(), superClassId);
842                         ASSERT_EQ(std::string(superClassName), "Body");
843                     } else {
844                         ASSERT_EQ(desc->GetProfileType().GetRaw(), 0);
845                     }
846                 }
847             }
848         };
849         decoder.GetTypeInfo(pf_.get(), targetRecordName, methodLiteral,
850                             callback);
851     }
852     unlink("ark-profiler15/modules.ap");
853     rmdir("ark-profiler15/");
854 }
855 
856 HWTEST_F_L0(PGOProfilerTest, OpTypeTest)
857 {
858     mkdir("ark-profiler16/", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
859     const char *targetRecordName = "op_type_test";
860     ExecuteAndLoadJSPandaFile("ark-profiler16/", targetRecordName);
861     ASSERT_NE(pf_, nullptr);
862     uint32_t checksum = pf_->GetChecksum();
863 
864     // Loader
865     PGOProfilerDecoder decoder("ark-profiler16/modules.ap", 1);
866     ASSERT_TRUE(decoder.LoadAndVerify(checksum));
867     std::string types[17] =
868         { "1", "5", "4", "4", "4", "4", "4", "4", "5", "4", "4", "1", "1", "4", "5", "1", "1" };
869     int index = 0;
870     auto methodLiterals = pf_->GetMethodLiteralMap();
871     for (auto iter : methodLiterals) {
872         auto methodLiteral = iter.second;
873         auto methodId = methodLiteral->GetMethodId();
874         auto methodName = methodLiteral->GetMethodName(pf_.get(), methodId);
875         if (std::string(methodName) != "sun" && std::string(methodName) != "sun1") {
876             decoder.MatchAndMarkMethod(pf_.get(), targetRecordName, methodName, methodId);
877             ASSERT_TRUE(!decoder.Match(pf_.get(), targetRecordName, methodId));
878         }
879         auto callback = [methodName, types, &index](uint32_t offset, const PGOType *type) {
880             ASSERT_NE(offset, 0);
881             if (type->IsScalarOpType()) {
882                 auto sampleType = *reinterpret_cast<const PGOSampleType *>(type);
883                 if (sampleType.IsProfileType()) {
884                     return;
885                 }
886                 if (std::string(methodName) == "advance") {
887                     if (sampleType.GetWeight() > 0) {
888                         auto trueWeight = sampleType.GetWeight() >> 10;
889                         auto falseWeight = sampleType.GetWeight() & 0x7FF;
890                         auto primitiveType = sampleType.GetPrimitiveType();
891                         ASSERT_GT(trueWeight, falseWeight);
892                         ASSERT_EQ(static_cast<uint32_t>(primitiveType), PGOSampleType::IntType());
893                     } else {
894                         ASSERT_EQ(sampleType.GetTypeString(), types[index++]);
895                     }
896                 }
897             }
898         };
899         decoder.GetTypeInfo(pf_.get(), targetRecordName, methodLiteral,
900                             callback);
901     }
902     unlink("ark-profiler16/modules.ap");
903     rmdir("ark-profiler16/");
904 }
905 
906 HWTEST_F_L0(PGOProfilerTest, ArrayProfileTest)
907 {
908     mkdir("ark-profiler18/", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
909     const char *targetRecordName = "array_test";
910     ExecuteAndLoadJSPandaFile("ark-profiler18/", targetRecordName);
911     ASSERT_NE(pf_, nullptr);
912     uint32_t checksum = pf_->GetChecksum();
913 
914     // Loader
915     PGOProfilerDecoder decoder("ark-profiler18/modules.ap", 1);
916     ASSERT_TRUE(decoder.LoadAndVerify(checksum));
917     auto methodLiterals = pf_->GetMethodLiteralMap();
918     for (auto iter : methodLiterals) {
919         auto methodLiteral = iter.second;
920         auto methodId = methodLiteral->GetMethodId();
921         auto methodName = methodLiteral->GetMethodName(pf_.get(), methodId);
922         decoder.MatchAndMarkMethod(pf_.get(), targetRecordName, methodName, methodId);
923         ASSERT_TRUE(!decoder.Match(pf_.get(), targetRecordName, methodId));
924         auto callback = [methodName, &decoder, jsPandaFile = pf_](uint32_t offset, const PGOType *type) {
925             if (type->IsScalarOpType()) {
926                 auto sampleType = *reinterpret_cast<const PGOSampleType *>(type);
927                 if (sampleType.IsProfileType()) {
928                     ASSERT_EQ(std::string(methodName), "func_main_0");
929                     PGOHClassTreeDesc *desc;
930                     if (!decoder.GetHClassTreeDesc(sampleType, &desc)) {
931                         return;
932                     }
933                 }
934             } else if (type->IsRwOpType()) {
935                 auto pgoRWOpType = *reinterpret_cast<const PGORWOpType *>(type);
936                 if (std::string(methodName) == "foo") {
937                     ASSERT_TRUE(pgoRWOpType.GetCount() == 3);
938                     auto classType = pgoRWOpType.GetObjectInfo(0).GetProfileType();
939                     ASSERT_TRUE(classType.IsBuiltinsArray());
940                     ASSERT_EQ(classType.GetElementsKindBeforeTransition(), ElementsKind::NUMBER);
941 
942                     classType = pgoRWOpType.GetObjectInfo(1).GetProfileType();
943                     ASSERT_TRUE(classType.IsBuiltinsArray());
944                     ASSERT_EQ(classType.GetElementsKindBeforeTransition(), ElementsKind::HOLE_INT);
945 
946                     classType = pgoRWOpType.GetObjectInfo(2).GetProfileType();
947                     ASSERT_TRUE(classType.IsBuiltinsArray());
948                     ASSERT_EQ(classType.GetElementsKindBeforeTransition(), ElementsKind::TAGGED);
949                 } else if (std::string(methodName) == "foo1") {
950                     ASSERT_TRUE(pgoRWOpType.GetCount() == 2);
951                     auto classType = pgoRWOpType.GetObjectInfo(0).GetProfileType();
952                     ASSERT_TRUE(classType.IsBuiltinsArray());
953                     ASSERT_EQ(classType.GetElementsKindBeforeTransition(), ElementsKind::NUMBER);
954 
955                     classType = pgoRWOpType.GetObjectInfo(1).GetProfileType();
956                     ASSERT_TRUE(classType.IsBuiltinsArray());
957                     ASSERT_EQ(classType.GetElementsKindBeforeTransition(), ElementsKind::TAGGED);
958                 } else if (std::string(methodName) == "foo2") {
959                     ASSERT_TRUE(pgoRWOpType.GetCount() == 1);
960                     auto classType = pgoRWOpType.GetObjectInfo(0).GetProfileType();
961                     ASSERT_TRUE(classType.IsBuiltinsArray());
962                     ASSERT_EQ(classType.GetElementsKindBeforeTransition(), ElementsKind::HOLE_TAGGED);
963                 }
964             }
965         };
966         decoder.GetTypeInfo(pf_.get(), targetRecordName, methodLiteral,
967                             callback);
968     }
969     unlink("ark-profiler18/modules.ap");
970     rmdir("ark-profiler18/");
971 }
972 
973 HWTEST_F_L0(PGOProfilerTest, ObjectLiteralProfileTest)
974 {
975     mkdir("ark-profiler20/", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
976     const char *targetRecordName = "object_literal";
977     ExecuteAndLoadJSPandaFile("ark-profiler20/", targetRecordName);
978     ASSERT_NE(pf_, nullptr);
979     uint32_t checksum = pf_->GetChecksum();
980 
981     // Loader
982     PGOProfilerDecoder decoder("ark-profiler20/modules.ap", 1);
983     ASSERT_TRUE(decoder.LoadAndVerify(checksum));
984     auto methodLiterals = pf_->GetMethodLiteralMap();
985     for (auto iter : methodLiterals) {
986         auto methodLiteral = iter.second;
987         auto methodId = methodLiteral->GetMethodId();
988         auto methodName = methodLiteral->GetMethodName(pf_.get(), methodId);
989         decoder.MatchAndMarkMethod(pf_.get(), targetRecordName, methodName, methodId);
990         ASSERT_TRUE(!decoder.Match(pf_.get(), targetRecordName, methodId));
991         auto callback = [methodName, &decoder, jsPandaFile = pf_](uint32_t offset, const PGOType *type) {
992             if (type->IsScalarOpType()) {
993                 auto sampleType = *reinterpret_cast<const PGOSampleType *>(type);
994                 if (sampleType.IsProfileType()) {
995                     ASSERT_EQ(std::string(methodName), "func_main_0");
996                     PGOHClassTreeDesc *desc;
997                     if (!decoder.GetHClassTreeDesc(sampleType, &desc)) {
998                         return;
999                     }
1000                 }
1001             } else if (type->IsRwOpType()) {
1002                 auto pgoRWOpType = *reinterpret_cast<const PGORWOpType *>(type);
1003                 if (std::string(methodName) == "foo") {
1004                     ASSERT_TRUE(pgoRWOpType.GetCount() == 2);
1005                     auto classType = PGOSampleType(pgoRWOpType.GetObjectInfo(0).GetProfileType());
1006                     PGOHClassTreeDesc *desc;
1007                     ASSERT_TRUE(decoder.GetHClassTreeDesc(classType, &desc));
1008 
1009                     classType = PGOSampleType(pgoRWOpType.GetObjectInfo(1).GetProfileType());
1010                     ASSERT_TRUE(decoder.GetHClassTreeDesc(classType, &desc));
1011                 }
1012             }
1013         };
1014         decoder.GetTypeInfo(pf_.get(), targetRecordName, methodLiteral,
1015                             callback);
1016     }
1017     unlink("ark-profiler20/modules.ap");
1018     rmdir("ark-profiler20/");
1019 }
1020 
1021 HWTEST_F_L0(PGOProfilerTest, ArraySizeProfileTest)
1022 {
1023     mkdir("ark-profiler21/", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
1024     const char *targetRecordName = "array_size_test";
1025     ExecuteAndLoadJSPandaFile("ark-profiler21/", targetRecordName);
1026     ASSERT_NE(pf_, nullptr);
1027     uint32_t checksum = pf_->GetChecksum();
1028 
1029     // Loader
1030     PGOProfilerDecoder decoder("ark-profiler21/modules.ap", 1);
1031     ASSERT_TRUE(decoder.LoadAndVerify(checksum));
1032     auto methodLiterals = pf_->GetMethodLiteralMap();
1033     for (auto iter : methodLiterals) {
1034         auto methodLiteral = iter.second;
1035         auto methodId = methodLiteral->GetMethodId();
1036         auto methodName = methodLiteral->GetMethodName(pf_.get(), methodId);
1037         decoder.MatchAndMarkMethod(pf_.get(), targetRecordName, methodName, methodId);
1038         ASSERT_TRUE(!decoder.Match(pf_.get(), targetRecordName, methodId));
1039         auto callback = [methodName, jsPandaFile = pf_](uint32_t offset, const PGOType *type) {
1040             if (type->IsDefineOpType()) {
1041                 auto defineOptype = reinterpret_cast<const PGODefineOpType *>(type);
1042                     if (std::string(methodName) == "foo") {
1043                         ASSERT_EQ(defineOptype->GetElementsLength(), 4);
1044                     } else if (std::string(methodName) == "foo1") {
1045                         ASSERT_EQ(defineOptype->GetElementsLength(), 12);
1046                     } else if (std::string(methodName) == "foo2") {
1047                         ASSERT_EQ(defineOptype->GetElementsLength(), 12);
1048                     }
1049             }
1050         };
1051         decoder.GetTypeInfo(pf_.get(), targetRecordName, methodLiteral,
1052                             callback);
1053     }
1054     unlink("ark-profiler21/modules.ap");
1055     rmdir("ark-profiler21/");
1056 }
1057 
1058 HWTEST_F_L0(PGOProfilerTest, StringEqualProfileTest)
1059 {
1060     mkdir("ark-profiler22/", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
1061     const char *targetRecordName = "string_equal";
1062     ExecuteAndLoadJSPandaFile("ark-profiler22/", targetRecordName);
1063     ASSERT_NE(pf_, nullptr);
1064     uint32_t checksum = pf_->GetChecksum();
1065 
1066     // Loader
1067     PGOProfilerDecoder decoder("ark-profiler22/modules.ap", 1);
1068     ASSERT_TRUE(decoder.LoadAndVerify(checksum));
1069     auto methodLiterals = pf_->GetMethodLiteralMap();
1070     for (auto iter : methodLiterals) {
1071         auto methodLiteral = iter.second;
1072         auto methodId = methodLiteral->GetMethodId();
1073         auto methodName = methodLiteral->GetMethodName(pf_.get(), methodId);
1074         decoder.MatchAndMarkMethod(pf_.get(), targetRecordName, methodName, methodId);
1075         ASSERT_TRUE(!decoder.Match(pf_.get(), targetRecordName, methodId));
1076         auto callback = [methodName, jsPandaFile = pf_](uint32_t offset, const PGOType *type) {
1077             if (type->IsScalarOpType()) {
1078                 auto sampleType = *reinterpret_cast<const PGOSampleType *>(type);
1079                 if (sampleType.IsProfileType()) {
1080                     return;
1081                 }
1082                 if (std::string(methodName) == "foo1" ||
1083                     std::string(methodName) == "foo2") {
1084                     auto primitiveType = sampleType.GetPrimitiveType();
1085                     ASSERT_EQ(static_cast<uint32_t>(primitiveType), PGOSampleType::StringType());
1086                 }
1087             }
1088         };
1089         decoder.GetTypeInfo(pf_.get(), targetRecordName, methodLiteral,
1090                             callback);
1091     }
1092     unlink("ark-profiler22/modules.ap");
1093     rmdir("ark-profiler22/");
1094 }
1095 
1096 HWTEST_F_L0(PGOProfilerTest, BuiltinsTest)
1097 {
1098     mkdir("ark-profiler23/", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
1099     const char *targetRecordName = "builtins_test";
1100     ExecuteAndLoadJSPandaFile("ark-profiler23/", targetRecordName);
1101     ASSERT_NE(pf_, nullptr);
1102     uint32_t checksum = pf_->GetChecksum();
1103 
1104     // Loader
1105     PGOProfilerDecoder decoder("ark-profiler23/modules.ap", 1);
1106     ASSERT_TRUE(decoder.LoadAndVerify(checksum));
1107     auto methodLiterals = pf_->GetMethodLiteralMap();
1108     for (auto iter : methodLiterals) {
1109         auto methodLiteral = iter.second;
1110         auto methodId = methodLiteral->GetMethodId();
1111         auto methodName = methodLiteral->GetMethodName(pf_.get(), methodId);
1112         if (std::string(methodName) != "ArrayList") {
1113             decoder.MatchAndMarkMethod(pf_.get(), targetRecordName, methodName, methodId);
1114             ASSERT_TRUE(!decoder.Match(pf_.get(), targetRecordName, methodId));
1115         }
1116         auto callback = [methodName](uint32_t offset, const PGOType *type) {
1117             ASSERT_NE(offset, 0);
1118             if (type->IsRwOpType() && std::string(methodName) == "A") {
1119                 auto pgoRWOpType = *reinterpret_cast<const PGORWOpType *>(type);
1120                 ASSERT_TRUE(pgoRWOpType.GetCount() == 1);
1121             }
1122         };
1123         decoder.GetTypeInfo(pf_.get(), targetRecordName, methodLiteral,
1124                             callback);
1125     }
1126     unlink("ark-profiler23/modules.ap");
1127     rmdir("ark-profiler23/");
1128 }
1129 
1130 #endif
1131 
1132 #if defined(SUPPORT_ENABLE_ASM_INTERP)
1133 HWTEST_F_L0(PGOProfilerTest, FileConsistencyCheck)
1134 {
1135     mkdir("ark-profiler17/", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
1136     const char *targetRecordName = "sample_test";
1137     ExecuteAndLoadJSPandaFile("ark-profiler17/", targetRecordName);
1138     ASSERT_NE(pf_, nullptr);
1139     uint32_t checksum = pf_->GetChecksum();
1140 
1141     // write to corrupt the ap file's consistency
1142     std::ofstream fWriter("ark-profiler17/modules.ap", std::fstream::app);
1143 
1144     fWriter.write(reinterpret_cast<char *>(&checksum), sizeof(checksum));
1145     fWriter.seekp(100);
1146     fWriter.write(reinterpret_cast<char *>(&checksum), sizeof(checksum));
1147     fWriter.close();
1148 
1149     // Loader
1150     PGOProfilerDecoder loader("ark-profiler17/modules.ap", DECODER_THRESHOLD);
1151     ASSERT_FALSE(loader.LoadAndVerify(checksum));
1152     unlink("ark-profiler17/modules.ap");
1153     rmdir("ark-profiler17/");
1154 }
1155 
1156 HWTEST_F_L0(PGOProfilerTest, MergeApSelfTwice)
1157 {
1158     mkdir("ark-profiler18/", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
1159     const char *targetRecordName = "op_type_test";
1160     ExecuteAndLoadJSPandaFile("ark-profiler18/", targetRecordName);
1161     ASSERT_NE(pf_, nullptr);
1162 
1163     // Loader
1164     PGOProfilerDecoder decoder("ark-profiler18/modules_merge.ap", 1);
1165     PGOProfilerDecoder decoderSingle("ark-profiler18/modules.ap", 1);
1166     ASSERT_TRUE(PGOProfilerManager::MergeApFiles("ark-profiler18/modules.ap:ark-profiler18/modules.ap",
1167                                                  "ark-profiler18/modules_merge.ap", 1, ApGenMode::OVERWRITE));
1168     ASSERT_TRUE(decoder.LoadFull());
1169     ASSERT_TRUE(decoderSingle.LoadFull());
1170 
1171     auto doubleCount =
1172         decoder.GetRecordDetailInfos().GetRecordInfos().begin()->second->GetMethodInfos().begin()->second->GetCount();
1173     auto singleCount = decoderSingle.GetRecordDetailInfos()
1174                             .GetRecordInfos()
1175                             .begin()
1176                             ->second->GetMethodInfos()
1177                             .begin()
1178                             ->second->GetCount();
1179     ASSERT_EQ(doubleCount, singleCount + singleCount);
1180 
1181     unlink("ark-profiler18/modules.ap");
1182     unlink("ark-profiler18/modules_merge.ap");
1183     rmdir("ark-profiler18/");
1184 }
1185 #endif
1186 
1187 HWTEST_F_L0(PGOProfilerTest, RuntimeMerge)
1188 {
1189     mkdir("ark-profiler19/", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
1190     ExecuteAndLoadJSPandaFile("ark-profiler19/", "truck");
1191     ExecuteAndLoadJSPandaFile("ark-profiler19/", "call_test");
1192     ExecuteAndLoadJSPandaFile("ark-profiler19/", "truck");
1193 
1194     // Loader
1195     PGOProfilerDecoder loader("ark-profiler19/modules.ap", DECODER_THRESHOLD);
1196     CString expectRecordName = "sample_test";
1197 #if defined(SUPPORT_ENABLE_ASM_INTERP)
1198     std::unordered_map<std::string, std::unordered_map<std::string, std::vector<PGOMethodId>>> methodIdInAp;
1199     ParseRelatedPandaFileMethods(loader, methodIdInAp);
1200     ASSERT_EQ(methodIdInAp.size(), 3);
1201     CheckApMethods(methodIdInAp);
1202 #else
1203     uint32_t checksum = pf_->GetChecksum();
1204     ASSERT_TRUE(!loader.LoadAndVerify(checksum));
1205 #endif
1206     unlink("ark-profiler19/modules.ap");
1207     rmdir("ark-profiler19/");
1208 }
1209 
1210 HWTEST_F_L0(PGOProfilerTest, ProfdumpMerge)
1211 {
1212     mkdir("ark-profiler20/", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
1213 
1214     ExecuteAndLoadJSPandaFile("ark-profiler20/merge_file_1.ap", "merge_file_1");
1215     ExecuteAndLoadJSPandaFile("ark-profiler20/merge_file_2.ap", "merge_file_2");
1216     ExecuteAndLoadJSPandaFile("ark-profiler20/merge_file_3.ap", "merge_file_3");
1217 
1218     // Loader
1219     PGOProfilerDecoder loader("ark-profiler20/merged.ap", DECODER_THRESHOLD);
1220     ASSERT_TRUE(PGOProfilerManager::MergeApFiles(
1221         "ark-profiler20/merge_file_1.ap:ark-profiler20/merge_file_2.ap:ark-profiler20/merge_file_3.ap",
1222         "ark-profiler20/merged.ap", 1, ApGenMode::OVERWRITE));
1223 
1224     CString expectRecordName = "sample_test";
1225 #if defined(SUPPORT_ENABLE_ASM_INTERP)
1226     std::unordered_map<std::string, std::unordered_map<std::string, std::vector<PGOMethodId>>> methodIdInAp;
1227     ParseRelatedPandaFileMethods(loader, methodIdInAp);
1228     ASSERT_EQ(methodIdInAp.size(), 3);
1229     CheckApMethods(methodIdInAp);
1230 #else
1231     uint32_t checksum = pf_->GetChecksum();
1232     ASSERT_TRUE(!loader.LoadAndVerify(checksum));
1233 #endif
1234     unlink("ark-profiler20/merge_file_1.ap");
1235     unlink("ark-profiler20/merge_file_2.ap");
1236     unlink("ark-profiler20/merge_file_3.ap");
1237     unlink("ark-profiler20/merged.ap");
1238     rmdir("ark-profiler20/");
1239 }
1240 
1241 HWTEST_F_L0(PGOProfilerTest, ApVersionMatchCheck)
1242 {
1243     mkdir("ark-ApVersionMatchCheck/", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
1244     const char *targetRecordName = "sample_test";
1245     ExecuteAndLoadJSPandaFile("ark-ApVersionMatchCheck/", targetRecordName);
1246     ASSERT_NE(pf_, nullptr);
1247 
1248     PGOProfilerEncoderMock encoder("ark-ApVersionMatchCheck/modules.ap", DECODER_THRESHOLD,
1249                                    PGOProfilerEncoder::ApGenMode::MERGE);
1250     encoder.InitializeData();
1251     encoder.SetVersion(PGOProfilerHeader::PROFILE_TYPE_WITH_ABC_ID_MINI_VERSION);
1252     encoder.Save();
1253 
1254     PGOProfilerDecoder decoder("ark-ApVersionMatchCheck/modules.ap", DECODER_THRESHOLD);
1255     PGOProfilerHeader::SetStrictMatch(true);
1256     ASSERT_FALSE(decoder.LoadFull());
1257     PGOProfilerHeader::SetStrictMatch(false);
1258     ASSERT_TRUE(decoder.LoadFull());
1259 
1260     unlink("ark-ApVersionMatchCheck/modules.ap");
1261     unlink("ark-ApVersionMatchCheck/");
1262 }
1263 
1264 HWTEST_F_L0(PGOProfilerTest, TypedArrayOnHeap)
1265 {
1266     mkdir("ark-profiler24/", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
1267     const char *targetRecordName = "typedarray_length";
1268     ExecuteAndLoadJSPandaFile("ark-profiler24/", targetRecordName);
1269     ASSERT_NE(pf_, nullptr);
1270     uint32_t checksum = pf_->GetChecksum();
1271 
1272     // Loader
1273     PGOProfilerDecoder decoder("ark-profiler24/modules.ap", 1);
1274     ASSERT_TRUE(decoder.LoadAndVerify(checksum));
1275     auto methodLiterals = pf_->GetMethodLiteralMap();
1276     for (auto iter : methodLiterals) {
1277         auto methodLiteral = iter.second;
1278         auto methodId = methodLiteral->GetMethodId();
1279         auto methodName = methodLiteral->GetMethodName(pf_.get(), methodId);
1280         auto callback = [methodName](uint32_t offset, const PGOType *type) {
1281             ASSERT_NE(offset, 0);
1282             if (type->IsRwOpType() && std::string(methodName) == "test") {
1283                 auto pgoRWOpType = *reinterpret_cast<const PGORWOpType *>(type);
1284                 ASSERT_TRUE(pgoRWOpType.GetCount() == 1);
1285             }
1286         };
1287         decoder.GetTypeInfo(pf_.get(), targetRecordName, methodLiteral,
1288                             callback);
1289     }
1290     unlink("ark-profiler24/modules.ap");
1291     rmdir("ark-profiler24/");
1292 }
1293 
1294 HWTEST_F_L0(PGOProfilerTest, ProfileTypeConstructor)
1295 {
1296     mkdir("ark-profiler25/", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
1297     const char *targetRecordName = "typedarray_length";
1298     ExecuteAndLoadJSPandaFile("ark-profiler25/", targetRecordName);
1299     ASSERT_NE(pf_, nullptr);
1300     ApEntityId inValidId = 555;
1301     ApEntityId validId = 64;
1302     // Loader
1303     PGOProfilerDecoder decoder("ark-profiler25/modules.ap", 1);
1304     ASSERT_TRUE(decoder.LoadFull());
1305 
1306     auto invalidRes = ProfileTypeRef(inValidId);
1307     auto expectFalse = ProfileType::CreateFromProfileTypeRef(decoder.GetRecordDetailInfos(), invalidRes);
1308     EXPECT_FALSE(expectFalse.has_value());
1309 
1310     auto validRes = ProfileTypeRef(validId);
1311     auto expectTrue = ProfileType::CreateFromProfileTypeRef(decoder.GetRecordDetailInfos(), validRes);
1312     EXPECT_TRUE(expectTrue.has_value());
1313     unlink("ark-profiler25/modules.ap");
1314     rmdir("ark-profiler25/");
1315 }
1316 
1317 HWTEST_F_L0(PGOProfilerTest, CompatibleWithAOTFileTest)
1318 {
1319     constexpr uint32_t CHECKSUM = 1;
1320     PGOProfilerDecoder decoder("", DECODER_THRESHOLD);
1321     EXPECT_TRUE(decoder.LoadAndVerify(CHECKSUM));
1322     EXPECT_FALSE(decoder.IsCompatibleWithAOTFile());
1323 }
1324 
1325 HWTEST_F_L0(PGOProfilerTest, ExternalMethodLiteralTest)
1326 {
1327     mkdir("ark-profiler26/", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
1328     const char *targetRecordName = "typedarray_length";
1329     ExecuteAndLoadJSPandaFile("ark-profiler26/", targetRecordName);
1330     ASSERT_NE(pf_, nullptr);
1331     uint32_t checksum = pf_->GetChecksum();
1332 
1333     PGOProfilerDecoder decoder("ark-profiler26/modules.ap", DECODER_THRESHOLD);
1334     ASSERT_TRUE(decoder.LoadAndVerify(checksum));
1335     auto callback = []([[maybe_unused]] uint32_t offset, [[maybe_unused]] const PGOType *type) {
1336         EXPECT_TRUE(false);
1337     };
1338     decoder.GetTypeInfo(pf_.get(), targetRecordName, nullptr,
1339                         callback);
1340     unlink("ark-profiler26/modules.ap");
1341     rmdir("ark-profiler26/");
1342 }
1343 
1344 HWTEST_F_L0(PGOProfilerTest, PGOObjectInfoOperatorLessThanTest)
1345 {
1346     constexpr uint64_t rawTypeLess = 0;
1347     constexpr uint64_t rawTypeGreater = 1;
1348 
1349     ProfileType profileTypeLess(rawTypeLess);
1350     ProfileType profileTypeGreater(rawTypeGreater);
1351 
1352     PGOObjectInfo objectInfoLess(profileTypeLess, profileTypeGreater, profileTypeGreater,
1353                                  profileTypeGreater, profileTypeGreater, profileTypeGreater, PGOSampleType());
1354     PGOObjectInfo objectInfoGreater(profileTypeGreater, profileTypeLess, profileTypeGreater,
1355                                     profileTypeGreater, profileTypeGreater, profileTypeGreater, PGOSampleType());
1356 
1357     EXPECT_TRUE(objectInfoLess < objectInfoGreater);
1358     EXPECT_FALSE(objectInfoGreater < objectInfoLess);
1359 }
1360 
1361 HWTEST_F_L0(PGOProfilerTest, PGODisableWithAOTFileWorkloadTest)
1362 {
1363     mkdir("ark-profiler27/", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
1364     std::ofstream fWriter("ark-profiler27/tmp.an", std::fstream::app);
1365     fWriter.close();
1366     const char *targetRecordName = "typedarray_length";
1367     std::string targetAbcPath = std::string(TARGET_ABC_PATH) + targetRecordName + ".abc";
1368     // Force set in advance to simulate AOT/JIT enable list check is passed in UT
1369     ecmascript::AnFileDataManager::GetInstance()->SetEnable(true);
1370     ecmascript::AnFileDataManager::GetInstance()->SetDir("ark-profiler27/tmp");
1371     RuntimeOption option;
1372     option.SetEnableProfile(true);
1373     option.SetProfileDir("ark-profiler27/");
1374     EcmaVM *ecmaVM = JSNApi::CreateJSVM(option);
1375     JSNApi::LoadAotFile(ecmaVM, "");
1376     EXPECT_TRUE(ecmaVM->IsEnablePGOProfiler());
1377     auto result = JSNApi::Execute(ecmaVM, targetAbcPath, targetRecordName, false);
1378     EXPECT_TRUE(result);
1379     JSNApi::DestroyJSVM(ecmaVM);
1380     EXPECT_TRUE(FileExist("ark-profiler27/modules.ap"));
1381     unlink("ark-profiler27/modules.ap");
1382     unlink("ark-profiler27/tmp.an");
1383     rmdir("ark-profiler27/");
1384 }
1385 
1386 HWTEST_F_L0(PGOProfilerTest, PGODisableWithAOTFileAppTest)
1387 {
1388     mkdir("ark-profiler27/", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
1389     std::ofstream fWriter("ark-profiler27/tmp.an", std::fstream::app);
1390     fWriter.close();
1391     const char *targetRecordName = "typedarray_length";
1392     std::string targetAbcPath = std::string(TARGET_ABC_PATH) + targetRecordName + ".abc";
1393     // Force set in advance to simulate AOT/JIT enable list check is passed in UT
1394     ecmascript::AnFileDataManager::GetInstance()->SetEnable(true);
1395     ecmascript::AnFileDataManager::GetInstance()->SetDir("ark-profiler27/tmp");
1396     RuntimeOption option;
1397     EcmaVM *ecmaVM = JSNApi::CreateJSVM(option);
1398     option.SetEnableProfile(true);
1399     option.SetProfileDir("ark-profiler27/");
1400     JSNApi::PreFork(ecmaVM);
1401     JSNApi::PostFork(ecmaVM, option);
1402     EXPECT_TRUE(ecmaVM->IsEnablePGOProfiler());
1403     JSNApi::LoadAotFile(ecmaVM, "");
1404     EXPECT_FALSE(ecmaVM->IsEnablePGOProfiler());
1405     auto result = JSNApi::Execute(ecmaVM, targetAbcPath, targetRecordName, false);
1406     EXPECT_TRUE(result);
1407     JSNApi::DestroyJSVM(ecmaVM);
1408     EXPECT_FALSE(FileExist("ark-profiler27/modules.ap"));
1409     unlink("ark-profiler27/tmp.an");
1410     rmdir("ark-profiler27/");
1411 }
1412 
1413 HWTEST_F_L0(PGOProfilerTest, PGODisableUnderAOTFailTest)
1414 {
1415     std::map<std::string, int32_t> mockAOTCompileStatusMap;
1416     mockAOTCompileStatusMap["module1"] = 0;
1417     mockAOTCompileStatusMap["module2"] = 1;
1418     mockAOTCompileStatusMap["module3"] = 4;
1419     RuntimeOption option;
1420     {
1421         // Not update existing setting when AOT compilation uninitialized or succeed
1422         EcmaVM *ecmaVM = JSNApi::CreateJSVM(option);
1423         RuntimeOption localOption = option;
1424         localOption.SetEnableProfile(true);
1425         localOption.SetAOTCompileStatusMap(mockAOTCompileStatusMap);
1426         JSNApi::PreFork(ecmaVM);
1427         JSNApi::PostFork(ecmaVM, localOption);
1428         EXPECT_FALSE(ecmaVM->GetJSOptions().GetAOTHasException());
1429         JSNApi::DestroyJSVM(ecmaVM);
1430     }
1431     {
1432         // Disable existing setting when AOT compilation failed
1433         EcmaVM *ecmaVM = JSNApi::CreateJSVM(option);
1434         RuntimeOption localOption = option;
1435         mockAOTCompileStatusMap["module4"] = 2;
1436         localOption.SetAOTCompileStatusMap(mockAOTCompileStatusMap);
1437         JSNApi::PreFork(ecmaVM);
1438         JSNApi::PostFork(ecmaVM, localOption);
1439         EXPECT_TRUE(ecmaVM->GetJSOptions().GetAOTHasException());
1440         JSNApi::DestroyJSVM(ecmaVM);
1441     }
1442     {
1443         // Disable existing setting when AOT compilation crashed
1444         EcmaVM *ecmaVM = JSNApi::CreateJSVM(option);
1445         RuntimeOption localOption = option;
1446         mockAOTCompileStatusMap["module4"] = 3;
1447         localOption.SetAOTCompileStatusMap(mockAOTCompileStatusMap);
1448         JSNApi::PreFork(ecmaVM);
1449         JSNApi::PostFork(ecmaVM, localOption);
1450         EXPECT_TRUE(ecmaVM->GetJSOptions().GetAOTHasException());
1451         JSNApi::DestroyJSVM(ecmaVM);
1452     }
1453 }
1454 
1455 HWTEST_F_L0(PGOProfilerTest, EnableForceICTest)
1456 {
1457     RuntimeOption option;
1458     EcmaVM* ecmaVM = JSNApi::CreateJSVM(option);
1459     JSThread* jsThread = ecmaVM->GetJSThread();
1460     JSRuntimeOptions& jsOption = ecmaVM->GetJSOptions();
1461     EXPECT_TRUE(jsThread->IsEnableForceIC());
1462     EXPECT_TRUE(jsOption.IsEnableForceIC());
1463     EXPECT_TRUE(ecmascript::pgo::PGOProfilerManager::GetInstance()->IsEnableForceIC());
1464 
1465     JSNApi::PreFork(ecmaVM);
1466     JSNApi::PostFork(ecmaVM, option);
1467     EXPECT_FALSE(jsThread->IsEnableForceIC());
1468     EXPECT_FALSE(jsOption.IsEnableForceIC());
1469     EXPECT_FALSE(ecmascript::pgo::PGOProfilerManager::GetInstance()->IsEnableForceIC());
1470 
1471     JSNApi::DestroyJSVM(ecmaVM);
1472 }
1473 }  // namespace panda::test
1474