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 #ifndef ECMASCRIPT_COMPILER_AOT_COMPILER_PREPROCESSOR_H 16 #define ECMASCRIPT_COMPILER_AOT_COMPILER_PREPROCESSOR_H 17 18 #include "ecmascript/compiler/bytecode_info_collector.h" 19 #include "ecmascript/compiler/compiler_log.h" 20 #include "ecmascript/pgo_profiler/pgo_profiler_decoder.h" 21 #include "ecmascript/ecma_vm.h" 22 #include "libpandabase/macros.h" 23 #include "ecmascript/compiler/aot_compilation_env.h" 24 #include "ecmascript/compiler/aot_file/aot_file_manager.h" 25 #include "ecmascript/ohos/ohos_preload_app_info.h" 26 27 namespace panda::ecmascript::kungfu { 28 class OhosPkgArgs; 29 using PGOProfilerDecoder = pgo::PGOProfilerDecoder; 30 31 struct AbcFileInfo { AbcFileInfoAbcFileInfo32 explicit AbcFileInfo(std::string extendedFilePath, std::shared_ptr<JSPandaFile> jsPandaFile) 33 : extendedFilePath_(extendedFilePath), jsPandaFile_(jsPandaFile) {} 34 ~AbcFileInfo() = default; 35 36 std::string extendedFilePath_; 37 std::shared_ptr<JSPandaFile> jsPandaFile_; 38 }; 39 40 class CallMethodFlagMap { 41 public: CallMethodFlagMap()42 CallMethodFlagMap() {} 43 void SetIsFastCall(CString fileDesc, uint32_t methodOffset, bool isFastCall); 44 bool IsFastCall(CString fileDesc, uint32_t methodOffset) const; 45 void SetIsAotCompile(CString fileDesc, uint32_t methodOffset, bool isAotCompile); 46 bool IsAotCompile(CString fileDesc, uint32_t methodOffset) const; 47 void SetIsJitCompile(CString fileDesc, uint32_t methodOffset, bool isAotCompile); 48 bool IsJitCompile(CString fileDesc, uint32_t methodOffset) const; 49 private: 50 std::map<std::pair<CString, uint32_t>, bool> abcIdMethodIdToIsFastCall_ {}; 51 std::map<std::pair<CString, uint32_t>, bool> abcIdMethodIdToIsAotCompile_ {}; 52 std::map<std::pair<CString, uint32_t>, bool> abcIdMethodIdToIsJitCompile_ {}; 53 }; 54 55 struct CompilationOptions { 56 explicit PUBLIC_API CompilationOptions(JSRuntimeOptions &runtimeOptions); 57 void ParseOption(const std::string &option, std::map<std::string, std::vector<std::string>> &optionMap) const; 58 std::vector<std::string> SplitString(const std::string &str, const char ch) const; 59 std::string triple_; 60 std::string outputFileName_; 61 size_t optLevel_; 62 size_t relocMode_; 63 std::string logOption_; 64 std::string logMethodsList_; 65 bool compilerLogTime_; 66 bool deviceIsScreenOff_; 67 size_t maxAotMethodSize_; 68 size_t maxMethodsInModule_; 69 uint32_t hotnessThreshold_; 70 int32_t deviceThermalLevel_ {0}; 71 std::string profilerIn_; 72 std::string optBCRange_; 73 bool needMerge_ {false}; 74 bool isEnableArrayBoundsCheckElimination_ {true}; 75 bool isEnableTypeLowering_ {true}; 76 bool isEnableEarlyElimination_ {true}; 77 bool isEnableLaterElimination_ {true}; 78 bool isEnableValueNumbering_ {true}; 79 bool isEnableOptInlining_ {true}; 80 bool isEnableOptString_ {true}; 81 bool isEnableOptPGOType_ {true}; 82 bool isEnableOptTrackField_ {true}; 83 bool isEnableOptLoopPeeling_ {true}; 84 bool isEnableOptLoopInvariantCodeMotion_ {false}; 85 bool isEnableOptConstantFolding_ {true}; 86 bool isEnableLazyDeopt_ {false}; 87 bool isEnableLexenvSpecialization_ {false}; 88 bool isEnableNativeInline_ {true}; 89 bool isEnablePGOHCRLowering_ {false}; 90 bool isEnableLoweringBuiltin_ {true}; 91 bool isEnableOptBranchProfiling_ {true}; 92 bool isEnableEscapeAnalysis_ {false}; 93 bool isEnableInductionVariableAnalysis_ {false}; 94 bool isEnableVerifierPass_ {true}; 95 bool isEnableBaselinePgo_ {false}; 96 bool isEnableMergePoly_ {true}; 97 bool enableAotCodeComment_ {false}; 98 std::map<std::string, std::vector<std::string>> optionSelectMethods_; 99 std::map<std::string, std::vector<std::string>> optionSkipMethods_; 100 size_t anFileMaxByteSize_ {0_MB}; 101 }; 102 103 class AotCompilerPreprocessor { 104 public: AotCompilerPreprocessor(EcmaVM * vm,JSRuntimeOptions & runtimeOptions,std::map<std::string,std::shared_ptr<OhosPkgArgs>> & pkgsArgs,PGOProfilerDecoder & profilerDecoder,arg_list_t & pandaFileNames)105 AotCompilerPreprocessor(EcmaVM *vm, JSRuntimeOptions &runtimeOptions, 106 std::map<std::string, std::shared_ptr<OhosPkgArgs>> &pkgsArgs, 107 PGOProfilerDecoder &profilerDecoder, arg_list_t &pandaFileNames) 108 : vm_(vm), 109 runtimeOptions_(runtimeOptions), 110 pkgsArgs_(pkgsArgs), 111 profilerDecoder_(profilerDecoder), 112 pandaFileNames_(pandaFileNames), 113 aotCompilationEnv_(vm) {}; 114 115 ~AotCompilerPreprocessor() = default; 116 117 bool PUBLIC_API HandleTargetCompilerMode(CompilationOptions &cOptions); 118 119 bool PUBLIC_API HandlePandaFileNames(const int argc, const char **argv); 120 121 void PUBLIC_API AOTInitialize(); 122 123 void DoPreAnalysis(CompilationOptions &cOptions); 124 125 void AnalyzeGraphs(JSPandaFile *jsPandaFile, BytecodeInfoCollector &collector, CompilationOptions &cOptions); 126 127 void AnalyzeGraph(BCInfo &bytecodeInfo, CompilationOptions &cOptions, BytecodeInfoCollector &collector, 128 MethodLiteral *methodLiteral, MethodPcInfo &methodPCInfo); 129 130 void PUBLIC_API Process(CompilationOptions &cOptions); 131 132 void PUBLIC_API GenerateAbcFileInfos(std::unordered_map<CString, uint32_t> &fileNameToChecksumMap); 133 134 void GenerateBytecodeInfoCollectors(const CompilationOptions &cOptions); 135 136 bool PUBLIC_API HandleMergedPgoFile(std::unordered_map<CString, uint32_t> &fileNameToChecksumMap); 137 138 void GeneratePGOTypes(); 139 140 void SnapshotInitialize(); 141 142 bool FilterOption(const std::map<std::string, std::vector<std::string>> &optionMap, 143 const std::string &recordName, const std::string &methodName) const; 144 145 bool IsSkipMethod(const JSPandaFile *jsPandaFile, const BCInfo &bytecodeInfo, 146 const CString &recordName, const MethodLiteral *methodLiteral, 147 const MethodPcInfo &methodPCInfo, const std::string &methodName, 148 CompilationOptions &cOptions) const; 149 150 void GenerateMethodMap(CompilationOptions &cOptions); 151 152 bool MethodHasTryCatch(const JSPandaFile *jsPandaFile, const MethodLiteral *methodLiteral) const; 153 154 bool HasSkipMethod(const CVector<std::string> &methodList, const std::string &methodName) const; 155 156 bool ForbidenRebuildAOT(std::string &fileName) const; 157 158 bool PUBLIC_API HasPreloadAotFile() const; 159 160 bool PUBLIC_API HasExistsAOTFiles(CompilationOptions &cOptions) const; 161 SetIsFastCall(CString fileDesc,uint32_t methodOffset,bool isFastCall)162 void SetIsFastCall(CString fileDesc, uint32_t methodOffset, bool isFastCall) 163 { 164 callMethodFlagMap_.SetIsFastCall(fileDesc, methodOffset, isFastCall); 165 } 166 IsFastCall(CString fileDesc,uint32_t methodOffset)167 bool IsFastCall(CString fileDesc, uint32_t methodOffset) 168 { 169 return callMethodFlagMap_.IsFastCall(fileDesc, methodOffset); 170 } 171 SetIsAotCompile(CString fileDesc,uint32_t methodOffset,bool isAotCompile)172 void SetIsAotCompile(CString fileDesc, uint32_t methodOffset, bool isAotCompile) 173 { 174 callMethodFlagMap_.SetIsAotCompile(fileDesc, methodOffset, isAotCompile); 175 } 176 GetIsAotCompile(CString fileDesc,uint32_t methodOffset)177 bool GetIsAotCompile(CString fileDesc, uint32_t methodOffset) 178 { 179 return callMethodFlagMap_.IsAotCompile(fileDesc, methodOffset); 180 } 181 182 std::string PUBLIC_API GetMainPkgArgsAppSignature() const; 183 GetCompilerResult()184 bool GetCompilerResult() 185 { 186 // The size of fileInfos is not equal to pandaFiles size, set compiler result to false 187 return fileInfos_.size() == pandaFileNames_.size(); 188 } 189 GetAbcFileInfo()190 const CVector<AbcFileInfo>& GetAbcFileInfo() const 191 { 192 return fileInfos_; 193 } 194 GetBcInfoCollectors()195 const CVector<std::unique_ptr<BytecodeInfoCollector>>& GetBcInfoCollectors() const 196 { 197 return bcInfoCollectors_; 198 } 199 GetMainPkgArgs()200 std::shared_ptr<OhosPkgArgs> GetMainPkgArgs() const 201 { 202 if (pkgsArgs_.empty()) { 203 return nullptr; 204 } 205 return pkgsArgs_.at(mainPkgName_); 206 } 207 GetMainPkgName()208 std::string GetMainPkgName() const 209 { 210 return mainPkgName_; 211 } 212 GetPkgsArgs()213 const std::map<std::string, std::shared_ptr<OhosPkgArgs>> &GetPkgsArgs() const 214 { 215 return pkgsArgs_; 216 } GetCallMethodFlagMap()217 CallMethodFlagMap *GetCallMethodFlagMap() 218 { 219 return &callMethodFlagMap_; 220 } 221 GetHelper()222 static std::string GetHelper() 223 { 224 std::string str; 225 str.append(COMPILER_HELP_HEAD_MSG); 226 str.append(HELP_OPTION_MSG); 227 return str; 228 } 229 230 private: 231 NO_COPY_SEMANTIC(AotCompilerPreprocessor); 232 NO_MOVE_SEMANTIC(AotCompilerPreprocessor); 233 void HandleTargetModeInfo(CompilationOptions &cOptions); 234 235 std::shared_ptr<JSPandaFile> CreateAndVerifyJSPandaFile(const std::string &fileName); 236 237 void ResolveModule(const JSPandaFile *jsPandaFile, const std::string &fileName); 238 OutCompiledMethodsRange()239 bool OutCompiledMethodsRange() const 240 { 241 static uint32_t compiledMethodsCount = 0; 242 ++compiledMethodsCount; 243 return compiledMethodsCount < runtimeOptions_.GetCompilerMethodsRange().first || 244 runtimeOptions_.GetCompilerMethodsRange().second <= compiledMethodsCount; 245 } 246 247 EcmaVM *vm_; 248 JSRuntimeOptions &runtimeOptions_; 249 std::map<std::string, std::shared_ptr<OhosPkgArgs>> &pkgsArgs_; 250 std::string mainPkgName_; 251 PGOProfilerDecoder &profilerDecoder_; 252 arg_list_t &pandaFileNames_; 253 CVector<AbcFileInfo> fileInfos_; 254 CVector<std::unique_ptr<BytecodeInfoCollector>> bcInfoCollectors_; 255 CallMethodFlagMap callMethodFlagMap_; 256 AOTCompilationEnv aotCompilationEnv_; 257 CVector<std::string> irreducibleMethods_; 258 friend class OhosPkgArgs; 259 }; 260 } // namespace panda::ecmascript::kungfu 261 #endif // ECMASCRIPT_COMPILER_AOT_COMPILER_PREPROCESSOR_H 262