• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2023-2025 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_PLUGINS_ETS_RUNTIME_MEM_ETS_REFERENCE_PROCESSOR_H
17 #define PANDA_PLUGINS_ETS_RUNTIME_MEM_ETS_REFERENCE_PROCESSOR_H
18 
19 #include "plugins/ets/runtime/types/ets_object.h"
20 #include "runtime/mem/gc/reference-processor/reference_processor.h"
21 
22 #include "plugins/ets/runtime/types/ets_class.h"
23 #include "plugins/ets/runtime/types/ets_weak_reference.h"
24 #include "plugins/ets/runtime/types/ets_finalizable_weak_ref.h"
25 
26 #include "plugins/ets/runtime/mem/mpsc_set.h"
27 
28 namespace ark::mem::ets {
29 
30 class EtsReferenceProcessor final : public ReferenceProcessor {
31     using RefFinalizer = ark::ets::EtsFinalizableWeakRef::Finalizer;
32 
33 public:
34     explicit EtsReferenceProcessor(GC *gc);
35     NO_COPY_SEMANTIC(EtsReferenceProcessor);
36     NO_MOVE_SEMANTIC(EtsReferenceProcessor);
37     ~EtsReferenceProcessor() final = default;
38 
39     void Initialize() override;
40 
41     bool IsReference(const BaseClass *baseCls, const ObjectHeader *ref,
42                      const ReferenceCheckPredicateT &pred) const final;
43 
44     void HandleReference(GC *gc, GCMarkingStackType *objectsStack, const BaseClass *cls, const ObjectHeader *object,
45                          const ReferenceProcessPredicateT &pred) final;
46     void HandleReference(GC *gc, const BaseClass *cls, const ObjectHeader *object,
47                          const ReferenceProcessorT &processor) final;
48 
49     void ProcessReferences(bool concurrent, bool clearSoftReferences, GCPhase gcPhase,
50                            const mem::GC::ReferenceClearPredicateT &pred) final;
51     void ProcessReferencesAfterCompaction([[maybe_unused]] const mem::GC::ReferenceClearPredicateT &pred) final;
52 
CollectClearedReferences()53     ark::mem::Reference *CollectClearedReferences() final
54     {
55         return nullptr;
56     }
57 
ScheduleForEnqueue(Reference * clearedReferences)58     void ScheduleForEnqueue([[maybe_unused]] Reference *clearedReferences) final
59     {
60         UNREACHABLE();
61     }
62 
Enqueue(ark::mem::Reference * clearedReferences)63     void Enqueue([[maybe_unused]] ark::mem::Reference *clearedReferences) final
64     {
65         UNREACHABLE();
66     }
67 
68     /// @return size of the queue of weak references
69     size_t GetReferenceQueueSize() const final;
70 
71     /// Process native finalizers of FinalizableWeakRef
72     void ProcessFinalizers() final;
73 
74 private:
75     template <typename Handler>
76     void ProcessReferences(const mem::GC::ReferenceClearPredicateT &pred, const Handler &handler);
77 
78     /// Add finalizer of dead referent of FinalizableWeakRef to the queue
79     void EnqueueFinalizer(ark::ets::EtsWeakReference *weakRef);
80 
81     /// Handle fields of references
82     template <bool USE_OBJECT_REF>
83     void HandleOtherFields(const BaseClass *cls, const ObjectHeader *object, const ReferenceProcessorT &processor);
84 
85     mem::MPSCSet<PandaUnorderedSet<ObjectHeader *>> weakReferences_;
86     GC *gc_ {nullptr};
87     ark::ets::EtsObject *nullValue_ {nullptr};
88     PandaDeque<RefFinalizer> finalizerQueue_;
89 };
90 
91 template <typename Handler>
ProcessReferences(const mem::GC::ReferenceClearPredicateT & pred,const Handler & handler)92 void EtsReferenceProcessor::ProcessReferences(const mem::GC::ReferenceClearPredicateT &pred, const Handler &handler)
93 {
94     weakReferences_.FlushSets();
95     while (!weakReferences_.IsEmpty()) {
96         auto *weakRefObj = weakReferences_.Extract();
97         ASSERT(ark::ets::EtsClass::FromRuntimeClass(weakRefObj->ClassAddr<Class>())->IsWeakReference());
98         auto *weakRef = static_cast<ark::ets::EtsWeakReference *>(ark::ets::EtsObject::FromCoreType(weakRefObj));
99         auto *referent = weakRef->GetReferent();
100         if (referent == nullptr || referent == nullValue_) {
101             LOG(DEBUG, REF_PROC) << "Don't process reference " << GetDebugInfoAboutObject(weakRefObj)
102                                  << " because referent is nullish";
103             continue;
104         }
105         auto *referentObj = referent->GetCoreType();
106         if (!pred(referentObj)) {
107             LOG(DEBUG, REF_PROC) << "Don't process reference " << GetDebugInfoAboutObject(weakRefObj)
108                                  << " because referent " << GetDebugInfoAboutObject(referentObj) << " failed predicate";
109             continue;
110         }
111 
112         handler(weakRefObj, referentObj);
113     }
114 }
115 }  // namespace ark::mem::ets
116 
117 #endif  // PANDA_PLUGINS_ETS_RUNTIME_MEM_ETS_REFERENCE_PROCESSOR_H
118