1 /*
2 * Copyright (c) 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 #include "ecmascript/cross_vm/unified_gc/unified_gc.h"
17 #include "ecmascript/cross_vm/unified_gc/unified_gc_marker.h"
18 #include "ecmascript/checkpoint/thread_state_transition.h"
19 #include "ecmascript/mem/heap.h"
20 #include "ecmascript/mem/concurrent_sweeper.h"
21 #include "ecmascript/mem/verification.h"
22
23 namespace panda::ecmascript {
StartUnifiedGCMark(TriggerGCType gcType,GCReason gcReason)24 void SharedHeap::StartUnifiedGCMark([[maybe_unused]]TriggerGCType gcType, [[maybe_unused]]GCReason gcReason)
25 {
26 ASSERT(gcType == TriggerGCType::UNIFIED_GC && gcReason == GCReason::CROSSREF_CAUSE);
27 ASSERT(JSThread::GetCurrent() == dThread_);
28 {
29 ThreadManagedScope runningScope(dThread_);
30 SuspendAllScope scope(dThread_);
31 Runtime *runtime = Runtime::GetInstance();
32 std::vector<RecursionScope> recurScopes;
33 // The approximate size is enough, because even if some thread creates and registers after here, it will keep
34 // waiting in transition to RUNNING state before JSThread::SetReadyForGCIterating.
35 recurScopes.reserve(runtime->ApproximateThreadListSize());
36 runtime->GCIterateThreadList([&recurScopes](JSThread *thread) {
37 Heap *heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap());
38 recurScopes.emplace_back(heap, HeapType::LOCAL_HEAP);
39 });
40 #ifdef PANDA_JS_ETS_HYBRID_MODE
41 if (!unifiedGC_->StartXGCBarrier()) {
42 unifiedGC_->SetInterruptUnifiedGC(false);
43 dThread_->FinishRunningTask();
44 return;
45 }
46 #endif // PANDA_JS_ETS_HYBRID_MODE
47 runtime->GCIterateThreadList([gcType](JSThread *thread) {
48 Heap *heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap());
49 if (UNLIKELY(heap->ShouldVerifyHeap())) { // LCOV_EXCL_BR_LINE
50 // pre unified gc heap verify
51 LOG_ECMA(DEBUG) << "pre unified gc heap verify";
52 heap->ProcessSharedGCRSetWorkList();
53 Verification(heap, VerifyKind::VERIFY_PRE_GC).VerifyAll();
54 }
55 heap->SetGCType(gcType);
56 });
57 unifiedGC_->RunPhases();
58 runtime->GCIterateThreadList([](JSThread *thread) {
59 Heap *heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap());
60 if (UNLIKELY(heap->ShouldVerifyHeap())) { // LCOV_EXCL_BR_LINE
61 // post unified gc heap verify
62 LOG_ECMA(DEBUG) << "post unified gc heap verify";
63 Verification(heap, VerifyKind::VERIFY_POST_GC).VerifyAll();
64 }
65 });
66 #ifdef PANDA_JS_ETS_HYBRID_MODE
67 unifiedGC_->FinishXGCBarrier();
68 #endif // PANDA_JS_ETS_HYBRID_MODE
69 }
70 }
71
CreateUnifiedGC()72 void SharedHeap::CreateUnifiedGC()
73 {
74 unifiedGC_ = new UnifiedGC();
75 }
76
UnifiedGCPrepare()77 void Heap::UnifiedGCPrepare()
78 {
79 WaitRunningTaskFinished();
80 sweeper_->EnsureAllTaskFinished();
81 WaitClearTaskFinished();
82 }
83
CreateUnifiedGCMarker()84 void Heap::CreateUnifiedGCMarker()
85 {
86 unifiedGCMarker_ = new UnifiedGCMarker(this);
87 }
88
GetRunningTaskCount()89 uint32_t BaseHeap::GetRunningTaskCount()
90 {
91 LockHolder holder(waitTaskFinishedMutex_);
92 return runningTaskCount_;
93 }
94 } // namespace panda::ecmascript
95