• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2024 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_GC_G1_HOT_CARDS_H
17 #define PANDA_RUNTIME_MEM_GC_G1_HOT_CARDS_H
18 
19 #include "runtime/include/mem/panda_containers.h"
20 #include "runtime/mem/gc/card_table-inl.h"
21 #include "runtime/arch/memory_helpers.h"
22 
23 namespace ark::mem {
24 
25 class HotCards {
26 public:
27     using Card = CardTable::Card;
28     using CardPtr = CardTable::CardPtr;
29 
30     void PushCard(CardPtr cardPtr);
31 
32     void DecrementHotValue();
33 
34     // Should be called when mutator thread is on pause
35     void DrainMarkedCards(PandaUnorderedSet<CardPtr> *markedCards);
36     void ClearHotCards();
37 
38     template <typename CardHandler>
HandleCards(CardHandler handler)39     size_t HandleCards(CardHandler handler)
40     {
41         UpdateCardsStatus();
42 
43         // clear card before we process it, because parallel mutator thread can make a write and we would miss it
44         arch::StoreLoadBarrier();
45 
46         size_t processedCardsCnt = 0;
47         auto cardIt = unprocessedCards_.begin();
48         while (cardIt != unprocessedCards_.end()) {
49             if (!handler.Handle(*cardIt)) {
50                 break;
51             }
52             ++processedCardsCnt;
53             cardIt = unprocessedCards_.erase(cardIt);
54         }
55         return processedCardsCnt;
56     }
57 
SetHot(CardPtr cardPtr,uint8_t value)58     static ALWAYS_INLINE void SetHot(CardPtr cardPtr, uint8_t value)
59     {
60         cardPtr->SetCard(value | Card::GetHotFlag());
61     }
62 
ResetHot(CardPtr cardPtr,uint8_t value)63     static ALWAYS_INLINE void ResetHot(CardPtr cardPtr, uint8_t value)
64     {
65         cardPtr->SetCard(value & RESET_HOT_MASK);
66     }
67 
SetMaxHotValue(CardPtr cardPtr,uint8_t value)68     static ALWAYS_INLINE void SetMaxHotValue(CardPtr cardPtr, uint8_t value)
69     {
70         cardPtr->SetCard(value | Card::GetMaxHotValue());
71     }
72 
SetHotAndMaxHotValue(CardPtr cardPtr,uint8_t value)73     static ALWAYS_INLINE void SetHotAndMaxHotValue(CardPtr cardPtr, uint8_t value)
74     {
75         static constexpr uint8_t HOT_FLAG_MAX_VALUE = Card::GetHotFlag() | Card::GetMaxHotValue();
76         cardPtr->SetCard(value | HOT_FLAG_MAX_VALUE);
77     }
78 
IncrementHotValue(CardPtr cardPtr,uint8_t value)79     static ALWAYS_INLINE void IncrementHotValue(CardPtr cardPtr, uint8_t value)
80     {
81         ASSERT(!Card::IsMaxHotValue(value));
82         cardPtr->SetCard(value + Card::GetHotValue());
83     }
84 
85     static constexpr uint8_t RESET_HOT_MASK = uint8_t(~Card::GetHotFlag());
86     static constexpr uint8_t RESET_MARK_MASK = ~CardTable::Card::GetMarkedValue();
87 
88 private:
89     void UpdateCardsStatus();
90 
91     template <typename F>
VisitHotCards(F fun)92     void VisitHotCards(F fun)
93     {
94         std::for_each(hotCards_.begin(), hotCards_.end(), std::move(fun));
95     }
96 
97     PandaUnorderedSet<CardPtr> hotCards_;
98     PandaUnorderedSet<CardPtr> unprocessedCards_;
99 };
100 
101 }  // namespace ark::mem
102 
103 #endif  // PANDA_RUNTIME_MEM_GC_G1_HOT_CARDS_H