• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 ECMASCRIPT_MEM_REMEMBERED_SET_H
17 #define ECMASCRIPT_MEM_REMEMBERED_SET_H
18 
19 #include "ecmascript/mem/mem.h"
20 #include "mem/gc/bitmap.h"
21 
22 namespace panda::ecmascript {
23 enum class SlotStatus : bool {
24     KEEP_SLOT,
25     CLEAR_SLOT,
26 };
27 
28 class RememberedSet : public mem::Bitmap {
29 public:
30     using RememberedWordType = uintptr_t;
31     static const size_t BYTESPERCHUNK = static_cast<size_t>(MemAlignment::MEM_ALIGN_OBJECT);
32 
RememberedSet(uintptr_t begin_addr,size_t range_size,uintptr_t bitset_addr)33     RememberedSet(uintptr_t begin_addr, size_t range_size, uintptr_t bitset_addr)
34         : mem::Bitmap(reinterpret_cast<mem::Bitmap::BitmapWordType *>(bitset_addr), range_size / BYTESPERCHUNK),
35           beginAddr_(begin_addr)
36     {
37     }
38     ~RememberedSet() = default;
39     NO_COPY_SEMANTIC(RememberedSet);
40     NO_MOVE_SEMANTIC(RememberedSet);
41 
Insert(uintptr_t address)42     void Insert(uintptr_t address)
43     {
44         SetBit(AddrToBitOffset(address));
45     }
46 
AtomicInsert(uintptr_t address)47     void AtomicInsert(uintptr_t address)
48     {
49         AtomicTestAndSetBit(AddrToBitOffset(address));
50     }
51 
52     template<typename VisitorType>
IterateOverSetBits(VisitorType visitor)53     void IterateOverSetBits(VisitorType visitor)
54     {
55         IterateOverSetBitsInRange(0, Size(), visitor);
56     }
57 
58     template<typename MemVisitor>
IterateOverMarkedChunks(MemVisitor visitor)59     void IterateOverMarkedChunks(MemVisitor visitor)
60     {
61         IterateOverSetBits(
62             [&visitor, this](size_t bit_offset) -> bool { return visitor(BitOffsetToAddr(bit_offset)); });
63     }
64 
Clear(uintptr_t address)65     void Clear(uintptr_t address)
66     {
67         ClearBit(AddrToBitOffset(address));
68     }
69 
ClearRange(uintptr_t begin,uintptr_t end)70     void ClearRange(uintptr_t begin, uintptr_t end)
71     {
72         ClearBitsInRange(AddrToBitOffset(begin), AddrToBitOffset(end));
73     }
74 
GetSizeInByte(size_t range_size)75     static size_t GetSizeInByte(size_t range_size)
76     {
77         return (range_size >> mem::Bitmap::LOG_BITSPERWORD) / BYTESPERCHUNK * sizeof(mem::Bitmap::BitmapWordType);
78     }
79 
80     static constexpr uint32_t GetBeginAddrOffset(bool is32Bit = false)
81     {
82         return is32Bit ? BITMAP_MEMBER_SIZE_32 : BITMAP_MEMBER_SIZE_64;
83     }
84 
CheckLayout()85     static constexpr bool CheckLayout()
86     {
87     #ifdef PANDA_TARGET_32
88         static_assert(GetBeginAddrOffset(true) == MEMBER_OFFSET(RememberedSet, beginAddr_));
89     #else
90         static_assert(GetBeginAddrOffset(false) == MEMBER_OFFSET(RememberedSet, beginAddr_));
91     #endif
92         return true;
93     }
94 
95 private:
BitOffsetToAddr(size_t bit_offset)96     void *BitOffsetToAddr(size_t bit_offset) const
97     {
98         return ToVoidPtr(beginAddr_ + bit_offset * BYTESPERCHUNK);
99     }
100 
AddrToBitOffset(uintptr_t addr)101     size_t AddrToBitOffset(uintptr_t addr) const
102     {
103         return (addr - beginAddr_) / BYTESPERCHUNK;
104     }
105     // BitMap class consist members: bitmap_ and bitsize_
106     static constexpr size_t BITMAP_MEMBER_SIZE_64 = sizeof(uint64_t) + sizeof(uint64_t) + sizeof(uint64_t);
107     static constexpr size_t BITMAP_MEMBER_SIZE_32 = sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint32_t);
108     uintptr_t beginAddr_;
109 };
110 static_assert(RememberedSet::CheckLayout());
111 }  // namespace panda::ecmascript
112 
113 #endif  // ECMASCRIPT_MEM_REMEMBERED_SET_H
114