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