1 /*
2  * Copyright (c) 2021-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 #ifndef ES2PANDA_COMPILER_CORE_COMPILEQUEUE_H
17 #define ES2PANDA_COMPILER_CORE_COMPILEQUEUE_H
18 
19 #include <aot/options.h>
20 #include <macros.h>
21 #include <os/thread.h>
22 #include <util/symbolTable.h>
23 #include <util/workerQueue.h>
24 
25 #include <condition_variable>
26 #include <mutex>
27 
28 #include <abc2program/abc2program_compiler.h>
29 
30 namespace panda::es2panda::binder {
31 class FunctionScope;
32 }  // namespace panda::es2panda::binder
33 
34 namespace panda::es2panda::compiler {
35 
36 class CompilerContext;
37 
38 class CompileFunctionJob : public util::WorkerJob {
39 public:
CompileFunctionJob(CompilerContext *context)40     explicit CompileFunctionJob(CompilerContext *context) : context_(context) {};
41     NO_COPY_SEMANTIC(CompileFunctionJob);
42     NO_MOVE_SEMANTIC(CompileFunctionJob);
43     ~CompileFunctionJob() override = default;
44 
Scope() const45     binder::FunctionScope *Scope() const
46     {
47         return scope_;
48     }
49 
SetFunctionScope(binder::FunctionScope *scope)50     void SetFunctionScope(binder::FunctionScope *scope)
51     {
52         scope_ = scope;
53     }
54 
55     void Run() override;
56 
57 private:
58     CompilerContext *context_ {};
59     binder::FunctionScope *scope_ {};
60 };
61 
62 class CompileModuleRecordJob : public util::WorkerJob {
63 public:
CompileModuleRecordJob(CompilerContext *context)64     explicit CompileModuleRecordJob(CompilerContext *context) : context_(context) {};
65     NO_COPY_SEMANTIC(CompileModuleRecordJob);
66     NO_MOVE_SEMANTIC(CompileModuleRecordJob);
67     ~CompileModuleRecordJob() override = default;
68 
69     void Run() override;
70 
71 private:
72     CompilerContext *context_ {};
73 };
74 
75 class CompileFileJob : public util::WorkerJob {
76 public:
CompileFileJob(es2panda::SourceFile *src, es2panda::CompilerOptions *options, std::map<std::string, panda::es2panda::util::ProgramCache*> &progsInfo, std::unordered_set<std::string> &optimizationPendingProgs, util::SymbolTable *symbolTable, panda::ArenaAllocator *allocator)77     explicit CompileFileJob(es2panda::SourceFile *src, es2panda::CompilerOptions *options,
78                             std::map<std::string, panda::es2panda::util::ProgramCache*> &progsInfo,
79                             std::unordered_set<std::string> &optimizationPendingProgs,
80                             util::SymbolTable *symbolTable, panda::ArenaAllocator *allocator)
81         : src_(src), options_(options), progsInfo_(progsInfo), optimizationPendingProgs_(optimizationPendingProgs),
82           symbolTable_(symbolTable), allocator_(allocator) {};
83     NO_COPY_SEMANTIC(CompileFileJob);
84     NO_MOVE_SEMANTIC(CompileFileJob);
85     ~CompileFileJob() override = default;
86 
87     void Run() override;
88 
89 private:
90     friend class CompileAbcClassJob;
91     bool RetrieveProgramFromCacheFiles(const std::string &buffer);
92     void CompileProgram();
93     void OptimizeAndCacheProgram(panda::pandasm::Program *prog);
94 
95     static std::mutex globalMutex_;
96     es2panda::SourceFile *src_;
97     es2panda::CompilerOptions *options_;
98     std::map<std::string, panda::es2panda::util::ProgramCache*> &progsInfo_;
99     std::unordered_set<std::string> &optimizationPendingProgs_;
100     util::SymbolTable *symbolTable_;
101     panda::ArenaAllocator *allocator_;
102 };
103 
104 class CompileAbcClassJob : public util::WorkerJob {
105 public:
CompileAbcClassJob(const uint32_t classId, const es2panda::CompilerOptions &options, abc2program::Abc2ProgramCompiler &compiler, std::map<std::string, panda::es2panda::util::ProgramCache*> &progsInfo, panda::ArenaAllocator *allocator, std::string abcPkgName, bool pkgVersionUpdateRequiredInAbc = true)106     explicit CompileAbcClassJob(const uint32_t classId,
107                                 const es2panda::CompilerOptions &options,
108                                 abc2program::Abc2ProgramCompiler &compiler,
109                                 std::map<std::string, panda::es2panda::util::ProgramCache*> &progsInfo,
110                                 panda::ArenaAllocator *allocator,
111                                 std::string abcPkgName,
112                                 bool pkgVersionUpdateRequiredInAbc = true)
113         : classId_(classId), options_(options), compiler_(compiler), progsInfo_(progsInfo),
114           allocator_(allocator), abcPkgName_(abcPkgName),
115           pkgVersionUpdateRequiredInAbc_(pkgVersionUpdateRequiredInAbc) {};
116 
SetHasUpdatedVersion(bool hasUpdatedVersion)117     void SetHasUpdatedVersion(bool hasUpdatedVersion)
118     {
119         hasUpdatedVersion_ = hasUpdatedVersion;
120     }
121 
122     NO_COPY_SEMANTIC(CompileAbcClassJob);
123     NO_MOVE_SEMANTIC(CompileAbcClassJob);
124     ~CompileAbcClassJob() override = default;
125 
126     void Run() override;
127 
128 private:
129     void UpdatePackageVersion(panda::pandasm::Program *prog, const CompilerOptions &options);
130     void UpdateDynamicImportPackageVersion(panda::pandasm::Program *prog,
131         const std::unordered_map<std::string, panda::es2panda::PkgInfo> &pkgContextInfo);
132     void UpdateStaticImportPackageVersion(panda::pandasm::Program *prog,
133         const std::unordered_map<std::string, panda::es2panda::PkgInfo> &pkgContextInfo);
134 
135     const uint32_t classId_;
136     const es2panda::CompilerOptions &options_;
137     abc2program::Abc2ProgramCompiler &compiler_;
138     std::map<std::string, panda::es2panda::util::ProgramCache*> &progsInfo_;
139     panda::ArenaAllocator *allocator_;
140     std::string abcPkgName_;
141     bool pkgVersionUpdateRequiredInAbc_;
142     bool hasUpdatedVersion_ {false};
143 };
144 
145 class PostAnalysisOptimizeFileJob : public util::WorkerJob {
146 public:
PostAnalysisOptimizeFileJob(const std::string &fileName, pandasm::Program *program)147     explicit PostAnalysisOptimizeFileJob(const std::string &fileName, pandasm::Program *program)
148         : fileName_(std::move(fileName)), program_(program) {}
149     NO_COPY_SEMANTIC(PostAnalysisOptimizeFileJob);
150     NO_MOVE_SEMANTIC(PostAnalysisOptimizeFileJob);
151     ~PostAnalysisOptimizeFileJob() override = default;
152 
153     void Run() override;
154 
155 private:
156     std::string fileName_;
157     pandasm::Program *program_;
158 };
159 
160 class CompileFuncQueue : public util::WorkerQueue {
161 public:
CompileFuncQueue(size_t threadCount, CompilerContext *context)162     explicit CompileFuncQueue(size_t threadCount, CompilerContext *context)
163         : util::WorkerQueue(threadCount), context_(context) {}
164 
165     NO_COPY_SEMANTIC(CompileFuncQueue);
166     NO_MOVE_SEMANTIC(CompileFuncQueue);
167     ~CompileFuncQueue() override = default;
168 
169     void Schedule() override;
170 
171 private:
172     CompilerContext *context_;
173 };
174 
175 class CompileFileQueue : public util::WorkerQueue {
176 public:
CompileFileQueue(size_t threadCount, es2panda::CompilerOptions *options, std::map<std::string, panda::es2panda::util::ProgramCache*> &progsInfo, std::unordered_set<std::string> &optimizationPendingProgs, util::SymbolTable *symbolTable, panda::ArenaAllocator *allocator)177     explicit CompileFileQueue(size_t threadCount, es2panda::CompilerOptions *options,
178                               std::map<std::string, panda::es2panda::util::ProgramCache*> &progsInfo,
179                               std::unordered_set<std::string> &optimizationPendingProgs,
180                               util::SymbolTable *symbolTable, panda::ArenaAllocator *allocator)
181         : util::WorkerQueue(threadCount), options_(options), progsInfo_(progsInfo),
182         optimizationPendingProgs_(optimizationPendingProgs), symbolTable_(symbolTable),
183         allocator_(allocator) {}
184 
185     NO_COPY_SEMANTIC(CompileFileQueue);
186     NO_MOVE_SEMANTIC(CompileFileQueue);
187     ~CompileFileQueue() override = default;
188 
189     void Schedule() override;
190 
191 private:
192     es2panda::CompilerOptions *options_;
193     std::map<std::string, panda::es2panda::util::ProgramCache*> &progsInfo_;
194     std::unordered_set<std::string> &optimizationPendingProgs_;
195     util::SymbolTable *symbolTable_;
196     panda::ArenaAllocator *allocator_;
197 };
198 
199 class CompileAbcClassQueue : public util::WorkerQueue {
200 public:
CompileAbcClassQueue(size_t threadCount, const es2panda::CompilerOptions &options, abc2program::Abc2ProgramCompiler &compiler, std::map<std::string, panda::es2panda::util::ProgramCache*> &progsInfo, panda::ArenaAllocator *allocator, es2panda::SourceFile *src)201     explicit CompileAbcClassQueue(size_t threadCount,
202                                   const es2panda::CompilerOptions &options,
203                                   abc2program::Abc2ProgramCompiler &compiler,
204                                   std::map<std::string, panda::es2panda::util::ProgramCache*> &progsInfo,
205                                   panda::ArenaAllocator *allocator,
206                                   es2panda::SourceFile *src)
207         : util::WorkerQueue(threadCount), options_(options), compiler_(compiler), progsInfo_(progsInfo),
208           allocator_(allocator), src_(src) {}
209 
210     NO_COPY_SEMANTIC(CompileAbcClassQueue);
211     NO_MOVE_SEMANTIC(CompileAbcClassQueue);
212     ~CompileAbcClassQueue() override = default;
213 
214     void Schedule() override;
215 
216 private:
217     bool NeedUpdateVersion();
218 
219     static std::mutex globalMutex_;
220     const es2panda::CompilerOptions &options_;
221     abc2program::Abc2ProgramCompiler &compiler_;
222     std::map<std::string, panda::es2panda::util::ProgramCache*> &progsInfo_;
223     panda::ArenaAllocator *allocator_;
224     es2panda::SourceFile *src_;
225 };
226 
227 class PostAnalysisOptimizeFileQueue : public util::WorkerQueue {
228 public:
PostAnalysisOptimizeFileQueue(size_t threadCount, std::map<std::string, panda::es2panda::util::ProgramCache*> &progsInfo, std::unordered_set<std::string> &optimizationPendingProgs)229     explicit PostAnalysisOptimizeFileQueue(size_t threadCount,
230                                            std::map<std::string, panda::es2panda::util::ProgramCache*> &progsInfo,
231                                            std::unordered_set<std::string> &optimizationPendingProgs)
232         : util::WorkerQueue(threadCount), progsInfo_(progsInfo), optimizationPendingProgs_(optimizationPendingProgs) {}
233 
234     NO_COPY_SEMANTIC(PostAnalysisOptimizeFileQueue);
235     NO_MOVE_SEMANTIC(PostAnalysisOptimizeFileQueue);
236     ~PostAnalysisOptimizeFileQueue() override = default;
237 
238     void Schedule() override;
239 
240 private:
241     std::map<std::string, panda::es2panda::util::ProgramCache*> &progsInfo_;
242     std::unordered_set<std::string> &optimizationPendingProgs_;
243 };
244 
245 }  // namespace panda::es2panda::compiler
246 
247 #endif
248