• 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 
16 #include "ecmascript/mem/shared_heap/shared_concurrent_marker.h"
17 
18 #include "ecmascript/checkpoint/thread_state_transition.h"
19 #include "ecmascript/mem/shared_heap/shared_gc_marker-inl.h"
20 #include "ecmascript/mem/verification.h"
21 #include "ecmascript/mem/verification.h"
22 
23 namespace panda::ecmascript {
SharedConcurrentMarker(EnableConcurrentMarkType type)24 SharedConcurrentMarker::SharedConcurrentMarker(EnableConcurrentMarkType type)
25     : sHeap_(SharedHeap::GetInstance()),
26       dThread_(DaemonThread::GetInstance()),
27       sWorkManager_(sHeap_->GetWorkManager()),
28       enableMarkType_(type) {}
29 
EnableConcurrentMarking(EnableConcurrentMarkType type)30 void SharedConcurrentMarker::EnableConcurrentMarking(EnableConcurrentMarkType type)
31 {
32     if (IsConfigDisabled()) {
33         return;
34     }
35     if (IsEnabled() && !dThread_->IsReadyToConcurrentMark() && type == EnableConcurrentMarkType::DISABLE) {
36         enableMarkType_ = EnableConcurrentMarkType::REQUEST_DISABLE;
37     } else {
38         enableMarkType_ = type;
39     }
40 }
41 
Mark(TriggerGCType gcType,GCReason gcReason)42 void SharedConcurrentMarker::Mark(TriggerGCType gcType, GCReason gcReason)
43 {
44     RecursionScope recurScope(this);
45     gcType_ = gcType;
46     gcReason_ = gcReason;
47     sHeap_->WaitSensitiveStatusFinished();
48     {
49         ThreadManagedScope runningScope(dThread_);
50         SuspendAllScope scope(dThread_);
51         TRACE_GC(GCStats::Scope::ScopeId::ConcurrentMark, sHeap_->GetEcmaGCStats());
52         LOG_GC(DEBUG) << "SharedConcurrentMarker: Concurrent Marking Begin";
53         ECMA_BYTRACE_NAME(HITRACE_TAG_ARK, "SharedConcurrentMarker::Mark");
54         CHECK_DAEMON_THREAD();
55         // TODO: support shared runtime state
56         if (UNLIKELY(sHeap_->ShouldVerifyHeap())) {
57             SharedHeapVerification(sHeap_, VerifyKind::VERIFY_PRE_SHARED_GC).VerifyAll();
58         }
59         InitializeMarking();
60     }
61     // Daemon thread do not need to post task to GC_Thread
62     ASSERT(!dThread_->IsInRunningState());
63     DoMarking();
64     HandleMarkingFinished();
65 }
66 
Finish()67 void SharedConcurrentMarker::Finish()
68 {
69     sWorkManager_->Finish();
70 }
71 
ReMark()72 void SharedConcurrentMarker::ReMark()
73 {
74     CHECK_DAEMON_THREAD();
75 #ifndef NDEBUG
76     ASSERT(dThread_->HasLaunchedSuspendAll());
77 #endif
78     TRACE_GC(GCStats::Scope::ScopeId::ReMark, sHeap_->GetEcmaGCStats());
79     LOG_GC(DEBUG) << "SharedConcurrentMarker: Remarking Begin";
80     // TODO: support shared runtime state
81     SharedGCMarker *sharedGCMarker = sHeap_->GetSharedGCMarker();
82     // If enable shared concurrent mark, the recorded weak reference slots from local to share may be changed
83     // during LocalGC. For now just re-scan the local_to_share bit to record and update these weak references.
84     sharedGCMarker->MarkRoots(DAEMON_THREAD_INDEX, SharedMarkType::CONCURRENT_MARK_REMARK);
85     sharedGCMarker->DoMark<SharedMarkType::CONCURRENT_MARK_REMARK>(DAEMON_THREAD_INDEX);
86     sharedGCMarker->MergeBackAndResetRSetWorkListHandler();
87     sHeap_->WaitRunningTaskFinished();
88 }
89 
Reset(bool clearGCBits)90 void SharedConcurrentMarker::Reset(bool clearGCBits)
91 {
92     Finish();
93     dThread_->SetSharedMarkStatus(SharedMarkStatus::READY_TO_CONCURRENT_MARK);
94     isConcurrentMarking_ = false;
95     if (clearGCBits) {
96         // Shared gc clear GC bits in ReclaimRegions after GC
97         auto callback = [](Region *region) {
98             region->ClearMarkGCBitset();
99             region->ResetAliveObject();
100         };
101         sHeap_->EnumerateOldSpaceRegions(callback);
102     }
103 }
104 
ResetWorkManager(SharedGCWorkManager * sWorkManager)105 void SharedConcurrentMarker::ResetWorkManager(SharedGCWorkManager *sWorkManager)
106 {
107     sWorkManager_ = sWorkManager;
108 }
109 
InitializeMarking()110 void SharedConcurrentMarker::InitializeMarking()
111 {
112     CHECK_DAEMON_THREAD();
113     // TODO: support shared runtime state
114     sHeap_->Prepare(true);
115     isConcurrentMarking_ = true;
116     dThread_->SetSharedMarkStatus(SharedMarkStatus::CONCURRENT_MARKING_OR_FINISHED);
117 
118     sHeapObjectSize_ = sHeap_->GetHeapObjectSize();
119     sHeap_->GetAppSpawnSpace()->EnumerateRegions([](Region *current) {
120         current->ClearMarkGCBitset();
121     });
122     sHeap_->EnumerateOldSpaceRegions([](Region *current) {
123         ASSERT(current->InSharedSweepableSpace());
124         current->ResetAliveObject();
125     });
126     sWorkManager_->Initialize(TriggerGCType::SHARED_GC, SharedParallelMarkPhase::SHARED_MARK_TASK);
127     sHeap_->GetSharedGCMarker()->MarkRoots(DAEMON_THREAD_INDEX, SharedMarkType::CONCURRENT_MARK_INITIAL_MARK);
128 }
129 
DoMarking()130 void SharedConcurrentMarker::DoMarking()
131 {
132     ClockScope clockScope;
133     sHeap_->GetSharedGCMarker()->DoMark<SharedMarkType::CONCURRENT_MARK_INITIAL_MARK>(DAEMON_THREAD_INDEX);
134     sHeap_->WaitRunningTaskFinished();
135     FinishMarking(clockScope.TotalSpentTime());
136 }
137 
FinishMarking(float spendTime)138 void SharedConcurrentMarker::FinishMarking(float spendTime)
139 {
140     sHeapObjectSize_ = sHeap_->GetHeapObjectSize();
141     SetDuration(spendTime);
142 }
143 
HandleMarkingFinished()144 void SharedConcurrentMarker::HandleMarkingFinished()
145 {
146     sHeap_->WaitSensitiveStatusFinished();
147     sHeap_->DaemonCollectGarbage(gcType_, gcReason_);
148 }
149 }  // namespace panda::ecmascript
150