• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-2022 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 "runtime/mem/mem_stats_additional_info.h"
17 
18 #include "runtime/include/class-inl.h"
19 #include "runtime/include/runtime.h"
20 
21 namespace panda::mem {
22 
GetAdditionalStatistics(HeapManager * heap_manager)23 PandaString MemStatsAdditionalInfo::GetAdditionalStatistics(HeapManager *heap_manager)
24 {
25     PandaVector<Class *> classes;
26     auto class_linker = Runtime::GetCurrent()->GetClassLinker();
27     class_linker->EnumerateClasses([&classes](Class *cls) {
28         classes.push_back(cls);
29         return true;
30     });
31 
32     PandaVector<uint64_t> footprint_of_classes(classes.size(), 0U);
33     heap_manager->CountInstances(classes, true, footprint_of_classes.data());
34 
35     PandaMultiMap<uint64_t, Class *> footprint_to_class;
36     for (size_t index = 0; index < classes.size(); ++index) {
37         footprint_to_class.insert({footprint_of_classes[index], classes[index]});
38     }
39 
40     PandaStringStream statistic;
41     PandaMultiMap<uint64_t, Class *>::reverse_iterator rit;
42     for (rit = footprint_to_class.rbegin(); rit != footprint_to_class.rend(); ++rit) {
43         if (rit->first == 0U) {
44             break;
45         }
46         auto clazz = rit->second;
47         statistic << "class: " << clazz->GetName() << ", footprint - " << rit->first << std::endl;
48     }
49     return statistic.str();
50 }
51 
RecordGCPhaseStart(GCPhase phase)52 void MemStatsAdditionalInfo::RecordGCPhaseStart(GCPhase phase)
53 {
54     os::memory::LockHolder lk(phase_lock_);
55     if (current_phase_ != GCPhase::GC_PHASE_LAST) {
56         RecordGCPauseEnd();
57     }
58     phase_start_time_ = clock::now();
59     current_phase_ = phase;
60 }
61 
RecordGCPhaseEnd()62 void MemStatsAdditionalInfo::RecordGCPhaseEnd()
63 {
64     os::memory::LockHolder lk(phase_lock_);
65     ASSERT(current_phase_ != GCPhase::GC_PHASE_LAST);
66 
67     uint64_t phase_index = ToIndex(current_phase_);
68     duration phase_time = clock::now() - phase_start_time_;
69     if (phase_count_[phase_index] != 0) {
70         min_phase_time_[phase_index] = std::min(min_phase_time_[phase_index], phase_time);
71         max_phase_time_[phase_index] = std::max(max_phase_time_[phase_index], phase_time);
72     } else {
73         min_phase_time_[phase_index] = phase_time;
74         max_phase_time_[phase_index] = phase_time;
75     }
76     phase_count_[phase_index]++;
77     sum_phase_time_[phase_index] += phase_time;
78 
79     current_phase_ = GCPhase::GC_PHASE_LAST;
80 }
81 
GetMinGCPhaseTime(GCPhase phase)82 uint64_t MemStatsAdditionalInfo::GetMinGCPhaseTime(GCPhase phase)
83 {
84     os::memory::LockHolder lk(phase_lock_);
85     return std::chrono::duration_cast<std::chrono::milliseconds>(min_phase_time_[ToIndex(phase)]).count();
86 }
87 
GetMaxGCPhaseTime(GCPhase phase)88 uint64_t MemStatsAdditionalInfo::GetMaxGCPhaseTime(GCPhase phase)
89 {
90     os::memory::LockHolder lk(phase_lock_);
91     return std::chrono::duration_cast<std::chrono::milliseconds>(max_phase_time_[ToIndex(phase)]).count();
92 }
93 
GetAverageGCPhaseTime(GCPhase phase)94 uint64_t MemStatsAdditionalInfo::GetAverageGCPhaseTime(GCPhase phase)
95 {
96     os::memory::LockHolder lk(phase_lock_);
97     return phase_count_[ToIndex(phase)] != 0
98                ? static_cast<uint64_t>(
99                      std::chrono::duration_cast<std::chrono::milliseconds>(sum_phase_time_[ToIndex(phase)]).count()) /
100                      phase_count_[ToIndex(phase)]
101                : 0;
102 }
103 
GetTotalGCPhaseTime(GCPhase phase)104 uint64_t MemStatsAdditionalInfo::GetTotalGCPhaseTime(GCPhase phase)
105 {
106     os::memory::LockHolder lk(phase_lock_);
107     return std::chrono::duration_cast<std::chrono::milliseconds>(sum_phase_time_[ToIndex(phase)]).count();
108 }
109 
110 }  // namespace panda::mem
111