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