1 // Copyright 2020 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifdef V8_ENABLE_PRECISE_ZONE_STATS
6
7 #if defined(__clang__) || defined(__GLIBCXX__)
8 #include <cxxabi.h>
9 #endif // __GLIBCXX__
10 #include <cinttypes>
11 #include <cstdio>
12
13 #include "src/utils/utils.h"
14 #include "src/zone/type-stats.h"
15
16 namespace v8 {
17 namespace internal {
18
MergeWith(const TypeStats & other)19 void TypeStats::MergeWith(const TypeStats& other) {
20 for (auto const& item : other.map_) {
21 Add(item.first, item.second);
22 }
23 }
24
25 class Demangler {
26 public:
27 Demangler() = default;
~Demangler()28 ~Demangler() {
29 if (buffer_) free(buffer_);
30 USE(buffer_len_); // In case demangling is not supported.
31 }
32
demangle(std::type_index type_id)33 const char* demangle(std::type_index type_id) {
34 #if defined(__clang__) || defined(__GLIBCXX__)
35 int status = -1;
36 char* result =
37 abi::__cxa_demangle(type_id.name(), buffer_, &buffer_len_, &status);
38 if (status == 0) {
39 // Upon success, the buffer_ may be reallocated.
40 buffer_ = result;
41 return buffer_;
42 }
43 #endif
44 return type_id.name();
45 }
46
47 private:
48 char* buffer_ = nullptr;
49 size_t buffer_len_ = 0;
50 };
51
Dump() const52 void TypeStats::Dump() const {
53 Demangler d;
54 PrintF("===== TypeStats =====\n");
55 PrintF("-------------+--------------+------------+--------+--------------\n");
56 PrintF(" alloc | dealloc | count | sizeof | name\n");
57 PrintF("-------------+--------------+------------+--------+--------------\n");
58 uint64_t total_allocation_count = 0;
59 uint64_t total_allocated_bytes = 0;
60 uint64_t total_deallocated_bytes = 0;
61 for (auto const& item : map_) {
62 const StatsEntry& entry = item.second;
63 total_allocation_count += entry.allocation_count;
64 total_allocated_bytes += entry.allocated_bytes;
65 total_deallocated_bytes += entry.deallocated_bytes;
66 PrintF("%12zu | %12zu | %10zu | %6zu | %s\n", entry.allocated_bytes,
67 entry.deallocated_bytes, entry.allocation_count, entry.instance_size,
68 d.demangle(item.first));
69 }
70 PrintF("%12" PRIu64 " | %12" PRIu64 " | %10" PRIu64
71 " | ===== TOTAL STATS =====\n",
72 total_allocated_bytes, total_deallocated_bytes,
73 total_allocation_count);
74 }
75
76 } // namespace internal
77 } // namespace v8
78
79 #endif // V8_ENABLE_PRECISE_ZONE_STATS
80