1 /*
2  * Copyright (c) 2024 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_ENABLE_AOT_LIST_HELPER_H
17 #define ECMASCRIPT_OHOS_ENABLE_AOT_LIST_HELPER_H
18 
19 #include <fstream>
20 #include <memory>
21 #include <set>
22 #include <string>
23 #include <vector>
24 
25 #include "ohos_constants.h"
26 #include "ecmascript/base/string_helper.h"
27 #include "ecmascript/log_wrapper.h"
28 #include "ecmascript/platform/file.h"
29 #include "ecmascript/ohos/aot_runtime_info.h"
30 #include "macros.h"
31 
32 #ifdef AOT_ESCAPE_ENABLE
33 #include "parameters.h"
34 #endif
35 namespace panda::ecmascript::ohos {
36 class EnableAotJitListHelper {
37 constexpr static const char *const AOT_BUILD_COUNT_DISABLE = "ark.aot.build.count.disable";
38 constexpr static const char *const ARK_PROFILE = "ark.profile";
39 public:
GetInstance()40     static std::shared_ptr<EnableAotJitListHelper> GetInstance()
41     {
42         static auto helper = std::make_shared<EnableAotJitListHelper>(ENABLE_LIST_NAME);
43         return helper;
44     }
45 
EnableAotJitListHelper(const std::string &enableListName)46     explicit EnableAotJitListHelper(const std::string &enableListName)
47     {
48         ReadEnableList(enableListName);
49     }
50 
51     EnableAotJitListHelper() = default;
52     virtual ~EnableAotJitListHelper() = default;
53 
IsEnableAot(const std::string &candidate)54     bool IsEnableAot(const std::string &candidate)
55     {
56         // The enable logic is not only controlled by the whitelist, but also by the ark.profile switch
57         if (IsEnabledByArkProfiler()) {
58             return true;
59         }
60         return (enableList_.find(candidate) != enableList_.end()) ||
61                (enableList_.find(candidate + ":aot") != enableList_.end());
62     }
63 
IsEnableJit(const std::string &candidate)64     bool IsEnableJit(const std::string &candidate)
65     {
66         return (enableList_.find(candidate) != enableList_.end()) ||
67                (enableList_.find(candidate + ":jit") != enableList_.end());
68     }
69 
AddEnableListEntry(const std::string &entry)70     void AddEnableListEntry(const std::string &entry)
71     {
72         enableList_.insert(entry);
73     }
74 
Clear()75     void Clear()
76     {
77         enableList_.clear();
78     }
79 
IsEnabledByArkProfiler() const80     virtual bool IsEnabledByArkProfiler() const
81     {
82 #ifdef AOT_ESCAPE_ENABLE
83         return OHOS::system::GetBoolParameter(ARK_PROFILE, false);
84 #endif
85         return false;
86     }
87 
GetAotBuildCountDisable()88     static bool GetAotBuildCountDisable()
89     {
90 #ifdef AOT_ESCAPE_ENABLE
91         return OHOS::system::GetBoolParameter(AOT_BUILD_COUNT_DISABLE, false);
92 #endif
93         return false;
94     }
95 
AddEnableListCount(bool isCompileSuccess, const std::string &pgoPath = �) const96     void AddEnableListCount(bool isCompileSuccess, const std::string &pgoPath = "") const
97     {
98         if (!isCompileSuccess) {
99             return;
100         }
101         std::string runtimePgoRealPath = pgoPath;
102         runtimePgoRealPath.append(ohos::OhosConstants::PATH_SEPARATOR);
103         runtimePgoRealPath.append(ohos::OhosConstants::AOT_RUNTIME_INFO_NAME);
104         ohos::AotRuntimeInfo::GetInstance().BuildCompileRuntimeInfo(ohos::RuntimeInfoType::AOT_BUILD,
105             runtimePgoRealPath);
106     }
107 
IsAotCompileSuccessOnce(const std::string &pgoRealPath = �) const108     bool IsAotCompileSuccessOnce(const std::string &pgoRealPath = "") const
109     {
110         if (GetAotBuildCountDisable()) {
111             return false;
112         }
113         int count = ohos::AotRuntimeInfo::GetInstance().GetCompileCountByType(
114             ohos::RuntimeInfoType::AOT_BUILD, pgoRealPath);
115         if (count > 0) {
116             return true;
117         }
118         return false;
119     }
120 
121 private:
122     NO_COPY_SEMANTIC(EnableAotJitListHelper);
123     NO_MOVE_SEMANTIC(EnableAotJitListHelper);
124 
Trim(std::string &data)125     static void Trim(std::string &data)
126     {
127         if (data.empty()) {
128             return;
129         }
130         data.erase(0, data.find_first_not_of(' '));
131         data.erase(data.find_last_not_of(' ') + 1);
132     }
133 
ReadEnableList(const std::string &aotJitListName)134     void ReadEnableList(const std::string &aotJitListName)
135     {
136         std::string realPath;
137         if (!panda::ecmascript::RealPath(aotJitListName, realPath, false)) {
138             LOG_ECMA(DEBUG) << "Fail to get realPath: " << aotJitListName;
139             return;
140         }
141         if (!panda::ecmascript::FileExist(realPath.c_str())) {
142             LOG_ECMA(DEBUG) << "bundle enable list not exist and will pass by all. file: " << realPath;
143             return;
144         }
145 
146         std::ifstream inputFile(realPath);
147 
148         if (!inputFile.is_open()) {
149             LOG_ECMA(ERROR) << "bundle enable list open failed! file: " << aotJitListName << ", errno: " << errno;
150             return;
151         }
152 
153         std::string line;
154         while (getline(inputFile, line)) {
155             auto appName = line;
156             Trim(appName);
157             // skip empty line
158             if (appName.empty()) {
159                 continue;
160             }
161             // skip comment line
162             if (appName.at(0) == '#') {
163                 continue;
164             }
165             AddEnableListEntry(appName);
166         }
167     }
168     std::set<std::string> enableList_ {};
169     PUBLIC_API static const std::string ENABLE_LIST_NAME;
170 };
171 }  // namespace panda::ecmascript::ohos
172 #endif  // ECMASCRIPT_OHOS_ENABLE_AOT_LIST_HELPER_H
173