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