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