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 24namespace panda::ecmascript::kungfu { 25class OhosPgoProcessor { 26public: 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 59private: 60 NO_MOVE_SEMANTIC(OhosPgoProcessor); 61 NO_COPY_SEMANTIC(OhosPgoProcessor); 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 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 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