• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 * Copyright (c) 2025 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 COMMON_COMPONENTS_OBJECTS_STRING_TABLE_INTERNAL_H
17 #define COMMON_COMPONENTS_OBJECTS_STRING_TABLE_INTERNAL_H
18 
19 #include "common_components/base/globals.h"
20 #include "common_components/platform/mutex.h"
21 #include "common_interfaces/thread/thread_holder.h"
22 #include "common_interfaces/objects/base_string_table.h"
23 #include "common_components/objects/string_table/hashtriemap.h"
24 #include "common_components/taskpool/task.h"
25 
26 namespace common {
27 
28 class BaseStringTableMutex {
29 public:
mtx_(isInit)30     explicit BaseStringTableMutex(bool isInit = true) : mtx_(isInit) {}
31 
LockWithThreadState(ThreadHolder * holder)32     void LockWithThreadState(ThreadHolder* holder)
33     {
34         if (mtx_.TryLock()) {
35             return;
36         }
37 #ifndef NDEBUG
38         BaseRuntime::RequestGC(GC_REASON_USER, true, GC_TYPE_FULL);  // Trigger CMC FULL GC
39 #endif
40         ThreadStateTransitionScope<ThreadHolder, ThreadState::WAIT> ts(holder);
41         mtx_.Lock();
42     }
43 
Lock()44     void Lock()
45     {
46         return mtx_.Lock();
47     }
48 
Unlock()49     void Unlock()
50     {
51         return mtx_.Unlock();
52     }
53 
54 private:
55     Mutex mtx_;
56 };
57 
58 template<bool ConcurrentSweep>
59 class BaseStringTableInternal;
60 
61 class BaseStringTableCleaner {
62 public:
63     using IteratorPtr = std::shared_ptr<std::atomic<uint32_t>>;
BaseStringTableCleaner(BaseStringTableInternal<true> * stringTable)64     BaseStringTableCleaner(BaseStringTableInternal<true>* stringTable) : stringTable_(stringTable) {}
~BaseStringTableCleaner()65     ~BaseStringTableCleaner()
66     {
67         stringTable_ = nullptr;
68     }
69     void PostSweepWeakRefTask(const WeakRefFieldVisitor &visitor);
70     void JoinAndWaitSweepWeakRefTask(const WeakRefFieldVisitor &visitor);
71 
72     void CleanUp();
73 private:
74     NO_COPY_SEMANTIC(BaseStringTableCleaner);
75     NO_MOVE_SEMANTIC(BaseStringTableCleaner);
76     static void ProcessSweepWeakRef(IteratorPtr &iter,
77                                     BaseStringTableCleaner *cleaner,
78                                     const WeakRefFieldVisitor &visitor);
79 
80     void StartSweepWeakRefTask();
81     void WaitSweepWeakRefTask();
82     void SignalSweepWeakRefTask();
83 
GetNextIndexId(IteratorPtr & iter)84     static inline uint32_t GetNextIndexId(IteratorPtr &iter)
85     {
86         return iter->fetch_add(1U, std::memory_order_relaxed);
87     }
88 
ReduceCountAndCheckFinish(BaseStringTableCleaner * cleaner)89     static inline bool ReduceCountAndCheckFinish(BaseStringTableCleaner *cleaner)
90     {
91         return (cleaner->PendingTaskCount_.fetch_sub(1U, std::memory_order_relaxed) == 1U);
92     }
93 
94     class CMCSweepWeakRefTask : public Task {
95       public:
CMCSweepWeakRefTask(IteratorPtr iter,BaseStringTableCleaner * cleaner,const WeakRefFieldVisitor & visitor)96         CMCSweepWeakRefTask(IteratorPtr iter, BaseStringTableCleaner *cleaner,
97                             const WeakRefFieldVisitor &visitor)
98             : Task(0), iter_(iter), cleaner_(cleaner), visitor_(visitor) {}
99         ~CMCSweepWeakRefTask() = default;
100 
101         bool Run(uint32_t threadIndex) override;
102 
103         NO_COPY_SEMANTIC(CMCSweepWeakRefTask);
104         NO_MOVE_SEMANTIC(CMCSweepWeakRefTask);
105 
106       private:
107         IteratorPtr iter_;
108         BaseStringTableCleaner *cleaner_;
109         const WeakRefFieldVisitor &visitor_;
110     };
111 
112     IteratorPtr iter_{};
113     BaseStringTableInternal<true>* stringTable_;
114     std::atomic<uint32_t> PendingTaskCount_{0U};
115     std::array<std::vector<HashTrieMapEntry*>, TrieMapConfig::ROOT_SIZE> waitFreeEntries_{};
116     Mutex sweepWeakRefMutex_{};
117     bool sweepWeakRefFinished_{true};
118     ConditionVariable sweepWeakRefCV_{};
119 };
120 
121 template<bool ConcurrentSweep>
122 class BaseStringTableInternal {
123 public:
124     using HandleCreator = BaseStringTableInterface<BaseStringTableImpl>::HandleCreator;
125     using HashTrieMapType = std::conditional_t<ConcurrentSweep,
126         HashTrieMap<BaseStringTableMutex, ThreadHolder, TrieMapConfig::NeedSlotBarrier>,
127         HashTrieMap<BaseStringTableMutex, ThreadHolder, TrieMapConfig::NoSlotBarrier>>;
128 
129     template <bool B = ConcurrentSweep, std::enable_if_t<B, int> = 0>
BaseStringTableInternal()130     BaseStringTableInternal(): cleaner_(new BaseStringTableCleaner(this)) {}
131 
132     template <bool B = ConcurrentSweep, std::enable_if_t<!B, int> = 0>
BaseStringTableInternal()133     BaseStringTableInternal() {}
134 
~BaseStringTableInternal()135     ~BaseStringTableInternal()
136     {
137         if constexpr (ConcurrentSweep) {
138             delete cleaner_;
139         }
140     }
141 
142     BaseString *GetOrInternFlattenString(ThreadHolder *holder, const HandleCreator &handleCreator, BaseString *string);
143 
144     BaseString *GetOrInternStringFromCompressedSubString(ThreadHolder *holder, const HandleCreator &handleCreator,
145                                                          const ReadOnlyHandle<BaseString> &string, uint32_t offset,
146                                                          uint32_t utf8Len);
147 
148     BaseString *GetOrInternString(ThreadHolder *holder, const HandleCreator &handleCreator, const uint8_t *utf8Data,
149                                   uint32_t utf8Len, bool canBeCompress);
150 
151     BaseString *GetOrInternString(ThreadHolder *holder, const HandleCreator &handleCreator, const uint16_t *utf16Data,
152                                   uint32_t utf16Len, bool canBeCompress);
153 
154     BaseString *TryGetInternString(const ReadOnlyHandle<BaseString> &string);
155 
GetHashTrieMap()156     HashTrieMapType &GetHashTrieMap()
157     {
158         return stringTable_;
159     }
160 
GetCleaner()161     BaseStringTableCleaner *GetCleaner()
162     {
163         return cleaner_;
164     }
165 
166     template <bool B = ConcurrentSweep, std::enable_if_t<B, int> = 0>
167     void SweepWeakRef(const WeakRefFieldVisitor& visitor, uint32_t rootID,
168                       std::vector<HashTrieMapEntry*>& waitDeleteEntries);
169 
170     template <bool B = ConcurrentSweep, std::enable_if_t<B, int> = 0>
171     void CleanUp();
172 
173     template <bool B = ConcurrentSweep, std::enable_if_t<!B, int> = 0>
174     void SweepWeakRef(const WeakRefFieldVisitor& visitor);
175 private:
176 
177     HashTrieMapType stringTable_{};
178     BaseStringTableCleaner* cleaner_ = nullptr;
179     static BaseString* AllocateLineStringObject(size_t size);
180     static constexpr size_t MAX_REGULAR_HEAP_OBJECT_SIZE = 32 * KB;
181 };
182 
183 class BaseStringTableImpl : public BaseStringTableInterface<BaseStringTableImpl> {
184 public:
185     BaseString* GetOrInternFlattenString(ThreadHolder* holder, const HandleCreator& handleCreator, BaseString* string);
186 
187     BaseString* GetOrInternStringFromCompressedSubString(ThreadHolder* holder, const HandleCreator& handleCreator,
188                                                          const ReadOnlyHandle<BaseString>& string, uint32_t offset,
189                                                          uint32_t utf8Len);
190 
191     BaseString* GetOrInternString(ThreadHolder* holder, const HandleCreator& handleCreator, const uint8_t* utf8Data,
192                                   uint32_t utf8Len, bool canBeCompress);
193 
194     BaseString* GetOrInternString(ThreadHolder* holder, const HandleCreator& handleCreator, const uint16_t* utf16Data,
195                                   uint32_t utf16Len, bool canBeCompress);
196 
197     BaseString* TryGetInternString(const ReadOnlyHandle<BaseString>& string);
198 
GetInternalTable()199     auto* GetInternalTable()
200     {
201         return &stringTable_;
202     }
203 private:
204 #ifndef GC_STW_STRINGTABLE
205     BaseStringTableInternal<true> stringTable_{};
206 #else
207     BaseStringTableInternal<false> stringTable_{};
208 #endif
209 };
210 }
211 #endif //COMMON_COMPONENTS_OBJECTS_STRING_TABLE_INTERNAL_H
212