• 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     auto targetApi = options_->CompilerOptions().targetApiVersion;
29 
30     if (mergeAbc_) {
31         // generate merged abc
32         auto emitMergedAbcJob = new EmitMergedAbcJob(options_->CompilerOutput(), progsInfo_, targetApi);
33         for (const auto &info: progsInfo_) {
34             // generate cache protoBins and set dependencies
35             if (!info.second->needUpdateCache) {
36                 continue;
37             }
38             auto outputCacheIter = options_->CompilerOptions().cacheFiles.find(info.first);
39             if (outputCacheIter != options_->CompilerOptions().cacheFiles.end()) {
40                 auto emitProtoJob = new EmitCacheJob(outputCacheIter->second, info.second);
41                 emitProtoJob->DependsOn(emitMergedAbcJob);
42                 jobs_.push_back(emitProtoJob);
43                 jobsCount_++;
44             }
45         }
46         //  One job should be placed after those jobs which depend on it to prevent blocking
47         jobs_.push_back(emitMergedAbcJob);
48         jobsCount_++;
49     } else {
50         for (const auto &info: progsInfo_) {
51             try {
52                 // generate multi abcs
53                 auto outputFileName = options_->OutputFiles().empty() ? options_->CompilerOutput() :
54                     options_->OutputFiles().at(info.first);
55                 auto emitSingleAbcJob = new EmitSingleAbcJob(outputFileName, &(info.second->program), statp_,
56                                                              targetApi);
57                 jobs_.push_back(emitSingleAbcJob);
58                 jobsCount_++;
59             } catch (std::exception &error) {
60                 throw Error(ErrorType::GENERIC, error.what());
61             }
62         }
63     }
64 
65     lock.unlock();
66     jobsAvailable_.notify_all();
67 }
68 
Run()69 void EmitSingleAbcJob::Run()
70 {
71     if (!panda::pandasm::AsmEmitter::Emit(panda::os::file::File::GetExtendedFilePath(outputFileName_), *prog_, statp_,
72         nullptr, true, nullptr, targetApiVersion_)) {
73         throw Error(ErrorType::GENERIC, "Failed to emit " + outputFileName_ + ", error: " +
74             panda::pandasm::AsmEmitter::GetLastError());
75     }
76     for (auto *dependant : dependants_) {
77         dependant->Signal();
78     }
79 }
80 
Run()81 void EmitMergedAbcJob::Run()
82 {
83     std::vector<panda::pandasm::Program*> progs;
84     progs.reserve(progsInfo_.size());
85     for (const auto &info: progsInfo_) {
86         progs.push_back(&(info.second->program));
87     }
88 
89     bool success = panda::pandasm::AsmEmitter::EmitPrograms(
90         panda::os::file::File::GetExtendedFilePath(outputFileName_), progs, true, targetApiVersion_);
91 
92     for (auto *dependant : dependants_) {
93         dependant->Signal();
94     }
95 
96     if (!success) {
97         throw Error(ErrorType::GENERIC, "Failed to emit " + outputFileName_ + ", error: " +
98             panda::pandasm::AsmEmitter::GetLastError() +
99             "\nIf you're using any cache file generated by older version of SDK, " +
100             "please try cleaning the cache files and rebuild");
101     }
102 }
103 
Run()104 void EmitCacheJob::Run()
105 {
106     std::unique_lock<std::mutex> lock(m_);
107     cond_.wait(lock, [this] { return dependencies_ == 0; });
108     panda::proto::ProtobufSnapshotGenerator::UpdateCacheFile(progCache_, outputProtoName_);
109 }
110 
111 }  // namespace panda::es2panda::util
112