• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2024 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 COMPILER_AOT_AOT_MANAGER_H
17 #define COMPILER_AOT_AOT_MANAGER_H
18 
19 #include "aot_file.h"
20 #include "file.h"
21 #include "utils/arena_containers.h"
22 #include "runtime/include/mem/panda_containers.h"
23 #include "runtime/include/mem/panda_string.h"
24 #include "utils/expected.h"
25 
26 namespace ark::compiler {
27 class RuntimeInterface;
28 
29 class AotManager {
30     using BitSetElement = uint32_t;
31     static constexpr size_t MASK_WIDTH = BITS_PER_BYTE * sizeof(BitSetElement);
32 
33 public:
34     explicit AotManager() = default;
35 
36     NO_MOVE_SEMANTIC(AotManager);
37     NO_COPY_SEMANTIC(AotManager);
38     ~AotManager() = default;
39 
40     Expected<bool, std::string> AddFile(const std::string &fileName, RuntimeInterface *runtime, uint32_t gcType,
41                                         bool force = false);
42 
43     const AotFile *GetFile(const std::string &fileName) const;
44 
45     const AotPandaFile *FindPandaFile(const std::string &fileName);
46 
GetBootClassContext()47     PandaString GetBootClassContext() const
48     {
49         return bootClassContext_;
50     }
51 
SetBootClassContext(PandaString context)52     void SetBootClassContext(PandaString context)
53     {
54         bootClassContext_ = std::move(context);
55     }
56 
GetAppClassContext()57     PandaString GetAppClassContext() const
58     {
59         return appClassContext_;
60     }
61 
SetAppClassContext(PandaString context)62     void SetAppClassContext(PandaString context)
63     {
64         appClassContext_ = std::move(context);
65     }
66 
67     void VerifyClassHierarchy();
68 
GetAotStringRootsCount()69     uint32_t GetAotStringRootsCount()
70     {
71         // use counter to get roots count without acquiring vector's lock
72         // Atomic with acquire order reason: data race with aot_string_gc_roots_count_ with dependecies on reads after
73         // the load which should become visible
74         return aotStringGcRootsCount_.load(std::memory_order_acquire);
75     }
76 
77     void RegisterAotStringRoot(ObjectHeader **slot, bool isYoung);
78 
79     template <typename Callback>
VisitAotStringRoots(Callback cb,bool visitOnlyYoung)80     void VisitAotStringRoots(Callback cb, bool visitOnlyYoung)
81     {
82         ASSERT(aotStringGcRoots_.empty() ||
83                (aotStringYoungSet_.size() - 1) == (aotStringGcRoots_.size() - 1) / MASK_WIDTH);
84 
85         if (!visitOnlyYoung) {
86             for (auto root : aotStringGcRoots_) {
87                 cb(root);
88             }
89             return;
90         }
91 
92         if (!hasYoungAotStringRefs_) {
93             return;
94         }
95 
96         // Atomic with acquire order reason: data race with aot_string_gc_roots_count_ with dependecies on reads after
97         // the load which should become visible
98         size_t totalRoots = aotStringGcRootsCount_.load(std::memory_order_acquire);
99         for (size_t idx = 0; idx < aotStringYoungSet_.size(); idx++) {
100             auto mask = aotStringYoungSet_[idx];
101             if (mask == 0) {
102                 continue;
103             }
104             for (size_t offset = 0; offset < MASK_WIDTH && idx * MASK_WIDTH + offset < totalRoots; offset++) {
105                 if ((mask & (1ULL << offset)) != 0) {
106                     cb(aotStringGcRoots_[idx * MASK_WIDTH + offset]);
107                 }
108             }
109         }
110     }
111 
112     template <typename Callback, typename IsYoungPredicate>
UpdateAotStringRoots(Callback cb,IsYoungPredicate p)113     void UpdateAotStringRoots(Callback cb, IsYoungPredicate p)
114     {
115         ASSERT(aotStringGcRoots_.empty() ||
116                (aotStringYoungSet_.size() - 1) == (aotStringGcRoots_.size() - 1) / MASK_WIDTH);
117 
118         hasYoungAotStringRefs_ = false;
119         size_t idx = 0;
120         for (auto root : aotStringGcRoots_) {
121             cb(root);
122             uint64_t bitmask = 1ULL << (idx % MASK_WIDTH);
123 
124             if ((aotStringYoungSet_[idx / MASK_WIDTH] & bitmask) != 0) {
125                 bool isYoung = p(*root);
126                 hasYoungAotStringRefs_ |= isYoung;
127                 if (!isYoung) {
128                     aotStringYoungSet_[idx / MASK_WIDTH] &= ~bitmask;
129                 }
130             }
131 
132             idx++;
133         }
134     }
135 
InAotFileRange(uintptr_t pc)136     bool InAotFileRange(uintptr_t pc)
137     {
138         for (auto &aotFile : aotFiles_) {
139             auto code = reinterpret_cast<uintptr_t>(aotFile->GetCode());
140             if (pc >= code && pc < code + reinterpret_cast<uintptr_t>(aotFile->GetCodeSize())) {
141                 return true;
142             }
143         }
144         return false;
145     }
146 
HasAotFiles()147     bool HasAotFiles()
148     {
149         return !aotFiles_.empty();
150     }
151 
152 private:
153     PandaVector<std::unique_ptr<AotFile>> aotFiles_;
154     PandaUnorderedMap<std::string, AotPandaFile> filesMap_;
155     PandaString bootClassContext_;
156     PandaString appClassContext_;
157 
158     os::memory::RecursiveMutex aotStringRootsLock_;
159     PandaVector<ObjectHeader **> aotStringGcRoots_;
160     std::atomic_uint32_t aotStringGcRootsCount_ {0};
161     bool hasYoungAotStringRefs_ {false};
162     PandaVector<BitSetElement> aotStringYoungSet_;
163 };
164 
165 class AotClassContextCollector {
166 public:
acc_(acc)167     explicit AotClassContextCollector(PandaString *acc, bool useAbsPath = true) : acc_(acc), useAbsPath_(useAbsPath) {};
168     bool operator()(const panda_file::File &pf);
169 
170     DEFAULT_MOVE_SEMANTIC(AotClassContextCollector);
171     DEFAULT_COPY_SEMANTIC(AotClassContextCollector);
172     ~AotClassContextCollector() = default;
173 
174 private:
175     PandaString *acc_;
176     bool useAbsPath_;
177 };
178 }  // namespace ark::compiler
179 
180 #endif  // COMPILER_AOT_AOT_MANAGER_H
181