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 ®ionPred, 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