• 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 PANDA_RUNTIME_MEM_REM_SET_INL_H_
17 #define PANDA_RUNTIME_MEM_REM_SET_INL_H_
18 
19 #include "runtime/mem/rem_set.h"
20 #include "runtime/mem/region_space-inl.h"
21 
22 namespace panda::mem {
23 
24 template <typename LockConfigT>
RemSet(Region * region)25 RemSet<LockConfigT>::RemSet(Region *region) : region_(region)
26 {
27     allocator_ = region->GetInternalAllocator();
28 }
29 
30 template <typename LockConfigT>
~RemSet()31 RemSet<LockConfigT>::~RemSet()
32 {
33     Clear();
34 }
35 
36 template <typename LockConfigT>
AddRef(const void * from_field_addr)37 void RemSet<LockConfigT>::AddRef(const void *from_field_addr)
38 {
39     auto from_region = Region::AddrToRegion(from_field_addr);
40     auto card_ptr = GetCardPtr(from_field_addr);
41     auto list = GetCardList(from_region);
42     os::memory::LockHolder lock(rem_set_lock_);
43     if (list == nullptr) {
44         list = allocator_->New<CardList>();
45         // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
46         regions_[from_region] = list;
47     }
48     if (find(list->begin(), list->end(), card_ptr) == list->end()) {
49         list->push_back(card_ptr);
50     }
51 }
52 
53 template <typename LockConfigT>
Clear()54 void RemSet<LockConfigT>::Clear()
55 {
56     os::memory::LockHolder lock(rem_set_lock_);
57     for (auto region_iter : regions_) {
58         auto list = region_iter.second;
59         allocator_->Delete(list);
60     }
61     regions_.clear();
62 }
63 
64 template <typename LockConfigT>
GetCardList(Region * region)65 CardList *RemSet<LockConfigT>::GetCardList(Region *region)
66 {
67     os::memory::LockHolder lock(rem_set_lock_);
68     if (regions_.find(region) == regions_.end()) {
69         return nullptr;
70     }
71     // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
72     return regions_[region];
73 }
74 
75 template <typename LockConfigT>
GetCardPtr(const void * addr)76 CardPtr RemSet<LockConfigT>::GetCardPtr(const void *addr)
77 {
78     return card_table_ != nullptr ? card_table_->GetCardPtr(ToUintPtr(addr)) : nullptr;
79 }
80 
81 template <typename LockConfigT>
GetMemoryRange(CardPtr card)82 MemRange RemSet<LockConfigT>::GetMemoryRange(CardPtr card)
83 {
84     return card_table_->GetMemoryRange(card);
85 }
86 
87 /* static */
88 template <typename LockConfigT>
AddRefWithAddr(const void * obj_addr,const void * value_addr)89 void RemSet<LockConfigT>::AddRefWithAddr(const void *obj_addr, const void *value_addr)
90 {
91     auto from_region = Region::AddrToRegion(obj_addr);
92     // The eden region must be included in the collection set in GC. So, we don't need add ref here.
93     if (from_region->IsEden()) {
94         return;
95     }
96     auto to_region = Region::AddrToRegion(value_addr);
97     to_region->GetRemSet()->AddRef(obj_addr);
98 }
99 
100 /* static */
101 template <typename LockConfigT>
TraverseObjectToAddRef(const void * addr)102 void RemSet<LockConfigT>::TraverseObjectToAddRef(const void *addr)
103 {
104     auto traverse_object_visitor = [](ObjectHeader *from_object, ObjectHeader *object_to_traverse) {
105         AddRefWithAddr(from_object, object_to_traverse);
106     };
107     auto obj = static_cast<ObjectHeader *>(const_cast<void *>(addr));
108     GCStaticObjectHelpers::TraverseAllObjects(obj, traverse_object_visitor);
109 }
110 
111 template <typename LockConfigT>
112 template <typename ObjectVisitor>
VisitMarkedCards(const ObjectVisitor & object_visitor)113 inline void RemSet<LockConfigT>::VisitMarkedCards(const ObjectVisitor &object_visitor)
114 {
115     os::memory::LockHolder lock(rem_set_lock_);
116     for (auto region_iter : regions_) {
117         auto *region = region_iter.first;
118         auto *card_list = region_iter.second;
119         for (auto card_ptr : *card_list) {
120             // visit live objects in old region
121             auto mem_range = GetMemoryRange(card_ptr);
122             region->GetLiveBitmap()->IterateOverMarkedChunkInRange(
123                 ToVoidPtr(mem_range.GetStartAddress()), ToVoidPtr(mem_range.GetEndAddress()), object_visitor);
124         }
125     }
126 }
127 
128 }  // namespace panda::mem
129 
130 #endif  // PANDA_RUNTIME_MEM_REM_SET_INL_H_
131