1 /* 2 * Copyright (c) 2023 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 #ifndef ECMASCRIPT_OHOS_OHOS_PGO_PROCESSOR_H 17 #define ECMASCRIPT_OHOS_OHOS_PGO_PROCESSOR_H 18 19 #include "ecmascript/compiler/aot_compiler_preprocessor.h" 20 #include "ecmascript/log_wrapper.h" 21 #include "ecmascript/ohos/ohos_pkg_args.h" 22 #include "ecmascript/platform/os.h" 23 24 namespace panda::ecmascript::kungfu { 25 class OhosPgoProcessor { 26 public: MergeAndRemoveRuntimeAp(CompilationOptions &cOptions, const std::shared_ptr<OhosPkgArgs> &mainPkgArgs)27 static bool MergeAndRemoveRuntimeAp(CompilationOptions &cOptions, const std::shared_ptr<OhosPkgArgs> &mainPkgArgs) 28 { 29 if (!cOptions.needMerge_) { 30 // use baseline ap, do not need to merge and remove runtime ap(s) 31 return true; 32 } 33 if (cOptions.profilerIn_.empty()) { 34 LOG_COMPILER(WARN) << "No valid ap files found in : " << mainPkgArgs->GetPgoDir(); 35 return true; 36 } 37 std::string mergedAp(mainPkgArgs->GetMergedApPathWithoutCheck()); 38 bool isSingleAp = cOptions.profilerIn_.find(GetFileDelimiter()) == std::string::npos; 39 if (isSingleAp) { 40 if (!RenameSingleAp(cOptions.profilerIn_, mergedAp)) { 41 return false; 42 } 43 } else { 44 if (!ExportMergedAp(cOptions.profilerIn_, cOptions.hotnessThreshold_, mergedAp)) { 45 return false; 46 } 47 if (!UnlinkRuntimeAp(mainPkgArgs->GetRuntimeApPath())) { 48 return false; 49 } 50 } 51 ASSERT(mainPkgArgs != nullptr); 52 // all ohos ap(s) merged into the merged ap file. 53 cOptions.profilerIn_ = mainPkgArgs->GetMergedApPath(); 54 SetSecurityLabel(cOptions.profilerIn_); 55 ASSERT(!cOptions.profilerIn_.empty()); 56 return true; 57 } 58 59 private: 60 NO_MOVE_SEMANTIC(OhosPgoProcessor); 61 NO_COPY_SEMANTIC(OhosPgoProcessor); RenameSingleAp(const std::string &apPath, const std::string &exportAp)62 static bool RenameSingleAp(const std::string &apPath, const std::string &exportAp) 63 { 64 ASSERT(!exportAp.empty()); 65 if (apPath == exportAp) { 66 // no need to merge self. 67 return true; 68 } 69 std::string apRealPath; 70 if (!RealPath(apPath, apRealPath)) { 71 return false; 72 } 73 if (rename(apRealPath.c_str(), exportAp.c_str())) { 74 LOG_ECMA(ERROR) << "RenameSingleAp " << apRealPath << " --> " << exportAp << " failure!, errno: " << errno; 75 return false; 76 } 77 return true; 78 } 79 UnlinkRuntimeAp(const std::string &runtimeAp)80 static bool UnlinkRuntimeAp(const std::string &runtimeAp) 81 { 82 ASSERT(!runtimeAp.empty()); 83 std::string runtimeApRealPath; 84 if (!RealPath(runtimeAp, runtimeApRealPath)) { 85 return false; 86 } 87 if (!runtimeApRealPath.empty() && (Unlink(runtimeApRealPath.c_str()) == -1)) { 88 LOG_COMPILER(ERROR) << "Remove runtime ap failed. file: " << runtimeApRealPath << ", errno: " << errno; 89 return false; 90 } 91 return true; 92 } 93 ExportMergedAp(const std::string &profilerIn, uint32_t hotnessThreshold, const std::string &exportAp)94 static bool ExportMergedAp(const std::string &profilerIn, uint32_t hotnessThreshold, const std::string &exportAp) 95 { 96 ASSERT(!exportAp.empty()); 97 return pgo::PGOProfilerManager::MergeApFiles(profilerIn, exportAp, hotnessThreshold, 98 pgo::PGOProfilerEncoder::ApGenMode::MERGE); 99 } 100 }; 101 } // namespace panda::ecmascript::kungfu 102 #endif // ECMASCRIPT_OHOS_OHOS_PGO_PROCESSOR_H