• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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/partial_gc.h"
17 
18 #include "ecmascript/ecma_vm.h"
19 #include "ecmascript/mem/barriers-inl.h"
20 #include "ecmascript/mem/clock_scope.h"
21 #include "ecmascript/mem/concurrent_marker.h"
22 #include "ecmascript/mem/heap-inl.h"
23 #include "ecmascript/mem/mark_stack.h"
24 #include "ecmascript/mem/mem.h"
25 #include "ecmascript/mem/parallel_evacuator.h"
26 #include "ecmascript/mem/parallel_marker-inl.h"
27 #include "ecmascript/mem/space-inl.h"
28 #include "ecmascript/mem/visitor.h"
29 #include "ecmascript/mem/gc_stats.h"
30 #include "ecmascript/ecma_string_table.h"
31 #include "ecmascript/runtime_call_id.h"
32 
33 namespace panda::ecmascript {
PartialGC(Heap * heap)34 PartialGC::PartialGC(Heap *heap) : heap_(heap), workManager_(heap->GetWorkManager()) {}
35 
RunPhases()36 void PartialGC::RunPhases()
37 {
38     ECMA_BYTRACE_NAME(HITRACE_TAG_ARK, "PartialGC::RunPhases" + std::to_string(heap_->IsFullMark()));
39     MEM_ALLOCATE_AND_GC_TRACE(heap_->GetEcmaVM(), PartialGC_RunPhases);
40     ClockScope clockScope;
41 
42     markingInProgress_ = heap_->CheckOngoingConcurrentMarking();
43 
44     LOG_GC(DEBUG) << "markingInProgress_" << markingInProgress_;
45     Initialize();
46     Mark();
47     Sweep();
48     Evacuate();
49     Finish();
50     heap_->GetEcmaVM()->GetEcmaGCStats()->StatisticPartialGC(markingInProgress_, clockScope.GetPauseTime(), freeSize_);
51     LOG_GC(DEBUG) << "PartialGC::RunPhases " << clockScope.TotalSpentTime();
52 }
53 
Initialize()54 void PartialGC::Initialize()
55 {
56     ECMA_BYTRACE_NAME(HITRACE_TAG_ARK, "PartialGC::Initialize");
57     if (!markingInProgress_) {
58         LOG_GC(DEBUG) << "No ongoing Concurrent marking. Initializing...";
59         heap_->Prepare();
60         if (heap_->IsFullMark()) {
61             heap_->GetOldSpace()->SelectCSet();
62             heap_->GetAppSpawnSpace()->EnumerateRegions([](Region *current) {
63                 current->ClearMarkGCBitset();
64                 current->ClearCrossRegionRSet();
65             });
66             heap_->EnumerateNonNewSpaceRegions([](Region *current) {
67                 current->ResetAliveObject();
68             });
69         }
70         workManager_->Initialize(TriggerGCType::OLD_GC, ParallelGCTaskPhase::OLD_HANDLE_GLOBAL_POOL_TASK);
71 
72         freeSize_ = 0;
73         hugeSpaceFreeSize_ = 0;
74         oldSpaceCommitSize_ = heap_->GetOldSpace()->GetCommittedSize();
75         nonMoveSpaceCommitSize_ = heap_->GetNonMovableSpace()->GetCommittedSize();
76     }
77 }
78 
Finish()79 void PartialGC::Finish()
80 {
81     ECMA_BYTRACE_NAME(HITRACE_TAG_ARK, "PartialGC::Finish");
82     if (markingInProgress_) {
83         auto marker = heap_->GetConcurrentMarker();
84         marker->Reset(false);
85     } else {
86         workManager_->Finish();
87     }
88     if (heap_->IsFullMark()) {
89         heap_->GetSweeper()->TryFillSweptRegion();
90     }
91 }
92 
Mark()93 void PartialGC::Mark()
94 {
95     ECMA_BYTRACE_NAME(HITRACE_TAG_ARK, "PartialGC::Mark");
96     if (markingInProgress_) {
97         heap_->GetConcurrentMarker()->ReMark();
98         return;
99     }
100     heap_->GetNonMovableMarker()->MarkRoots(MAIN_THREAD_INDEX);
101     if (heap_->IsFullMark()) {
102         heap_->GetNonMovableMarker()->ProcessMarkStack(MAIN_THREAD_INDEX);
103     } else {
104         heap_->GetNonMovableMarker()->ProcessOldToNew(MAIN_THREAD_INDEX);
105         heap_->GetNonMovableMarker()->ProcessSnapshotRSet(MAIN_THREAD_INDEX);
106     }
107     heap_->WaitRunningTaskFinished();
108 }
109 
Sweep()110 void PartialGC::Sweep()
111 {
112     ECMA_BYTRACE_NAME(HITRACE_TAG_ARK, "PartialGC::Sweep");
113     ProcessNativeDelete();
114     if (heap_->IsFullMark()) {
115         heap_->GetSweeper()->Sweep();
116     }
117 }
118 
ProcessNativeDelete()119 void PartialGC::ProcessNativeDelete()
120 {
121     WeakRootVisitor gcUpdateWeak = [this](TaggedObject *header) {
122         Region *objectRegion = Region::ObjectAddressToRange(reinterpret_cast<TaggedObject *>(header));
123         if (!objectRegion->InYoungSpaceOrCSet() && !heap_->IsFullMark()) {
124             return header;
125         }
126         if (!objectRegion->Test(header)) {
127             return reinterpret_cast<TaggedObject *>(ToUintPtr(nullptr));
128         }
129         return header;
130     };
131     heap_->GetEcmaVM()->ProcessNativeDelete(gcUpdateWeak);
132 }
133 
Evacuate()134 void PartialGC::Evacuate()
135 {
136     ECMA_BYTRACE_NAME(HITRACE_TAG_ARK, "PartialGC::Evacuate");
137     heap_->GetEvacuator()->Evacuate();
138 }
139 }  // namespace panda::ecmascript
140