• 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 #ifndef PANDA_RUNTIME_MEM_GC_G1_G1_OBJECT_POINTER_HANDLER_H
16 #define PANDA_RUNTIME_MEM_GC_G1_G1_OBJECT_POINTER_HANDLER_H
17 
18 #include "libpandabase/mem/mem.h"
19 #include "runtime/include/coretypes/tagged_value.h"
20 #include "runtime/include/object_accessor.h"
21 #include "runtime/mem/region_allocator.h"
22 #include "runtime/mem/rem_set-inl.h"
23 #include "runtime/mem/gc/g1/g1-gc.h"
24 
25 namespace ark::mem {
26 template <LangTypeT LANG_TYPE>
27 struct ObjectReference;
28 
29 template <>
30 struct ObjectReference<LANG_TYPE_STATIC> {
31     using Type = ObjectPointerType *;
32 };
33 
34 template <>
35 struct ObjectReference<LANG_TYPE_DYNAMIC> {
36     using Type = coretypes::TaggedType *;
37 };
38 
39 template <typename LanguageConfig>
40 class G1GC;
41 
42 template <typename LanguageConfig>
43 class G1EvacuateRegionsWorkerState;
44 
45 class RemsetObjectPointerHandler {
46 public:
47     RemsetObjectPointerHandler(Region *fromRegion, size_t regionSizeBits, const std::atomic_bool &deferCards)
48         : fromRemset_(fromRegion->GetRemSet()), regionSizeBits_(regionSizeBits), deferCards_(deferCards)
49     {
50     }
51 
52     template <typename T>
53     bool ProcessObjectPointer(T *ref) const
54     {
55         ProcessObjectPointerInternal(ref);
56         // Atomic with relaxed order reason: memory order is not required
57         return !deferCards_.load(std::memory_order_relaxed);
58     }
59 
60 private:
61     template <typename T>
62     void ProcessObjectPointerInternal(T *ref) const
63     {
64         // fromRemset_ is not changed while handling one card
65         ASSERT(AddrToRegion(ref)->GetRemSet() == fromRemset_);
66 
67         auto o = ObjectAccessor::LoadAtomic(ref);
68         if (!ObjectAccessor::IsHeapObject(o)) {
69             return;
70         }
71 
72         auto *obj = ObjectAccessor::DecodeNotNull(o);
73         if (ark::mem::IsSameRegion(ref, obj, regionSizeBits_)) {
74             return;
75         }
76 
77         ASSERT_PRINT(IsHeapSpace(PoolManager::GetMmapMemPool()->GetSpaceTypeForAddr(obj)),
78                      "Not suitable space for to_obj: " << obj);
79 
80         // don't need lock because only one thread changes remsets
81         RemSet<>::AddRefWithAddr<false>(fromRemset_, ref, obj);
82         LOG(DEBUG, GC) << "fill rem set " << ref << " -> " << obj;
83     }
84     RemSetT *fromRemset_;
85     size_t regionSizeBits_;
86     const std::atomic_bool &deferCards_;
87 };
88 
89 template <class LanguageConfig>
90 class EvacuationObjectPointerHandler {
91 public:
92     using Ref = typename ObjectReference<LanguageConfig::LANG_TYPE>::Type;
93 
94     explicit EvacuationObjectPointerHandler(G1EvacuateRegionsWorkerState<LanguageConfig> *workerState)
95         : gc_(workerState->GetGC()), workerState_(workerState)
96     {
97     }
98 
99     bool ProcessObjectPointer(Ref ref) const
100     {
101         ProcessObjectPointerHelper(ref);
102         return true;
103     }
104 
105 private:
106     void ProcessObjectPointerHelper(Ref ref) const
107     {
108         auto o = ObjectAccessor::Load(ref);
109         if (!ObjectAccessor::IsHeapObject(o)) {
110             return;
111         }
112         auto *obj = ObjectAccessor::DecodeNotNull(o);
113         if (gc_->InGCSweepRange(obj)) {
114             workerState_->PushToQueue(ref);
115         } else if (!workerState_->IsSameRegion(ref, obj)) {
116             workerState_->EnqueueCard(ref);
117         }
118     }
119 
120     G1GC<LanguageConfig> *gc_;
121     G1EvacuateRegionsWorkerState<LanguageConfig> *workerState_;
122 };
123 }  // namespace ark::mem
124 
125 #endif
126