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