• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "emitFiles.h"
17 
18 #include <assembly-emitter.h>
19 #include <es2panda.h>
20 #include <mem/arena_allocator.h>
21 #include <protobufSnapshotGenerator.h>
22 
23 namespace panda::es2panda::aot {
Schedule()24 void EmitFileQueue::Schedule()
25 {
26     ASSERT(jobsCount_ == 0);
27     std::unique_lock<std::mutex> lock(m_);
28 
29     if (mergeAbc_) {
30         // generate merged abc
31         auto emitMergedAbcJob = new EmitMergedAbcJob(options_->CompilerOutput(), progsInfo_);
32         for (const auto &info: progsInfo_) {
33             // generate cache protoBins and set dependencies
34             if (!info.second->needUpdateCache) {
35                 continue;
36             }
37             auto outputCacheIter = options_->CompilerOptions().cacheFiles.find(info.first);
38             if (outputCacheIter != options_->CompilerOptions().cacheFiles.end()) {
39                 auto emitProtoJob = new EmitCacheJob(outputCacheIter->second, info.second);
40                 emitProtoJob->DependsOn(emitMergedAbcJob);
41                 jobs_.push_back(emitProtoJob);
42                 jobsCount_++;
43             }
44         }
45         //  One job should be placed after those jobs which depend on it to prevent blocking
46         jobs_.push_back(emitMergedAbcJob);
47         jobsCount_++;
48     } else {
49         for (const auto &info: progsInfo_) {
50             try {
51                 // generate multi abcs
52                 auto outputFileName = options_->OutputFiles().empty() ? options_->CompilerOutput() :
53                     options_->OutputFiles().at(info.first);
54                 auto emitSingleAbcJob = new EmitSingleAbcJob(outputFileName, &(info.second->program), statp_);
55                 jobs_.push_back(emitSingleAbcJob);
56                 jobsCount_++;
57             } catch (std::exception &error) {
58                 throw Error(ErrorType::GENERIC, error.what());
59             }
60         }
61     }
62 
63     lock.unlock();
64     jobsAvailable_.notify_all();
65 }
66 
Run()67 void EmitSingleAbcJob::Run()
68 {
69     if (!panda::pandasm::AsmEmitter::Emit(panda::os::file::File::GetExtendedFilePath(outputFileName_), *prog_, statp_,
70         nullptr, true)) {
71         throw Error(ErrorType::GENERIC, "Failed to emit " + outputFileName_ + ", error: " +
72             panda::pandasm::AsmEmitter::GetLastError());
73     }
74     for (auto *dependant : dependants_) {
75         dependant->Signal();
76     }
77 }
78 
Run()79 void EmitMergedAbcJob::Run()
80 {
81     std::vector<panda::pandasm::Program*> progs;
82     progs.reserve(progsInfo_.size());
83     for (const auto &info: progsInfo_) {
84         progs.push_back(&(info.second->program));
85     }
86     if (!panda::pandasm::AsmEmitter::EmitPrograms(panda::os::file::File::GetExtendedFilePath(outputFileName_), progs,
87         true)) {
88         throw Error(ErrorType::GENERIC, "Failed to emit " + outputFileName_ + ", error: " +
89             panda::pandasm::AsmEmitter::GetLastError());
90     }
91     for (auto *dependant : dependants_) {
92         dependant->Signal();
93     }
94 }
95 
Run()96 void EmitCacheJob::Run()
97 {
98     std::unique_lock<std::mutex> lock(m_);
99     cond_.wait(lock, [this] { return dependencies_ == 0; });
100     panda::proto::ProtobufSnapshotGenerator::UpdateCacheFile(progCache_, outputProtoName_);
101 }
102 
103 }  // namespace panda::es2panda::util
104