• 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/gc_stats.h"
17 
18 #include "ecmascript/mem/heap.h"
19 #include "ecmascript/mem/mem.h"
20 
21 namespace panda::ecmascript {
PrintStatisticResult(bool isForce)22 void GCStats::PrintStatisticResult(bool isForce)
23 {
24     LOG(INFO, RUNTIME) << "/******************* GCStats statistic: *******************/";
25     PrintSemiStatisticResult(isForce);
26     PrintMixStatisticResult(isForce);
27     PrintCompressStatisticResult(isForce);
28     PrintHeapStatisticResult(isForce);
29 }
30 
PrintSemiStatisticResult(bool isForce)31 void GCStats::PrintSemiStatisticResult(bool isForce)
32 {
33     if ((isForce && semiGCCount_ != 0) || (!isForce && semiGCCount_ != lastSemiGCCount_)) {
34         lastSemiGCCount_ = semiGCCount_;
35         LOG(INFO, RUNTIME) << " STWYoungGC statistic: total semi gc count " << semiGCCount_;
36         LOG(INFO, RUNTIME) << " MIN pause time: " << PrintTimeMilliseconds(semiGCMinPause_) << "ms"
37                             << " MAX pause time: " << PrintTimeMilliseconds(semiGCMAXPause_) << "ms"
38                             << " total pause time: " << PrintTimeMilliseconds(semiGCTotalPause_) << "ms"
39                             << " average pause time: " << PrintTimeMilliseconds(semiGCTotalPause_ / semiGCCount_)
40                             << "ms"
41                             << " tatal alive size: " << sizeToMB(semiTotalAliveSize_) << "MB"
42                             << " average alive size: " << sizeToMB(semiTotalAliveSize_ / semiGCCount_) << "MB"
43                             << " tatal commit size: " << sizeToMB(semiTotalCommitSize_) << "MB"
44                             << " average commit size: " << sizeToMB(semiTotalCommitSize_ / semiGCCount_) << "MB"
45                             << " semi aliveRate: " << double(semiTotalAliveSize_) / semiTotalCommitSize_
46                             << " total promote size: " << sizeToMB(semiTotalPromoteSize_) << "MB"
47                             << " average promote size: " << sizeToMB(semiTotalPromoteSize_ / semiGCCount_) << "MB";
48     }
49 }
50 
PrintMixStatisticResult(bool isForce)51 void GCStats::PrintMixStatisticResult(bool isForce)
52 {
53     if ((isForce && mixGCCount_ != 0) || (!isForce && lastOldGCCount_ != mixGCCount_)) {
54         lastOldGCCount_ = mixGCCount_;
55         LOG(INFO, RUNTIME) << " MixGC with non-concurrent mark statistic: total old gc count " << mixGCCount_;
56         LOG(INFO, RUNTIME) << " Pause time statistic:: MIN pause time: " << PrintTimeMilliseconds(mixGCMinPause_)
57                             << "ms"
58                             << " MAX pause time: " << PrintTimeMilliseconds(mixGCMAXPause_) << "ms"
59                             << " total pause time: " << PrintTimeMilliseconds(mixGCTotalPause_) << "ms"
60                             << " average pause time: " << PrintTimeMilliseconds(mixGCTotalPause_ / mixGCCount_) << "ms";
61         if (!isForce) {
62             PrintHeapStatisticResult(true);
63         }
64     }
65 
66     if ((isForce && mixConcurrentMarkGCCount_ != 0) ||
67             (!isForce && lastOldConcurrentMarkGCCount_ != mixConcurrentMarkGCCount_)) {
68         lastOldConcurrentMarkGCCount_ = mixConcurrentMarkGCCount_;
69         LOG(INFO, RUNTIME) << " MixCollector with concurrent mark statistic: total old gc count "
70                             << mixConcurrentMarkGCCount_;
71         LOG(INFO, RUNTIME) << " Pause time statistic:: Current GC pause time: "
72                             << PrintTimeMilliseconds(mixConcurrentMarkGCPauseTime_) << "ms"
73                             << " Concurrent mark pause time: " << PrintTimeMilliseconds(mixConcurrentMarkMarkPause_)
74                             << "ms"
75                             << " Concurrent mark wait time: " << PrintTimeMilliseconds(mixConcurrentMarkWaitPause_)
76                             << "ms"
77                             << " Remark pause time: " << PrintTimeMilliseconds(mixConcurrentMarkRemarkPause_) << "ms"
78                             << " Evacuate pause time: " << PrintTimeMilliseconds(mixConcurrentMarkEvacuatePause_)
79                             << "ms"
80                             << " MIN pause time: " << PrintTimeMilliseconds(mixConcurrentMarkGCMinPause_) << "ms"
81                             << " MAX pause time: " << PrintTimeMilliseconds(mixConcurrentMarkGCMAXPause_) << "ms"
82                             << " total pause time: " << PrintTimeMilliseconds(mixConcurrentMarkGCTotalPause_) << "ms"
83                             << " average pause time: "
84                             << PrintTimeMilliseconds(mixConcurrentMarkGCTotalPause_ / mixConcurrentMarkGCCount_)
85                             << "ms";
86         if (!isForce) {
87             PrintHeapStatisticResult(true);
88         }
89     }
90 }
91 
PrintCompressStatisticResult(bool isForce)92 void GCStats::PrintCompressStatisticResult(bool isForce)
93 {
94     if ((isForce && fullGCCount_ != 0) || (!isForce && fullGCCount_ != lastFullGCCount_)) {
95         lastFullGCCount_ = fullGCCount_;
96         LOG(INFO, RUNTIME) << " FullGC statistic: total compress gc count " << fullGCCount_;
97         LOG(INFO, RUNTIME)
98             << " MIN pause time: " << PrintTimeMilliseconds(fullGCMinPause_) << "ms"
99             << " MAX pause time: " << PrintTimeMilliseconds(fullGCMaxPause_) << "ms"
100             << " total pause time: " << PrintTimeMilliseconds(fullGCTotalPause_) << "ms"
101             << " average pause time: " << PrintTimeMilliseconds(fullGCTotalPause_ / fullGCCount_) << "ms"
102             << " young and old total alive size: " << sizeToMB(compressYoungAndOldAliveSize_) << "MB"
103             << " young and old average alive size: " << sizeToMB(compressYoungAndOldAliveSize_ / fullGCCount_)
104             << "MB"
105             << " young total commit size: " << sizeToMB(compressYoungCommitSize_) << "MB"
106             << " old total commit size: " << sizeToMB(compressOldCommitSize_) << "MB"
107             << " young and old average commit size: "
108             << sizeToMB((compressYoungCommitSize_ + compressOldCommitSize_) / fullGCCount_) << "MB"
109             << " young and old free rate: "
110             << 1 - float(compressYoungAndOldAliveSize_) / (compressYoungCommitSize_ + compressOldCommitSize_)
111             << " non move total free size: " << sizeToMB(compressNonMoveTotalFreeSize_) << "MB"
112             << " non move total commit size: " << sizeToMB(compressNonMoveTotalCommitSize_) << "MB"
113             << " non move free rate: " << float(compressNonMoveTotalFreeSize_) / compressNonMoveTotalCommitSize_;
114     }
115 }
116 
PrintHeapStatisticResult(bool isForce)117 void GCStats::PrintHeapStatisticResult(bool isForce)
118 {
119     if (isForce && heap_ != nullptr) {
120         NativeAreaAllocator *nativeAreaAllocator = const_cast<NativeAreaAllocator *>(heap_->GetNativeAreaAllocator());
121         HeapRegionAllocator *heapRegionAllocator = const_cast<HeapRegionAllocator *>(heap_->GetHeapRegionAllocator());
122         LOG(INFO, RUNTIME) << "/******************* Memory statistic: *******************/";
123         LOG(INFO, RUNTIME) << " Anno memory usage size:" << sizeToMB(heapRegionAllocator->GetAnnoMemoryUsage())
124                             << "MB"
125                             << " anno memory max usage size:" << sizeToMB(heapRegionAllocator->GetMaxAnnoMemoryUsage())
126                             << "MB"
127                             << " native memory usage size:" << sizeToMB(nativeAreaAllocator->GetNativeMemoryUsage())
128                             << "MB"
129                             << " native memory max usage size:"
130                             << sizeToMB(nativeAreaAllocator->GetMaxNativeMemoryUsage()) << "MB";
131         LOG(INFO, RUNTIME) << " Semi space commit size" << sizeToMB(heap_->GetNewSpace()->GetCommittedSize()) << "MB"
132                             << " semi space heap object size: " << sizeToMB(heap_->GetNewSpace()->GetHeapObjectSize())
133                             << "MB"
134                             << " old space commit size: "
135                             << sizeToMB(heap_->GetOldSpace()->GetCommittedSize()) << "MB"
136                             << " old space heap object size: " << sizeToMB(heap_->GetOldSpace()->GetHeapObjectSize())
137                             << "MB"
138                             << " non move space commit size: "
139                             << sizeToMB(heap_->GetNonMovableSpace()->GetCommittedSize()) << "MB"
140                             << " huge object space commit size: "
141                             << sizeToMB(heap_->GetHugeObjectSpace()->GetCommittedSize()) << "MB";
142     }
143 }
144 
StatisticSTWYoungGC(Duration time,size_t aliveSize,size_t promoteSize,size_t commitSize)145 void GCStats::StatisticSTWYoungGC(Duration time, size_t aliveSize, size_t promoteSize, size_t commitSize)
146 {
147     auto timeToMillion = TimeToMicroseconds(time);
148     if (semiGCCount_ == 0) {
149         semiGCMinPause_ = timeToMillion;
150         semiGCMAXPause_ = timeToMillion;
151     } else {
152         semiGCMinPause_ = std::min(semiGCMinPause_, timeToMillion);
153         semiGCMAXPause_ = std::max(semiGCMAXPause_, timeToMillion);
154     }
155     semiGCTotalPause_ += timeToMillion;
156     semiTotalAliveSize_ += aliveSize;
157     semiTotalCommitSize_ += commitSize;
158     semiTotalPromoteSize_ += promoteSize;
159     semiGCCount_++;
160 }
161 
StatisticMixGC(bool concurrentMark,Duration time,size_t freeSize)162 void GCStats::StatisticMixGC(bool concurrentMark, Duration time, size_t freeSize)
163 {
164     auto timeToMillion = TimeToMicroseconds(time);
165     if (concurrentMark) {
166         timeToMillion += mixConcurrentMarkMarkPause_;
167         timeToMillion += mixConcurrentMarkWaitPause_;
168         if (mixConcurrentMarkGCCount_ == 0) {
169             mixConcurrentMarkGCMinPause_ = timeToMillion;
170             mixConcurrentMarkGCMAXPause_ = timeToMillion;
171         } else {
172             mixConcurrentMarkGCMinPause_ = std::min(mixConcurrentMarkGCMinPause_, timeToMillion);
173             mixConcurrentMarkGCMAXPause_ = std::max(mixConcurrentMarkGCMAXPause_, timeToMillion);
174         }
175         mixConcurrentMarkGCPauseTime_ = timeToMillion;
176         mixConcurrentMarkGCTotalPause_ += timeToMillion;
177         mixOldSpaceConcurrentMarkFreeSize_ = freeSize;
178         mixConcurrentMarkGCCount_++;
179     } else {
180         if (mixGCCount_ == 0) {
181             mixGCMinPause_ = timeToMillion;
182             mixGCMAXPause_ = timeToMillion;
183         } else {
184             mixGCMinPause_ = std::min(mixGCMinPause_, timeToMillion);
185             mixGCMAXPause_ = std::max(mixGCMAXPause_, timeToMillion);
186         }
187         mixGCTotalPause_ += timeToMillion;
188         mixOldSpaceFreeSize_ = freeSize;
189         mixGCCount_++;
190     }
191 }
192 
StatisticFullGC(Duration time,size_t youngAndOldAliveSize,size_t youngCommitSize,size_t oldCommitSize,size_t nonMoveSpaceFreeSize,size_t nonMoveSpaceCommitSize)193 void GCStats::StatisticFullGC(Duration time, size_t youngAndOldAliveSize, size_t youngCommitSize,
194                               size_t oldCommitSize, size_t nonMoveSpaceFreeSize,
195                               size_t nonMoveSpaceCommitSize)
196 {
197     auto timeToMillion = TimeToMicroseconds(time);
198     if (fullGCCount_ == 0) {
199         fullGCMinPause_ = timeToMillion;
200         fullGCMaxPause_ = timeToMillion;
201     } else {
202         fullGCMinPause_ = std::min(fullGCMinPause_, timeToMillion);
203         fullGCMaxPause_ = std::max(fullGCMaxPause_, timeToMillion);
204     }
205     fullGCTotalPause_ += timeToMillion;
206     compressYoungAndOldAliveSize_ += youngAndOldAliveSize;
207     compressYoungCommitSize_ += youngCommitSize;
208     compressOldCommitSize_ += oldCommitSize;
209     compressNonMoveTotalFreeSize_ += nonMoveSpaceFreeSize;
210     compressNonMoveTotalCommitSize_ += nonMoveSpaceCommitSize;
211     fullGCCount_++;
212 }
213 
StatisticConcurrentMark(Duration time)214 void GCStats::StatisticConcurrentMark(Duration time)
215 {
216     mixConcurrentMarkMarkPause_ = TimeToMicroseconds(time);
217 }
218 
StatisticConcurrentMarkWait(Duration time)219 void GCStats::StatisticConcurrentMarkWait(Duration time)
220 {
221     mixConcurrentMarkWaitPause_ = TimeToMicroseconds(time);
222 }
223 
StatisticConcurrentEvacuate(Duration time)224 void GCStats::StatisticConcurrentEvacuate(Duration time)
225 {
226     mixConcurrentMarkEvacuatePause_ = TimeToMicroseconds(time);
227 }
228 
StatisticConcurrentRemark(Duration time)229 void GCStats::StatisticConcurrentRemark(Duration time)
230 {
231     mixConcurrentMarkRemarkPause_ = TimeToMicroseconds(time);
232 }
233 }  // namespace panda::ecmascript
234