• 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 "runtime/mem/mem_stats.h"
17 
18 #include "libpandabase/utils/utf.h"
19 #include "runtime/include/class.h"
20 #include "runtime/include/runtime.h"
21 #include "runtime/mem/mem_stats_additional_info.h"
22 #include "runtime/mem/mem_stats_default.h"
23 #include "runtime/mem/object_helpers.h"
24 
25 namespace panda::mem {
26 
27 template <typename T>
RecordAllocateObject(size_t size,SpaceType type_mem)28 void MemStats<T>::RecordAllocateObject(size_t size, SpaceType type_mem)
29 {
30     ASSERT(IsHeapSpace(type_mem));
31     RecordAllocate(size, type_mem);
32     if (type_mem == SpaceType::SPACE_TYPE_HUMONGOUS_OBJECT) {
33         humongous_objects_allocated_.fetch_add(1, std::memory_order_acq_rel);
34     } else {
35         objects_allocated_.fetch_add(1, std::memory_order_acq_rel);
36     }
37 }
38 
39 template <typename T>
RecordMovedObjects(size_t total_object_num,size_t size,SpaceType type_mem)40 void MemStats<T>::RecordMovedObjects(size_t total_object_num, size_t size, SpaceType type_mem)
41 {
42     ASSERT(IsHeapSpace(type_mem));
43     RecordMoved(size, type_mem);
44     // We can't move SPACE_TYPE_HUMONGOUS_OBJECT
45     ASSERT(type_mem != SpaceType::SPACE_TYPE_HUMONGOUS_OBJECT);
46     uint64_t old_val = objects_allocated_.fetch_sub(total_object_num, std::memory_order_acq_rel);
47     (void)old_val;
48     ASSERT(old_val >= total_object_num);
49 }
50 
51 template <typename T>
RecordFreeObject(size_t object_size,SpaceType type_mem)52 void MemStats<T>::RecordFreeObject(size_t object_size, SpaceType type_mem)
53 {
54     ASSERT(IsHeapSpace(type_mem));
55     RecordFree(object_size, type_mem);
56     if (type_mem == SpaceType::SPACE_TYPE_HUMONGOUS_OBJECT) {
57         humongous_objects_freed_.fetch_add(1, std::memory_order_acq_rel);
58     } else {
59         objects_freed_.fetch_add(1, std::memory_order_acq_rel);
60     }
61 }
62 
63 template <typename T>
RecordFreeObjects(size_t total_object_num,size_t total_object_size,SpaceType type_mem)64 void MemStats<T>::RecordFreeObjects(size_t total_object_num, size_t total_object_size, SpaceType type_mem)
65 {
66     ASSERT(IsHeapSpace(type_mem));
67     RecordFree(total_object_size, type_mem);
68     if (type_mem == SpaceType::SPACE_TYPE_HUMONGOUS_OBJECT) {
69         humongous_objects_freed_.fetch_add(total_object_num, std::memory_order_acq_rel);
70     } else {
71         objects_freed_.fetch_add(total_object_num, std::memory_order_acq_rel);
72     }
73 }
74 
75 template <typename T>
GetStatistics(HeapManager * heap_manager)76 PandaString MemStats<T>::GetStatistics(HeapManager *heap_manager)
77 {
78     PandaStringStream statistic;
79     statistic << "memory statistics:" << std::endl;
80     statistic << "heap: allocated - " << GetAllocatedHeap() << ", freed - " << GetFreedHeap() << std::endl;
81     statistic << "raw memory: allocated - " << GetAllocated(SpaceType::SPACE_TYPE_INTERNAL) << ", freed - "
82               << GetFreed(SpaceType::SPACE_TYPE_INTERNAL) << std::endl;
83     statistic << "compiler: allocated - " << GetAllocated(SpaceType::SPACE_TYPE_CODE) << std::endl;
84     statistic << "ArenaAllocator: allocated - " << GetAllocated(SpaceType::SPACE_TYPE_COMPILER) << std::endl;
85     statistic << "total footprint now - " << GetTotalFootprint() << std::endl;
86     statistic << "total allocated object - " << GetTotalObjectsAllocated() << std::endl;
87     statistic << "min GC pause time - " << GetMinGCPause() << std::endl;
88     statistic << "max GC pause time - " << GetMaxGCPause() << std::endl;
89     statistic << "average GC pause time - " << GetAverageGCPause() << std::endl;
90     statistic << "total GC pause time - " << GetTotalGCPause() << std::endl;
91     auto additional_statistics = static_cast<T *>(this)->GetAdditionalStatistics(heap_manager);
92     return statistic.str() + additional_statistics;
93 }
94 
95 template <typename T>
GetTotalObjectsAllocated() const96 [[nodiscard]] uint64_t MemStats<T>::GetTotalObjectsAllocated() const
97 {
98     return objects_allocated_.load(std::memory_order_acquire);
99 }
100 
101 template <typename T>
GetTotalObjectsFreed() const102 [[nodiscard]] uint64_t MemStats<T>::GetTotalObjectsFreed() const
103 {
104     return objects_freed_.load(std::memory_order_acquire);
105 }
106 
107 template <typename T>
GetTotalRegularObjectsAllocated() const108 [[nodiscard]] uint64_t MemStats<T>::GetTotalRegularObjectsAllocated() const
109 {
110     return GetTotalObjectsAllocated() - GetTotalHumongousObjectsAllocated();
111 }
112 
113 template <typename T>
GetTotalRegularObjectsFreed() const114 [[nodiscard]] uint64_t MemStats<T>::GetTotalRegularObjectsFreed() const
115 {
116     return GetTotalObjectsFreed() - GetTotalHumongousObjectsFreed();
117 }
118 
119 template <typename T>
GetTotalHumongousObjectsAllocated() const120 [[nodiscard]] uint64_t MemStats<T>::GetTotalHumongousObjectsAllocated() const
121 {
122     return humongous_objects_allocated_.load(std::memory_order_acquire);
123 }
124 
125 template <typename T>
GetTotalHumongousObjectsFreed() const126 [[nodiscard]] uint64_t MemStats<T>::GetTotalHumongousObjectsFreed() const
127 {
128     return humongous_objects_freed_.load(std::memory_order_acquire);
129 }
130 
131 template <typename T>
GetObjectsCountAlive() const132 [[nodiscard]] uint64_t MemStats<T>::GetObjectsCountAlive() const
133 {
134     return GetTotalObjectsAllocated() - GetTotalObjectsFreed();
135 }
136 
137 template <typename T>
GetRegularObjectsCountAlive() const138 [[nodiscard]] uint64_t MemStats<T>::GetRegularObjectsCountAlive() const
139 {
140     return GetTotalRegularObjectsAllocated() - GetTotalRegularObjectsFreed();
141 }
142 
143 template <typename T>
GetHumonguousObjectsCountAlive() const144 [[nodiscard]] uint64_t MemStats<T>::GetHumonguousObjectsCountAlive() const
145 {
146     return GetTotalHumongousObjectsAllocated() - GetTotalHumongousObjectsFreed();
147 }
148 
149 template <typename T>
RecordGCPauseStart()150 void MemStats<T>::RecordGCPauseStart()
151 {
152     pause_start_time_ = clock::now();
153 }
154 
155 template <typename T>
RecordGCPauseEnd()156 void MemStats<T>::RecordGCPauseEnd()
157 {
158     duration pause_time = clock::now() - pause_start_time_;
159     if (pause_count_) {
160         min_pause_ = std::min(min_pause_, pause_time);
161         max_pause_ = std::max(max_pause_, pause_time);
162     } else {
163         min_pause_ = pause_time;
164         max_pause_ = pause_time;
165     }
166     pause_count_++;
167     sum_pause_ += pause_time;
168 }
169 
170 template <typename T>
GetMinGCPause() const171 uint64_t MemStats<T>::GetMinGCPause() const
172 {
173     return std::chrono::duration_cast<std::chrono::milliseconds>(min_pause_).count();
174 }
175 
176 template <typename T>
GetMaxGCPause() const177 uint64_t MemStats<T>::GetMaxGCPause() const
178 {
179     return std::chrono::duration_cast<std::chrono::milliseconds>(max_pause_).count();
180 }
181 
182 template <typename T>
GetAverageGCPause() const183 uint64_t MemStats<T>::GetAverageGCPause() const
184 {
185     return pause_count_ ? std::chrono::duration_cast<std::chrono::milliseconds>(sum_pause_).count() / pause_count_ : 0;
186 }
187 
188 template <typename T>
GetTotalGCPause() const189 uint64_t MemStats<T>::GetTotalGCPause() const
190 {
191     return std::chrono::duration_cast<std::chrono::milliseconds>(sum_pause_).count();
192 }
193 
194 template class MemStats<MemStatsDefault>;
195 template class MemStats<MemStatsAdditionalInfo>;
196 }  // namespace panda::mem
197