• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 PANDA_MEM_GC_G1_REM_SET_H
17 #define PANDA_MEM_GC_G1_REM_SET_H
18 
19 #include <limits>
20 
21 namespace panda::mem {
22 
23 namespace test {
24 class RemSetTest;
25 }  // namespace test
26 
27 class RemSetLockConfig {
28 public:
29     using CommonLock = os::memory::RecursiveMutex;
30     using DummyLock = os::memory::DummyLock;
31 };
32 
33 class Region;
34 
35 /// @brief Set in the Region. To record the regions and cards reference to this region.
36 template <typename LockConfigT = RemSetLockConfig::CommonLock>
37 class RemSet {
38 public:
39     RemSet() = default;
40     ~RemSet();
41 
42     NO_COPY_SEMANTIC(RemSet);
43     NO_MOVE_SEMANTIC(RemSet);
44 
45     template <bool NEED_LOCK = true>
46     void AddRef(const ObjectHeader *fromObjAddr, size_t offset);
47 
48     template <typename RegionPred, typename MemVisitor>
49     void Iterate(const RegionPred &regionPred, const MemVisitor &visitor);
50     template <typename Visitor>
51     void IterateOverObjects(const Visitor &visitor);
52 
53     void Clear();
54 
55     template <bool NEED_LOCK = true>
56     static void InvalidateRegion(Region *invalidRegion);
57 
58     template <bool NEED_LOCK = true>
59     static void InvalidateRefsFromRegion(Region *invalidRegion);
60 
Size()61     size_t Size() const
62     {
63         return bitmaps_.size();
64     }
65 
66     /**
67      * Used in the barrier. Record the reference from the region of obj_addr to the region of value_addr.
68      * @param obj_addr - address of the object
69      * @param offset   - offset in the object where value is stored
70      * @param value_addr - address of the reference in the field
71      */
72     template <bool NEED_LOCK = true>
73     static void AddRefWithAddr(const ObjectHeader *objAddr, size_t offset, const ObjectHeader *valueAddr);
74 
75     void Dump(std::ostream &out);
76 
77     class Bitmap {
78     public:
GetBitmapSizeInBytes()79         static constexpr size_t GetBitmapSizeInBytes()
80         {
81             return sizeof(bitmap_);
82         }
83 
GetNumBits()84         static constexpr size_t GetNumBits()
85         {
86             return GetBitmapSizeInBytes() * BITS_PER_BYTE;
87         }
88 
Set(size_t idx)89         void Set(size_t idx)
90         {
91             size_t elemIdx = idx / ELEM_BITS;
92             ASSERT(elemIdx < SIZE);
93             size_t bitOffset = idx - elemIdx * ELEM_BITS;
94             bitmap_[elemIdx] |= 1ULL << bitOffset;
95         }
96 
97         template <typename Visitor>
Iterate(const MemRange & range,const Visitor & visitor)98         void Iterate(const MemRange &range, const Visitor &visitor) const
99         {
100             size_t memSize = (range.GetEndAddress() - range.GetStartAddress()) / GetNumBits();
101             uintptr_t startAddr = range.GetStartAddress();
102             for (size_t i = 0; i < SIZE; ++i) {
103                 uintptr_t addr = startAddr + i * memSize * ELEM_BITS;
104                 uint64_t elem = bitmap_[i];
105                 while (elem > 0) {
106                     if (elem & 1ULL) {
107                         visitor(MemRange(addr, addr + memSize));
108                     }
109                     elem >>= 1ULL;
110                     addr += memSize;
111                 }
112             }
113         }
114 
115     private:
116         static constexpr size_t SIZE = 8U;
117         static constexpr size_t ELEM_BITS = std::numeric_limits<uint64_t>::digits;
118         std::array<uint64_t, SIZE> bitmap_ {0};
119     };
120 
121 private:
122     static size_t GetIdxInBitmap(uintptr_t addr, uintptr_t bitmapBeginAddr);
123     template <bool NEED_LOCK>
124     PandaUnorderedSet<Region *> *GetRefRegions();
125     template <bool NEED_LOCK>
126     void AddRefRegion(Region *region);
127     template <bool NEED_LOCK>
128     void RemoveFromRegion(Region *region);
129     template <bool NEED_LOCK>
130     void RemoveRefRegion(Region *region);
131 
132     LockConfigT remSetLock_;
133     // NOTE(alovkov): make value a Set?
134     PandaUnorderedMap<uintptr_t, Bitmap> bitmaps_;
135     PandaUnorderedSet<Region *> refRegions_;
136 
137     friend class test::RemSetTest;
138 };
139 }  // namespace panda::mem
140 #endif  // PANDA_MEM_GC_G1_REM_SET_H
141