• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-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_MEM_GC_REFERENCE_PROCESSOR_REFERENCE_PROCESSOR_H
17 #define PANDA_MEM_GC_REFERENCE_PROCESSOR_REFERENCE_PROCESSOR_H
18 
19 #include "libpandabase/macros.h"
20 #include "runtime/include/coretypes/tagged_value.h"
21 #include "runtime/include/mem/panda_containers.h"
22 #include "runtime/mem/gc/gc_root.h"
23 #include "runtime/mem/gc/gc.h"
24 
25 namespace ark {
26 class ObjectHeader;
27 class BaseClass;
28 namespace mem {
29 enum class GCPhase;
30 class GC;
31 class Reference;
32 }  // namespace mem
33 }  // namespace ark
34 
35 namespace ark::mem {
36 
37 /// General language-independent interface for ReferenceProcessing.
38 class ReferenceProcessor {
39 public:
40     using ReferenceCheckPredicateT = typename GC::ReferenceCheckPredicateT;
41     using ReferenceProcessPredicateT = typename GC::ReferenceProcessPredicateT;
42     using ReferenceProcessorT = typename GC::ReferenceProcessorT;
43 
44     explicit ReferenceProcessor() = default;
45     NO_COPY_SEMANTIC(ReferenceProcessor);
46     NO_MOVE_SEMANTIC(ReferenceProcessor);
47     virtual ~ReferenceProcessor() = default;
48 
Initialize()49     virtual void Initialize() {}
50 
51     /**
52      * True if current object is Reference and it's referent is not marked yet (maybe need to process this reference)
53      * Predicate checks GC-specific conditions on this reference (i.e. if we need to skip this reference e.g. referent
54      * is not in collection set)
55      */
56     virtual bool IsReference(const BaseClass *baseCls, const ObjectHeader *ref,
57                              const ReferenceCheckPredicateT &pred) const = 0;
58     /// True if current object is Reference and referent in collection set
IsReference(const BaseClass * baseCls,const ObjectHeader * ref)59     virtual bool IsReference([[maybe_unused]] const BaseClass *baseCls, [[maybe_unused]] const ObjectHeader *ref) const
60     {
61         ASSERT_PRINT(false, "Should be implemented by subclasses");
62         return false;
63     }
64 
65     /**
66      * Save reference for future processing and handle it with GC point of view (mark needed fields, if necessary)
67      * Predicate checks if we should add this reference to the queue (e.g. don't process to many refs on concurrent)
68      */
69     virtual void HandleReference(GC *gc, GCMarkingStackType *objectsStack, const BaseClass *cls,
70                                  const ObjectHeader *object, const ReferenceProcessPredicateT &pred) = 0;
71     /// Save reference for future processing and handle it with GC point of view (traverse needed fields, if necessary)
HandleReference(GC * gc,const BaseClass * cls,const ObjectHeader * object,const ReferenceProcessorT & processor)72     virtual void HandleReference([[maybe_unused]] GC *gc, [[maybe_unused]] const BaseClass *cls,
73                                  [[maybe_unused]] const ObjectHeader *object,
74                                  [[maybe_unused]] const ReferenceProcessorT &processor)
75     {
76         ASSERT_PRINT(false, "Should be implemented by subclasses");
77     }
78 
79     /**
80      * Process all references which we discovered by GC.
81      * Predicate checks if we should process all references at once (e.g. processing takes too much time)
82      */
83     virtual void ProcessReferences(bool concurrent, bool clearSoftReferences, GCPhase gcPhase,
84                                    const mem::GC::ReferenceClearPredicateT &pred) = 0;
85     /**
86      * Process all references which we discovered by GC.
87      * Predicate checks which references should be processed
88      */
ProcessReferencesAfterCompaction(bool clearSoftReferences,const mem::GC::ReferenceClearPredicateT & pred)89     virtual void ProcessReferencesAfterCompaction([[maybe_unused]] bool clearSoftReferences,
90                                                   [[maybe_unused]] const mem::GC::ReferenceClearPredicateT &pred)
91     {
92         ASSERT_PRINT(false, "Should be implemented by subclasses");
93     }
94 
95     /// Collect all processed references. They were cleared on the previous phase - we only collect them.
96     virtual ark::mem::Reference *CollectClearedReferences() = 0;
97 
98     virtual void ScheduleForEnqueue(Reference *clearedReferences) = 0;
99 
100     /// Enqueue cleared references to corresponding queue, if necessary.
101     virtual void Enqueue(ark::mem::Reference *clearedReferences) = 0;
102 
103     /// Return size of the queue of references.
104     virtual size_t GetReferenceQueueSize() const = 0;
105 
106     /// Process finalizers of references.
ProcessFinalizers()107     virtual void ProcessFinalizers() {}
108 };
109 
110 }  // namespace ark::mem
111 #endif  // PANDA_MEM_GC_REFERENCE_PROCESSOR_REFERENCE_PROCESSOR_H
112