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 ECMASCRIPT_MEM_SHARED_CONCURRENT_MARKER_H
17 #define ECMASCRIPT_MEM_SHARED_CONCURRENT_MARKER_H
18 
19 #include "ecmascript/mem/concurrent_marker.h"
20 #include "ecmascript/daemon/daemon_thread.h"
21 
22 namespace panda::ecmascript {
23 class EcmaVM;
24 class SharedHeap;
25 
26 class SharedConcurrentMarker {
27 public:
28     explicit SharedConcurrentMarker(EnableConcurrentMarkType type);
29     ~SharedConcurrentMarker() = default;
30 
31     /*
32      * Concurrent marking related configurations and utilities.
33      */
34     void EnableConcurrentMarking(EnableConcurrentMarkType type);
35 
IsEnabled() const36     bool IsEnabled() const
37     {
38         return !IsDisabled();
39     }
40 
IsDisabled() const41     bool IsDisabled() const
42     {
43         return enableMarkType_ == EnableConcurrentMarkType::DISABLE ||
44             enableMarkType_ == EnableConcurrentMarkType::CONFIG_DISABLE;
45     }
46 
ConfigConcurrentMark(bool enabled)47     void ConfigConcurrentMark(bool enabled)
48     {
49         enableMarkType_ = enabled ? EnableConcurrentMarkType::ENABLE :
50                           EnableConcurrentMarkType::CONFIG_DISABLE;
51     }
52 
IsRequestDisabled() const53     bool IsRequestDisabled() const
54     {
55         return enableMarkType_ == EnableConcurrentMarkType::REQUEST_DISABLE;
56     }
57 
IsConfigDisabled() const58     bool IsConfigDisabled() const
59     {
60         return enableMarkType_ == EnableConcurrentMarkType::CONFIG_DISABLE;
61     }
62 
IsTriggeredConcurrentMark() const63     bool IsTriggeredConcurrentMark() const
64     {
65         return isConcurrentMarking_;
66     }
67     void Mark(TriggerGCType gcType, GCReason gcReason);             // In daemon thread
68     void ReMark();                          // In daemon thread
69 
70     void Reset(bool clearGCBits = true);    // In daemon thread
71 
72     void ResetWorkManager(SharedGCWorkManager *sWorkManager);       // In js thread
73 
GetDuration() const74     double GetDuration() const
75     {
76         return duration_;
77     }
78 
GetHeapObjectSize() const79     double GetHeapObjectSize() const
80     {
81         return sHeapObjectSize_;
82     }
83 
84 private:
85     NO_COPY_SEMANTIC(SharedConcurrentMarker);
86     NO_MOVE_SEMANTIC(SharedConcurrentMarker);
87 
88     class RecursionScope {
89     public:
RecursionScope(SharedConcurrentMarker* sMarker)90         explicit RecursionScope(SharedConcurrentMarker* sMarker) : sMarker_(sMarker)
91         {
92             if (sMarker_->recursionDepth_++ != 0) {
93                 LOG_GC(FATAL) << "Recursion in SharedConcurrentMarker Constructor, depth: "
94                               << sMarker_->recursionDepth_;
95             }
96         }
~RecursionScope()97         ~RecursionScope()
98         {
99             if (--sMarker_->recursionDepth_ != 0) {
100                 LOG_GC(FATAL) << "Recursion in SharedConcurrentMarker Destructor, depth: "
101                               << sMarker_->recursionDepth_;
102             }
103         }
104     private:
105         SharedConcurrentMarker* sMarker_ {nullptr};
106     };
107 
SetDuration(double duration)108     void SetDuration(double duration)
109     {
110         duration_ = duration;
111     }
112 
113     void InitializeMarking();               // In daemon thread
114     void DoMarking();                       // In daemon thread
115     void FinishMarking(float spendTime);    // In daemon thread
116     void HandleMarkingFinished();           // In daemon thread
117 
118     void Finish();                          // In daemon thread
119 
120     SharedHeap *sHeap_ {nullptr};
121     DaemonThread *dThread_ {nullptr};
122 
123     // obtained from the shared heap instance.
124     SharedGCWorkManager *sWorkManager_ {nullptr};
125     size_t sHeapObjectSize_ {0};
126     double duration_ {0.0};
127     EnableConcurrentMarkType enableMarkType_ {EnableConcurrentMarkType::CONFIG_DISABLE};
128 
129     bool isConcurrentMarking_ {false};
130     int32_t recursionDepth_ {0};
131     TriggerGCType gcType_ {TriggerGCType::SHARED_GC};
132     GCReason gcReason_ {GCReason::OTHER};
133 };
134 }  // namespace panda::ecmascript
135 #endif  // ECMASCRIPT_MEM_SHARED_CONCURRENT_MARKER_H
136