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
30namespace panda::es2panda::binder {
31class FunctionScope;
32}  // namespace panda::es2panda::binder
33
34namespace panda::es2panda::compiler {
35
36class CompilerContext;
37
38class CompileFunctionJob : public util::WorkerJob {
39public:
40    explicit CompileFunctionJob(CompilerContext *context) : context_(context) {};
41    NO_COPY_SEMANTIC(CompileFunctionJob);
42    NO_MOVE_SEMANTIC(CompileFunctionJob);
43    ~CompileFunctionJob() override = default;
44
45    binder::FunctionScope *Scope() const
46    {
47        return scope_;
48    }
49
50    void SetFunctionScope(binder::FunctionScope *scope)
51    {
52        scope_ = scope;
53    }
54
55    void Run() override;
56
57private:
58    CompilerContext *context_ {};
59    binder::FunctionScope *scope_ {};
60};
61
62class CompileModuleRecordJob : public util::WorkerJob {
63public:
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
71private:
72    CompilerContext *context_ {};
73};
74
75class CompileFileJob : public util::WorkerJob {
76public:
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
89private:
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
104class CompileAbcClassJob : public util::WorkerJob {
105public:
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
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
128private:
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
145class PostAnalysisOptimizeFileJob : public util::WorkerJob {
146public:
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
155private:
156    std::string fileName_;
157    pandasm::Program *program_;
158};
159
160class CompileFuncQueue : public util::WorkerQueue {
161public:
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
171private:
172    CompilerContext *context_;
173};
174
175class CompileFileQueue : public util::WorkerQueue {
176public:
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
191private:
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
199class CompileAbcClassQueue : public util::WorkerQueue {
200public:
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
216private:
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
227class PostAnalysisOptimizeFileQueue : public util::WorkerQueue {
228public:
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
240private:
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